2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <sigc++/bind.h>
27 #include <cstdio> /* snprintf(3) ... grrr */
42 #include <sys/param.h>
43 #include <sys/mount.h>
48 #include <midi++/mmc.h>
49 #include <midi++/port.h>
50 #include <pbd/error.h>
52 #include <glibmm/thread.h>
53 #include <pbd/pathscanner.h>
54 #include <pbd/pthread_utils.h>
55 #include <pbd/strsplit.h>
56 #include <pbd/stacktrace.h>
57 #include <pbd/copyfile.h>
59 #include <ardour/audioengine.h>
60 #include <ardour/configuration.h>
61 #include <ardour/session.h>
62 #include <ardour/audio_diskstream.h>
63 #include <ardour/utils.h>
64 #include <ardour/audioplaylist.h>
65 #include <ardour/audiofilesource.h>
66 #include <ardour/silentfilesource.h>
67 #include <ardour/sndfilesource.h>
68 #include <ardour/sndfile_helpers.h>
69 #include <ardour/auditioner.h>
70 #include <ardour/export.h>
71 #include <ardour/redirect.h>
72 #include <ardour/send.h>
73 #include <ardour/insert.h>
74 #include <ardour/connection.h>
75 #include <ardour/slave.h>
76 #include <ardour/tempo.h>
77 #include <ardour/audio_track.h>
78 #include <ardour/cycle_timer.h>
79 #include <ardour/utils.h>
80 #include <ardour/named_selection.h>
81 #include <ardour/version.h>
82 #include <ardour/location.h>
83 #include <ardour/audioregion.h>
84 #include <ardour/crossfade.h>
85 #include <ardour/control_protocol_manager.h>
86 #include <ardour/region_factory.h>
87 #include <ardour/source_factory.h>
88 #include <ardour/playlist_factory.h>
90 #include <control_protocol/control_protocol.h>
96 using namespace ARDOUR;
100 Session::first_stage_init (string fullpath, string snapshot_name)
102 if (fullpath.length() == 0) {
104 throw failed_constructor();
107 char buf[PATH_MAX+1];
108 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
109 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
111 throw failed_constructor();
116 if (_path[_path.length()-1] != '/') {
120 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 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
142 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
143 _end_location_is_free = true;
144 g_atomic_int_set (&_record_status, Disabled);
145 loop_changing = false;
147 _last_roll_location = 0;
148 _last_record_location = 0;
149 pending_locate_frame = 0;
150 pending_locate_roll = false;
151 pending_locate_flush = false;
152 dstream_buffer_size = 0;
154 state_was_pending = false;
156 outbound_mtc_smpte_frame = 0;
157 next_quarter_frame_to_send = -1;
158 current_block_size = 0;
159 solo_update_disabled = false;
160 currently_soloing = false;
161 _have_captured = false;
162 _worst_output_latency = 0;
163 _worst_input_latency = 0;
164 _worst_track_latency = 0;
165 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
167 butler_mixdown_buffer = 0;
168 butler_gain_buffer = 0;
170 session_send_mmc = false;
171 session_send_mtc = false;
172 post_transport_work = PostTransportWork (0);
173 g_atomic_int_set (&butler_should_do_transport_work, 0);
174 g_atomic_int_set (&butler_active, 0);
175 g_atomic_int_set (&_playback_load, 100);
176 g_atomic_int_set (&_capture_load, 100);
177 g_atomic_int_set (&_playback_load_min, 100);
178 g_atomic_int_set (&_capture_load_min, 100);
180 waiting_to_start = false;
182 _gain_automation_buffer = 0;
183 _pan_automation_buffer = 0;
185 pending_abort = false;
186 destructive_index = 0;
188 first_file_data_format_reset = true;
189 first_file_header_format_reset = true;
190 butler_thread = (pthread_t) 0;
191 midi_thread = (pthread_t) 0;
193 AudioDiskstream::allocate_working_buffers();
195 /* default short fade = 15ms */
197 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
198 SndFileSource::setup_standard_crossfades (frame_rate());
200 last_mmc_step.tv_sec = 0;
201 last_mmc_step.tv_usec = 0;
204 /* click sounds are unset by default, which causes us to internal
205 waveforms for clicks.
209 click_emphasis_data = 0;
211 click_emphasis_length = 0;
214 process_function = &Session::process_with_events;
216 if (Config->get_use_video_sync()) {
217 waiting_for_sync_offset = true;
219 waiting_for_sync_offset = false;
222 _current_frame_rate = 48000;
223 _base_frame_rate = 48000;
227 _smpte_offset_negative = true;
228 last_smpte_valid = false;
232 last_rr_session_dir = session_dirs.begin();
233 refresh_disk_space ();
235 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
239 average_slave_delta = 1800;
240 have_first_delta_accumulator = false;
241 delta_accumulator_cnt = 0;
242 slave_state = Stopped;
244 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
246 /* These are all static "per-class" signals */
248 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
249 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
250 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
251 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
252 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
253 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
255 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
257 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
259 /* stop IO objects from doing stuff until we're ready for them */
261 IO::disable_panners ();
262 IO::disable_ports ();
263 IO::disable_connecting ();
267 Session::second_stage_init (bool new_session)
269 AudioFileSource::set_peak_dir (peak_dir());
272 if (load_state (_current_snapshot_name)) {
275 remove_empty_sounds ();
278 if (start_butler_thread()) {
282 if (start_midi_thread ()) {
286 // set_state() will call setup_raid_path(), but if it's a new session we need
287 // to call setup_raid_path() here.
289 if (set_state (*state_tree->root())) {
293 setup_raid_path(_path);
296 /* we can't save till after ::when_engine_running() is called,
297 because otherwise we save state with no connections made.
298 therefore, we reset _state_of_the_state because ::set_state()
299 will have cleared it.
301 we also have to include Loading so that any events that get
302 generated between here and the end of ::when_engine_running()
303 will be processed directly rather than queued.
306 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
308 // set_auto_input (true);
309 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
310 _locations.added.connect (mem_fun (this, &Session::locations_added));
311 setup_click_sounds (0);
312 setup_midi_control ();
314 /* Pay attention ... */
316 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
317 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
320 when_engine_running();
323 /* handle this one in a different way than all others, so that its clear what happened */
325 catch (AudioEngine::PortRegistrationFailure& err) {
326 error << _("Unable to create all required ports")
335 send_full_time_code ();
336 _engine.transport_locate (0);
337 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
338 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
340 ControlProtocolManager::instance().set_session (*this);
343 _end_location_is_free = true;
345 _end_location_is_free = false;
352 Session::raid_path () const
356 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
361 return path.substr (0, path.length() - 1); // drop final colon
365 Session::setup_raid_path (string path)
367 string::size_type colon;
371 string::size_type len = path.length();
376 if (path.length() == 0) {
380 session_dirs.clear ();
382 for (string::size_type n = 0; n < len; ++n) {
383 if (path[n] == ':') {
390 /* no multiple search path, just one location (common case) */
394 session_dirs.push_back (sp);
401 if (fspath[fspath.length()-1] != '/') {
405 fspath += sound_dir (false);
407 AudioFileSource::set_search_path (fspath);
414 while ((colon = remaining.find_first_of (':')) != string::npos) {
417 sp.path = remaining.substr (0, colon);
418 session_dirs.push_back (sp);
420 /* add sounds to file search path */
423 if (fspath[fspath.length()-1] != '/') {
426 fspath += sound_dir (false);
429 remaining = remaining.substr (colon+1);
432 if (remaining.length()) {
439 if (fspath[fspath.length()-1] != '/') {
442 fspath += sound_dir (false);
445 session_dirs.push_back (sp);
448 /* set the AudioFileSource search path */
450 AudioFileSource::set_search_path (fspath);
452 /* reset the round-robin soundfile path thingie */
454 last_rr_session_dir = session_dirs.begin();
458 Session::create (bool& new_session, string* mix_template, nframes_t initial_length)
462 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
463 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
469 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
470 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
474 /* if this is is an existing session with an old "sounds" directory, just use it. see Session::sound_dir() for more details */
476 if (!Glib::file_test (old_sound_dir(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
480 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
481 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
486 dir = dead_sound_dir ();
488 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
489 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
495 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
496 error << string_compose(_("Session: cannot create session export dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
501 /* check new_session so we don't overwrite an existing one */
504 std::string in_path = *mix_template;
506 ifstream in(in_path.c_str());
509 string out_path = _path;
511 out_path += _statefile_suffix;
513 ofstream out(out_path.c_str());
518 // okay, session is set up. Treat like normal saved
519 // session from now on.
525 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
531 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
538 /* set initial start + end point */
540 start_location->set_end (0);
541 _locations.add (start_location);
543 end_location->set_end (initial_length);
544 _locations.add (end_location);
546 _state_of_the_state = Clean;
548 if (save_state (_current_snapshot_name)) {
556 Session::load_diskstreams (const XMLNode& node)
559 XMLNodeConstIterator citer;
561 clist = node.children();
563 for (citer = clist.begin(); citer != clist.end(); ++citer) {
567 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
568 add_diskstream (dstream);
571 catch (failed_constructor& err) {
572 error << _("Session: could not load diskstream via XML state") << endmsg;
581 Session::maybe_write_autosave()
583 if (dirty() && record_status() != Recording) {
584 save_state("", true);
589 Session::remove_pending_capture_state ()
594 xml_path += _current_snapshot_name;
595 xml_path += _pending_suffix;
597 unlink (xml_path.c_str());
600 /** Rename a state file.
601 * @param snapshot_name Snapshot name.
604 Session::rename_state (string old_name, string new_name)
606 if (old_name == _current_snapshot_name || old_name == _name) {
607 /* refuse to rename the current snapshot or the "main" one */
611 const string old_xml_path = _path + old_name + _statefile_suffix;
612 const string new_xml_path = _path + new_name + _statefile_suffix;
614 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
615 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
619 /** Remove a state file.
620 * @param snapshot_name Snapshot name.
623 Session::remove_state (string snapshot_name)
625 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
626 /* refuse to remove the current snapshot or the "main" one */
630 const string xml_path = _path + snapshot_name + _statefile_suffix;
632 /* make a backup copy of the state file */
633 const string bak_path = xml_path + ".bak";
634 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
635 copy_file (xml_path, bak_path);
639 unlink (xml_path.c_str());
643 Session::save_state (string snapshot_name, bool pending)
649 if (_state_of_the_state & CannotSave) {
653 if (!_engine.connected ()) {
654 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
659 tree.set_root (&get_state());
661 if (snapshot_name.empty()) {
662 snapshot_name = _current_snapshot_name;
667 /* proper save: use _statefile_suffix (.ardour in English) */
669 xml_path += snapshot_name;
670 xml_path += _statefile_suffix;
672 /* make a backup copy of the old file */
676 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
677 copy_file (xml_path, bak_path);
682 /* pending save: use _pending_suffix (.pending in English) */
684 xml_path += snapshot_name;
685 xml_path += _pending_suffix;
692 tmp_path += snapshot_name;
695 // cerr << "actually writing state to " << xml_path << endl;
697 if (!tree.write (tmp_path)) {
698 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
699 unlink (tmp_path.c_str());
704 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
705 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
706 unlink (tmp_path.c_str());
713 save_history (snapshot_name);
715 bool was_dirty = dirty();
717 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
720 DirtyChanged (); /* EMIT SIGNAL */
723 StateSaved (snapshot_name); /* EMIT SIGNAL */
730 Session::restore_state (string snapshot_name)
732 if (load_state (snapshot_name) == 0) {
733 set_state (*state_tree->root());
740 Session::load_state (string snapshot_name)
749 state_was_pending = false;
751 /* check for leftover pending state from a crashed capture attempt */
754 xmlpath += snapshot_name;
755 xmlpath += _pending_suffix;
757 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
759 /* there is pending state from a crashed capture attempt */
761 if (AskAboutPendingState()) {
762 state_was_pending = true;
766 if (!state_was_pending) {
769 xmlpath += snapshot_name;
770 xmlpath += _statefile_suffix;
773 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
774 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
778 state_tree = new XMLTree;
782 if (!state_tree->read (xmlpath)) {
783 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
789 XMLNode& root (*state_tree->root());
791 if (root.name() != X_("Session")) {
792 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
798 const XMLProperty* prop;
801 if ((prop = root.property ("version")) == 0) {
802 /* no version implies very old version of Ardour */
806 major_version = atoi (prop->value()); // grab just the first number before the period
807 if (major_version < 2) {
816 backup_path += snapshot_name;
818 backup_path += _statefile_suffix;
820 /* don't make another copy if it already exists */
822 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
823 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
824 xmlpath, backup_path)
827 copy_file (xmlpath, backup_path);
829 /* if it fails, don't worry. right? */
837 Session::load_options (const XMLNode& node)
841 LocaleGuard lg (X_("POSIX"));
843 Config->set_variables (node, ConfigVariableBase::Session);
845 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
846 if ((prop = child->property ("val")) != 0) {
847 _end_location_is_free = (prop->value() == "yes");
855 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
857 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
858 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
860 return owner & modified_by_session_or_user;
864 Session::get_options () const
867 LocaleGuard lg (X_("POSIX"));
869 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
871 child = option_root.add_child ("end-marker-is-free");
872 child->add_property ("val", _end_location_is_free ? "yes" : "no");
884 Session::get_template()
886 /* if we don't disable rec-enable, diskstreams
887 will believe they need to store their capture
888 sources in their state node.
891 disable_record (false);
897 Session::state(bool full_state)
899 XMLNode* node = new XMLNode("Session");
902 // store libardour version, just in case
904 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
905 libardour2_major_version, libardour2_minor_version, libardour2_micro_version);
906 node->add_property("version", string(buf));
908 /* store configuration settings */
913 node->add_property ("name", _name);
915 if (session_dirs.size() > 1) {
919 vector<space_and_path>::iterator i = session_dirs.begin();
920 vector<space_and_path>::iterator next;
922 ++i; /* skip the first one */
926 while (i != session_dirs.end()) {
930 if (next != session_dirs.end()) {
940 child = node->add_child ("Path");
941 child->add_content (p);
945 /* save the ID counter */
947 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
948 node->add_property ("id-counter", buf);
950 /* various options */
952 node->add_child_nocopy (get_options());
954 child = node->add_child ("Sources");
957 Glib::Mutex::Lock sl (audio_source_lock);
959 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
961 /* Don't save information about AudioFileSources that are empty */
963 boost::shared_ptr<AudioFileSource> fs;
965 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
967 /* destructive file sources are OK if they are empty, because
968 we will re-use them every time.
971 if (!fs->destructive()) {
972 if (fs->length() == 0) {
978 child->add_child_nocopy (siter->second->get_state());
982 child = node->add_child ("Regions");
985 Glib::Mutex::Lock rl (region_lock);
987 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
989 /* only store regions not attached to playlists */
991 if (i->second->playlist() == 0) {
992 child->add_child_nocopy (i->second->state (true));
997 child = node->add_child ("DiskStreams");
1000 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1001 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1002 if (!(*i)->hidden()) {
1003 child->add_child_nocopy ((*i)->get_state());
1009 node->add_child_nocopy (_locations.get_state());
1011 // for a template, just create a new Locations, populate it
1012 // with the default start and end, and get the state for that.
1014 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1015 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1018 end->set_end(compute_initial_length());
1020 node->add_child_nocopy (loc.get_state());
1023 child = node->add_child ("Connections");
1025 Glib::Mutex::Lock lm (connection_lock);
1026 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1027 if (!(*i)->system_dependent()) {
1028 child->add_child_nocopy ((*i)->get_state());
1033 child = node->add_child ("Routes");
1035 boost::shared_ptr<RouteList> r = routes.reader ();
1037 RoutePublicOrderSorter cmp;
1038 RouteList public_order (*r);
1039 public_order.sort (cmp);
1041 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1042 if (!(*i)->hidden()) {
1044 child->add_child_nocopy ((*i)->get_state());
1046 child->add_child_nocopy ((*i)->get_template());
1053 child = node->add_child ("EditGroups");
1054 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1055 child->add_child_nocopy ((*i)->get_state());
1058 child = node->add_child ("MixGroups");
1059 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1060 child->add_child_nocopy ((*i)->get_state());
1063 child = node->add_child ("Playlists");
1064 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1065 if (!(*i)->hidden()) {
1066 if (!(*i)->empty()) {
1068 child->add_child_nocopy ((*i)->get_state());
1070 child->add_child_nocopy ((*i)->get_template());
1076 child = node->add_child ("UnusedPlaylists");
1077 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1078 if (!(*i)->hidden()) {
1079 if (!(*i)->empty()) {
1081 child->add_child_nocopy ((*i)->get_state());
1083 child->add_child_nocopy ((*i)->get_template());
1091 child = node->add_child ("Click");
1092 child->add_child_nocopy (_click_io->state (full_state));
1096 child = node->add_child ("NamedSelections");
1097 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1099 child->add_child_nocopy ((*i)->get_state());
1104 node->add_child_nocopy (_tempo_map->get_state());
1106 node->add_child_nocopy (get_control_protocol_state());
1109 node->add_child_copy (*_extra_xml);
1116 Session::get_control_protocol_state ()
1118 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1119 return cpm.get_state();
1123 Session::set_state (const XMLNode& node)
1127 const XMLProperty* prop;
1130 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1132 if (node.name() != X_("Session")){
1133 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1137 if ((prop = node.property ("name")) != 0) {
1138 _name = prop->value ();
1141 setup_raid_path(_path);
1143 if ((prop = node.property (X_("id-counter"))) != 0) {
1145 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1146 ID::init_counter (x);
1148 /* old sessions used a timebased counter, so fake
1149 the startup ID counter based on a standard
1154 ID::init_counter (now);
1158 IO::disable_ports ();
1159 IO::disable_connecting ();
1161 /* Object loading order:
1179 if (use_config_midi_ports ()) {
1182 if ((child = find_named_node (node, "extra")) != 0) {
1183 _extra_xml = new XMLNode (*child);
1186 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1187 load_options (*child);
1188 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1189 load_options (*child);
1191 error << _("Session: XML state has no options section") << endmsg;
1194 if ((child = find_named_node (node, "Locations")) == 0) {
1195 error << _("Session: XML state has no locations section") << endmsg;
1197 } else if (_locations.set_state (*child)) {
1203 if ((location = _locations.auto_loop_location()) != 0) {
1204 set_auto_loop_location (location);
1207 if ((location = _locations.auto_punch_location()) != 0) {
1208 set_auto_punch_location (location);
1211 if ((location = _locations.end_location()) == 0) {
1212 _locations.add (end_location);
1214 delete end_location;
1215 end_location = location;
1218 if ((location = _locations.start_location()) == 0) {
1219 _locations.add (start_location);
1221 delete start_location;
1222 start_location = location;
1225 AudioFileSource::set_header_position_offset (start_location->start());
1227 if ((child = find_named_node (node, "Sources")) == 0) {
1228 error << _("Session: XML state has no sources section") << endmsg;
1230 } else if (load_sources (*child)) {
1234 if ((child = find_named_node (node, "Regions")) == 0) {
1235 error << _("Session: XML state has no Regions section") << endmsg;
1237 } else if (load_regions (*child)) {
1241 if ((child = find_named_node (node, "Playlists")) == 0) {
1242 error << _("Session: XML state has no playlists section") << endmsg;
1244 } else if (load_playlists (*child)) {
1248 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1250 } else if (load_unused_playlists (*child)) {
1254 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1255 if (load_named_selections (*child)) {
1260 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1261 error << _("Session: XML state has no diskstreams section") << endmsg;
1263 } else if (load_diskstreams (*child)) {
1267 if ((child = find_named_node (node, "Connections")) == 0) {
1268 error << _("Session: XML state has no connections section") << endmsg;
1270 } else if (load_connections (*child)) {
1274 if ((child = find_named_node (node, "EditGroups")) == 0) {
1275 error << _("Session: XML state has no edit groups section") << endmsg;
1277 } else if (load_edit_groups (*child)) {
1281 if ((child = find_named_node (node, "MixGroups")) == 0) {
1282 error << _("Session: XML state has no mix groups section") << endmsg;
1284 } else if (load_mix_groups (*child)) {
1288 if ((child = find_named_node (node, "TempoMap")) == 0) {
1289 error << _("Session: XML state has no Tempo Map section") << endmsg;
1291 } else if (_tempo_map->set_state (*child)) {
1295 if ((child = find_named_node (node, "Routes")) == 0) {
1296 error << _("Session: XML state has no routes section") << endmsg;
1298 } else if (load_routes (*child)) {
1302 if ((child = find_named_node (node, "Click")) == 0) {
1303 warning << _("Session: XML state has no click section") << endmsg;
1304 } else if (_click_io) {
1305 _click_io->set_state (*child);
1308 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1309 ControlProtocolManager::instance().set_protocol_states (*child);
1312 /* here beginneth the second phase ... */
1314 StateReady (); /* EMIT SIGNAL */
1316 _state_of_the_state = Clean;
1318 if (state_was_pending) {
1319 save_state (_current_snapshot_name);
1320 remove_pending_capture_state ();
1321 state_was_pending = false;
1331 Session::load_routes (const XMLNode& node)
1334 XMLNodeConstIterator niter;
1335 RouteList new_routes;
1337 nlist = node.children();
1341 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1343 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1346 error << _("Session: cannot create Route from XML description.") << endmsg;
1350 new_routes.push_back (route);
1353 add_routes (new_routes);
1358 boost::shared_ptr<Route>
1359 Session::XMLRouteFactory (const XMLNode& node)
1361 if (node.name() != "Route") {
1362 return boost::shared_ptr<Route> ((Route*) 0);
1365 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1366 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1369 boost::shared_ptr<Route> x (new Route (*this, node));
1375 Session::load_regions (const XMLNode& node)
1378 XMLNodeConstIterator niter;
1379 boost::shared_ptr<AudioRegion> region;
1381 nlist = node.children();
1385 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1386 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1387 error << _("Session: cannot create Region from XML description.") << endmsg;
1394 boost::shared_ptr<AudioRegion>
1395 Session::XMLRegionFactory (const XMLNode& node, bool full)
1397 const XMLProperty* prop;
1398 boost::shared_ptr<Source> source;
1399 boost::shared_ptr<AudioSource> as;
1401 uint32_t nchans = 1;
1404 if (node.name() != X_("Region")) {
1405 return boost::shared_ptr<AudioRegion>();
1408 if ((prop = node.property (X_("channels"))) != 0) {
1409 nchans = atoi (prop->value().c_str());
1413 if ((prop = node.property ("name")) == 0) {
1414 cerr << "no name for this region\n";
1418 if ((prop = node.property (X_("source-0"))) == 0) {
1419 if ((prop = node.property ("source")) == 0) {
1420 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1421 return boost::shared_ptr<AudioRegion>();
1425 PBD::ID s_id (prop->value());
1427 if ((source = source_by_id (s_id)) == 0) {
1428 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1429 return boost::shared_ptr<AudioRegion>();
1432 as = boost::dynamic_pointer_cast<AudioSource>(source);
1434 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1435 return boost::shared_ptr<AudioRegion>();
1438 sources.push_back (as);
1440 /* pickup other channels */
1442 for (uint32_t n=1; n < nchans; ++n) {
1443 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1444 if ((prop = node.property (buf)) != 0) {
1446 PBD::ID id2 (prop->value());
1448 if ((source = source_by_id (id2)) == 0) {
1449 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1450 return boost::shared_ptr<AudioRegion>();
1453 as = boost::dynamic_pointer_cast<AudioSource>(source);
1455 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1456 return boost::shared_ptr<AudioRegion>();
1458 sources.push_back (as);
1463 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1465 /* a final detail: this is the one and only place that we know how long missing files are */
1467 if (region->whole_file()) {
1468 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1469 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1471 sfp->set_length (region->length());
1481 catch (failed_constructor& err) {
1482 return boost::shared_ptr<AudioRegion>();
1487 Session::get_sources_as_xml ()
1490 XMLNode* node = new XMLNode (X_("Sources"));
1491 Glib::Mutex::Lock lm (audio_source_lock);
1493 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1494 node->add_child_nocopy (i->second->get_state());
1497 /* XXX get MIDI and other sources here */
1503 Session::path_from_region_name (string name, string identifier)
1505 char buf[PATH_MAX+1];
1507 string dir = discover_best_sound_dir ();
1509 for (n = 0; n < 999999; ++n) {
1510 if (identifier.length()) {
1511 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1512 identifier.c_str(), n);
1514 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1517 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1522 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1531 Session::load_sources (const XMLNode& node)
1534 XMLNodeConstIterator niter;
1535 boost::shared_ptr<Source> source;
1537 nlist = node.children();
1541 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1544 if ((source = XMLSourceFactory (**niter)) == 0) {
1545 error << _("Session: cannot create Source from XML description.") << endmsg;
1549 catch (non_existent_source& err) {
1550 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1551 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1558 boost::shared_ptr<Source>
1559 Session::XMLSourceFactory (const XMLNode& node)
1561 if (node.name() != "Source") {
1562 return boost::shared_ptr<Source>();
1566 return SourceFactory::create (*this, node);
1569 catch (failed_constructor& err) {
1570 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1571 return boost::shared_ptr<Source>();
1576 Session::save_template (string template_name)
1579 string xml_path, bak_path, template_path;
1581 if (_state_of_the_state & CannotSave) {
1586 string dir = template_dir();
1588 if ((dp = opendir (dir.c_str()))) {
1591 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1592 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1597 tree.set_root (&get_template());
1600 xml_path += template_name;
1601 xml_path += _template_suffix;
1603 ifstream in(xml_path.c_str());
1606 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1612 if (!tree.write (xml_path)) {
1613 error << _("mix template not saved") << endmsg;
1621 Session::rename_template (string old_name, string new_name)
1623 string old_path = template_dir() + old_name + _template_suffix;
1624 string new_path = template_dir() + new_name + _template_suffix;
1626 return rename (old_path.c_str(), new_path.c_str());
1630 Session::delete_template (string name)
1632 string template_path = template_dir();
1633 template_path += name;
1634 template_path += _template_suffix;
1636 return remove (template_path.c_str());
1640 Session::refresh_disk_space ()
1643 struct statfs statfsbuf;
1644 vector<space_and_path>::iterator i;
1645 Glib::Mutex::Lock lm (space_lock);
1648 /* get freespace on every FS that is part of the session path */
1650 _total_free_4k_blocks = 0;
1652 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1653 statfs ((*i).path.c_str(), &statfsbuf);
1655 scale = statfsbuf.f_bsize/4096.0;
1657 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1658 _total_free_4k_blocks += (*i).blocks;
1664 Session::ensure_sound_dir (string path, string& result)
1669 /* Ensure that the parent directory exists */
1671 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1672 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1676 /* Ensure that the sounds directory exists */
1680 result += sound_dir_name;
1682 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1683 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1689 dead += dead_sound_dir_name;
1691 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1692 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1698 peak += peak_dir_name;
1700 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1701 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1705 /* callers expect this to be terminated ... */
1712 Session::discover_best_sound_dir (bool destructive)
1714 vector<space_and_path>::iterator i;
1717 /* handle common case without system calls */
1719 if (session_dirs.size() == 1) {
1723 /* OK, here's the algorithm we're following here:
1725 We want to select which directory to use for
1726 the next file source to be created. Ideally,
1727 we'd like to use a round-robin process so as to
1728 get maximum performance benefits from splitting
1729 the files across multiple disks.
1731 However, in situations without much diskspace, an
1732 RR approach may end up filling up a filesystem
1733 with new files while others still have space.
1734 Its therefore important to pay some attention to
1735 the freespace in the filesystem holding each
1736 directory as well. However, if we did that by
1737 itself, we'd keep creating new files in the file
1738 system with the most space until it was as full
1739 as all others, thus negating any performance
1740 benefits of this RAID-1 like approach.
1742 So, we use a user-configurable space threshold. If
1743 there are at least 2 filesystems with more than this
1744 much space available, we use RR selection between them.
1745 If not, then we pick the filesystem with the most space.
1747 This gets a good balance between the two
1751 refresh_disk_space ();
1753 int free_enough = 0;
1755 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1756 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1761 if (free_enough >= 2) {
1763 bool found_it = false;
1765 /* use RR selection process, ensuring that the one
1769 i = last_rr_session_dir;
1772 if (++i == session_dirs.end()) {
1773 i = session_dirs.begin();
1776 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1777 if (ensure_sound_dir ((*i).path, result) == 0) {
1778 last_rr_session_dir = i;
1784 } while (i != last_rr_session_dir);
1787 result = sound_dir();
1792 /* pick FS with the most freespace (and that
1793 seems to actually work ...)
1796 vector<space_and_path> sorted;
1797 space_and_path_ascending_cmp cmp;
1799 sorted = session_dirs;
1800 sort (sorted.begin(), sorted.end(), cmp);
1802 for (i = sorted.begin(); i != sorted.end(); ++i) {
1803 if (ensure_sound_dir ((*i).path, result) == 0) {
1804 last_rr_session_dir = i;
1809 /* if the above fails, fall back to the most simplistic solution */
1811 if (i == sorted.end()) {
1820 Session::load_playlists (const XMLNode& node)
1823 XMLNodeConstIterator niter;
1824 boost::shared_ptr<Playlist> playlist;
1826 nlist = node.children();
1830 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1832 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1833 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1841 Session::load_unused_playlists (const XMLNode& node)
1844 XMLNodeConstIterator niter;
1845 boost::shared_ptr<Playlist> playlist;
1847 nlist = node.children();
1851 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1853 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1854 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1858 // now manually untrack it
1860 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1867 boost::shared_ptr<Playlist>
1868 Session::XMLPlaylistFactory (const XMLNode& node)
1871 return PlaylistFactory::create (*this, node);
1874 catch (failed_constructor& err) {
1875 return boost::shared_ptr<Playlist>();
1880 Session::load_named_selections (const XMLNode& node)
1883 XMLNodeConstIterator niter;
1886 nlist = node.children();
1890 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1892 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1893 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1901 Session::XMLNamedSelectionFactory (const XMLNode& node)
1904 return new NamedSelection (*this, node);
1907 catch (failed_constructor& err) {
1913 Session::dead_sound_dir () const
1916 res += dead_sound_dir_name;
1922 Session::old_sound_dir (bool with_path) const
1930 res += old_sound_dir_name;
1936 Session::sound_dir (bool with_path) const
1947 res += interchange_dir_name;
1949 res += legalize_for_path (_name);
1951 res += sound_dir_name;
1959 /* if this already exists, don't check for the old session sound directory */
1961 if (Glib::file_test (full, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
1965 /* possibly support old session structure */
1968 string old_withpath;
1970 old_nopath += old_sound_dir_name;
1973 old_withpath = _path;
1974 old_withpath += old_sound_dir_name;
1976 if (Glib::file_test (old_withpath.c_str(), Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
1978 return old_withpath;
1983 /* ok, old "sounds" directory isn't there, return the new path */
1989 Session::peak_dir () const
1992 res += peak_dir_name;
1998 Session::automation_dir () const
2001 res += "automation/";
2006 Session::template_dir ()
2008 string path = get_user_ardour_path();
2009 path += "templates/";
2015 Session::export_dir () const
2018 res += export_dir_name;
2024 Session::suffixed_search_path (string suffix, bool data)
2028 path += get_user_ardour_path();
2029 if (path[path.length()-1] != ':') {
2034 path += get_system_data_path();
2036 path += get_system_module_path();
2039 vector<string> split_path;
2041 split (path, split_path, ':');
2044 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2049 if (distance (i, split_path.end()) != 1) {
2058 Session::template_path ()
2060 return suffixed_search_path (X_("templates"), true);
2064 Session::control_protocol_path ()
2066 return suffixed_search_path (X_("surfaces"), false);
2070 Session::load_connections (const XMLNode& node)
2072 XMLNodeList nlist = node.children();
2073 XMLNodeConstIterator niter;
2077 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2078 if ((*niter)->name() == "InputConnection") {
2079 add_connection (new ARDOUR::InputConnection (**niter));
2080 } else if ((*niter)->name() == "OutputConnection") {
2081 add_connection (new ARDOUR::OutputConnection (**niter));
2083 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2092 Session::load_edit_groups (const XMLNode& node)
2094 return load_route_groups (node, true);
2098 Session::load_mix_groups (const XMLNode& node)
2100 return load_route_groups (node, false);
2104 Session::load_route_groups (const XMLNode& node, bool edit)
2106 XMLNodeList nlist = node.children();
2107 XMLNodeConstIterator niter;
2112 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2113 if ((*niter)->name() == "RouteGroup") {
2115 rg = add_edit_group ("");
2116 rg->set_state (**niter);
2118 rg = add_mix_group ("");
2119 rg->set_state (**niter);
2128 state_file_filter (const string &str, void *arg)
2130 return (str.length() > strlen(Session::statefile_suffix()) &&
2131 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2135 bool operator()(const string* a, const string* b) {
2141 remove_end(string* state)
2143 string statename(*state);
2145 string::size_type start,end;
2146 if ((start = statename.find_last_of ('/')) != string::npos) {
2147 statename = statename.substr (start+1);
2150 if ((end = statename.rfind(".ardour")) == string::npos) {
2151 end = statename.length();
2154 return new string(statename.substr (0, end));
2158 Session::possible_states (string path)
2160 PathScanner scanner;
2161 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2163 transform(states->begin(), states->end(), states->begin(), remove_end);
2166 sort (states->begin(), states->end(), cmp);
2172 Session::possible_states () const
2174 return possible_states(_path);
2178 Session::auto_save()
2180 save_state (_current_snapshot_name);
2184 Session::add_edit_group (string name)
2186 RouteGroup* rg = new RouteGroup (*this, name);
2187 edit_groups.push_back (rg);
2188 edit_group_added (rg); /* EMIT SIGNAL */
2194 Session::add_mix_group (string name)
2196 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2197 mix_groups.push_back (rg);
2198 mix_group_added (rg); /* EMIT SIGNAL */
2204 Session::remove_edit_group (RouteGroup& rg)
2206 list<RouteGroup*>::iterator i;
2208 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2209 (*i)->apply (&Route::drop_edit_group, this);
2210 edit_groups.erase (i);
2211 edit_group_removed (); /* EMIT SIGNAL */
2218 Session::remove_mix_group (RouteGroup& rg)
2220 list<RouteGroup*>::iterator i;
2222 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2223 (*i)->apply (&Route::drop_mix_group, this);
2224 mix_groups.erase (i);
2225 mix_group_removed (); /* EMIT SIGNAL */
2232 Session::mix_group_by_name (string name)
2234 list<RouteGroup *>::iterator i;
2236 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2237 if ((*i)->name() == name) {
2245 Session::edit_group_by_name (string name)
2247 list<RouteGroup *>::iterator i;
2249 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2250 if ((*i)->name() == name) {
2258 Session::begin_reversible_command (string name)
2260 current_trans = new UndoTransaction;
2261 current_trans->set_name (name);
2265 Session::commit_reversible_command (Command *cmd)
2270 current_trans->add_command (cmd);
2273 gettimeofday (&now, 0);
2274 current_trans->set_timestamp (now);
2276 _history.add (current_trans);
2279 Session::GlobalRouteBooleanState
2280 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2282 GlobalRouteBooleanState s;
2283 boost::shared_ptr<RouteList> r = routes.reader ();
2285 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2286 if (!(*i)->hidden()) {
2287 RouteBooleanState v;
2290 Route* r = (*i).get();
2291 v.second = (r->*method)();
2300 Session::GlobalRouteMeterState
2301 Session::get_global_route_metering ()
2303 GlobalRouteMeterState s;
2304 boost::shared_ptr<RouteList> r = routes.reader ();
2306 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2307 if (!(*i)->hidden()) {
2311 v.second = (*i)->meter_point();
2321 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2323 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2325 boost::shared_ptr<Route> r = (i->first.lock());
2328 r->set_meter_point (i->second, arg);
2334 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2336 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2338 boost::shared_ptr<Route> r = (i->first.lock());
2341 Route* rp = r.get();
2342 (rp->*method) (i->second, arg);
2348 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2350 set_global_route_boolean (s, &Route::set_mute, src);
2354 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2356 set_global_route_boolean (s, &Route::set_solo, src);
2360 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2362 set_global_route_boolean (s, &Route::set_record_enable, src);
2367 Session::global_mute_memento (void* src)
2369 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2373 Session::global_metering_memento (void* src)
2375 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2379 Session::global_solo_memento (void* src)
2381 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2385 Session::global_record_enable_memento (void* src)
2387 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2392 template_filter (const string &str, void *arg)
2394 return (str.length() > strlen(Session::template_suffix()) &&
2395 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2399 Session::get_template_list (list<string> &template_names)
2401 vector<string *> *templates;
2402 PathScanner scanner;
2405 path = template_path ();
2407 templates = scanner (path, template_filter, 0, false, true);
2409 vector<string*>::iterator i;
2410 for (i = templates->begin(); i != templates->end(); ++i) {
2411 string fullpath = *(*i);
2414 start = fullpath.find_last_of ('/') + 1;
2415 if ((end = fullpath.find_last_of ('.')) <0) {
2416 end = fullpath.length();
2419 template_names.push_back(fullpath.substr(start, (end-start)));
2424 Session::read_favorite_dirs (FavoriteDirs & favs)
2426 string path = get_user_ardour_path();
2427 path += "/favorite_dirs";
2429 ifstream fav (path.c_str());
2434 if (errno != ENOENT) {
2435 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2446 getline(fav, newfav);
2452 favs.push_back (newfav);
2459 Session::write_favorite_dirs (FavoriteDirs & favs)
2461 string path = get_user_ardour_path();
2462 path += "/favorite_dirs";
2464 ofstream fav (path.c_str());
2470 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2471 fav << (*i) << endl;
2478 accept_all_non_peak_files (const string& path, void *arg)
2480 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2484 accept_all_state_files (const string& path, void *arg)
2486 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2490 Session::find_all_sources (string path, set<string>& result)
2495 if (!tree.read (path)) {
2499 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2504 XMLNodeConstIterator niter;
2506 nlist = node->children();
2510 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2514 if ((prop = (*niter)->property (X_("name"))) == 0) {
2518 if (prop->value()[0] == '/') {
2519 /* external file, ignore */
2523 string path = _path; /* /-terminated */
2524 path += sound_dir_name;
2526 path += prop->value();
2528 result.insert (path);
2535 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2537 PathScanner scanner;
2538 vector<string*>* state_files;
2540 string this_snapshot_path;
2546 if (ripped[ripped.length()-1] == '/') {
2547 ripped = ripped.substr (0, ripped.length() - 1);
2550 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2552 if (state_files == 0) {
2557 this_snapshot_path = _path;
2558 this_snapshot_path += _current_snapshot_name;
2559 this_snapshot_path += _statefile_suffix;
2561 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2563 if (exclude_this_snapshot && **i == this_snapshot_path) {
2567 if (find_all_sources (**i, result) < 0) {
2575 struct RegionCounter {
2576 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2577 AudioSourceList::iterator iter;
2578 boost::shared_ptr<Region> region;
2581 RegionCounter() : count (0) {}
2585 Session::cleanup_sources (Session::cleanup_report& rep)
2587 vector<boost::shared_ptr<Source> > dead_sources;
2588 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2589 PathScanner scanner;
2591 vector<space_and_path>::iterator i;
2592 vector<space_and_path>::iterator nexti;
2593 vector<string*>* soundfiles;
2594 vector<string> unused;
2595 set<string> all_sources;
2600 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2602 /* step 1: consider deleting all unused playlists */
2604 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2607 status = AskAboutPlaylistDeletion (*x);
2616 playlists_tbd.push_back (*x);
2620 /* leave it alone */
2625 /* now delete any that were marked for deletion */
2627 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2628 (*x)->drop_references ();
2631 playlists_tbd.clear ();
2633 /* step 2: find all un-used sources */
2638 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2640 AudioSourceList::iterator tmp;
2645 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2649 if (!i->second->used() && i->second->length() > 0) {
2650 dead_sources.push_back (i->second);
2651 i->second->GoingAway();
2657 /* build a list of all the possible sound directories for the session */
2659 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2664 sound_path += (*i).path;
2665 sound_path += sound_dir (false);
2667 if (nexti != session_dirs.end()) {
2674 /* now do the same thing for the files that ended up in the sounds dir(s)
2675 but are not referenced as sources in any snapshot.
2678 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2680 if (soundfiles == 0) {
2684 /* find all sources, but don't use this snapshot because the
2685 state file on disk still references sources we may have already
2689 find_all_sources_across_snapshots (all_sources, true);
2691 /* add our current source list
2694 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2695 boost::shared_ptr<AudioFileSource> fs;
2697 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2698 all_sources.insert (fs->path());
2702 char tmppath1[PATH_MAX+1];
2703 char tmppath2[PATH_MAX+1];
2705 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2710 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2712 realpath(spath.c_str(), tmppath1);
2713 realpath((*i).c_str(), tmppath2);
2715 if (strcmp(tmppath1, tmppath2) == 0) {
2722 unused.push_back (spath);
2726 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2728 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2729 struct stat statbuf;
2731 rep.paths.push_back (*x);
2732 if (stat ((*x).c_str(), &statbuf) == 0) {
2733 rep.space += statbuf.st_size;
2738 /* don't move the file across filesystems, just
2739 stick it in the `dead_sound_dir_name' directory
2740 on whichever filesystem it was already on.
2743 if ((*x).find ("/sounds/") != string::npos) {
2745 /* old school, go up 1 level */
2747 newpath = Glib::path_get_dirname (*x); // "sounds"
2748 newpath = Glib::path_get_dirname (newpath); // "session-name"
2752 /* new school, go up 4 levels */
2754 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2755 newpath = Glib::path_get_dirname (newpath); // "session-name"
2756 newpath = Glib::path_get_dirname (newpath); // "interchange"
2757 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2761 newpath += dead_sound_dir_name;
2763 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2764 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2769 newpath += Glib::path_get_basename ((*x));
2771 if (access (newpath.c_str(), F_OK) == 0) {
2773 /* the new path already exists, try versioning */
2775 char buf[PATH_MAX+1];
2779 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2782 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2783 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2787 if (version == 999) {
2788 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2792 newpath = newpath_v;
2797 /* it doesn't exist, or we can't read it or something */
2801 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2802 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2803 (*x), newpath, strerror (errno))
2808 /* see if there an easy to find peakfile for this file, and remove it.
2811 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2812 peakpath += ".peak";
2814 if (access (peakpath.c_str(), W_OK) == 0) {
2815 if (::unlink (peakpath.c_str()) != 0) {
2816 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2817 peakpath, _path, strerror (errno))
2819 /* try to back out */
2820 rename (newpath.c_str(), _path.c_str());
2828 /* dump the history list */
2832 /* save state so we don't end up a session file
2833 referring to non-existent sources.
2839 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2844 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2846 vector<space_and_path>::iterator i;
2847 string dead_sound_dir;
2848 struct dirent* dentry;
2849 struct stat statbuf;
2855 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2857 dead_sound_dir = (*i).path;
2858 dead_sound_dir += dead_sound_dir_name;
2860 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2864 while ((dentry = readdir (dead)) != 0) {
2866 /* avoid '.' and '..' */
2868 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2869 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2875 fullpath = dead_sound_dir;
2877 fullpath += dentry->d_name;
2879 if (stat (fullpath.c_str(), &statbuf)) {
2883 if (!S_ISREG (statbuf.st_mode)) {
2887 if (unlink (fullpath.c_str())) {
2888 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2889 fullpath, strerror (errno))
2893 rep.paths.push_back (dentry->d_name);
2894 rep.space += statbuf.st_size;
2905 Session::set_dirty ()
2907 bool was_dirty = dirty();
2909 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2912 DirtyChanged(); /* EMIT SIGNAL */
2918 Session::set_clean ()
2920 bool was_dirty = dirty();
2922 _state_of_the_state = Clean;
2925 DirtyChanged(); /* EMIT SIGNAL */
2930 Session::set_deletion_in_progress ()
2932 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2936 Session::add_controllable (Controllable* c)
2938 /* this adds a controllable to the list managed by the Session.
2939 this is a subset of those managed by the Controllable class
2940 itself, and represents the only ones whose state will be saved
2941 as part of the session.
2944 Glib::Mutex::Lock lm (controllables_lock);
2945 controllables.insert (c);
2949 Session::remove_controllable (Controllable* c)
2951 if (_state_of_the_state | Deletion) {
2955 Glib::Mutex::Lock lm (controllables_lock);
2957 Controllables::iterator x = controllables.find (c);
2959 if (x != controllables.end()) {
2960 controllables.erase (x);
2965 Session::controllable_by_id (const PBD::ID& id)
2967 Glib::Mutex::Lock lm (controllables_lock);
2969 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2970 if ((*i)->id() == id) {
2979 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2981 Stateful::add_instant_xml (node, dir);
2982 Config->add_instant_xml (node, get_user_ardour_path());
2986 Session::save_history (string snapshot_name)
2992 if (snapshot_name.empty()) {
2993 snapshot_name = _current_snapshot_name;
2996 xml_path = _path + snapshot_name + ".history";
2998 bak_path = xml_path + ".bak";
3000 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && ::rename (xml_path.c_str(), bak_path.c_str())) {
3001 error << _("could not backup old history file, current history not saved.") << endmsg;
3005 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3009 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3011 if (!tree.write (xml_path))
3013 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3015 /* don't leave a corrupt file lying around if it is
3019 if (unlink (xml_path.c_str())) {
3020 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
3022 if (rename (bak_path.c_str(), xml_path.c_str()))
3024 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
3035 Session::restore_history (string snapshot_name)
3040 if (snapshot_name.empty()) {
3041 snapshot_name = _current_snapshot_name;
3045 xmlpath = _path + snapshot_name + ".history";
3046 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
3048 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3052 if (!tree.read (xmlpath)) {
3053 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
3057 /* replace history */
3060 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3063 UndoTransaction* ut = new UndoTransaction ();
3066 ut->set_name(t->property("name")->value());
3067 stringstream ss(t->property("tv_sec")->value());
3069 ss.str(t->property("tv_usec")->value());
3071 ut->set_timestamp(tv);
3073 for (XMLNodeConstIterator child_it = t->children().begin();
3074 child_it != t->children().end();
3077 XMLNode *n = *child_it;
3080 if (n->name() == "MementoCommand" ||
3081 n->name() == "MementoUndoCommand" ||
3082 n->name() == "MementoRedoCommand") {
3084 if ((c = memento_command_factory(n))) {
3088 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3090 if ((c = global_state_command_factory (*n))) {
3091 ut->add_command (c);
3096 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3107 Session::config_changed (const char* parameter_name)
3109 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3111 if (PARAM_IS ("seamless-loop")) {
3113 } else if (PARAM_IS ("rf-speed")) {
3115 } else if (PARAM_IS ("auto-loop")) {
3117 } else if (PARAM_IS ("auto-input")) {
3119 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3120 /* auto-input only makes a difference if we're rolling */
3122 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3124 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3125 if ((*i)->record_enabled ()) {
3126 (*i)->monitor_input (!Config->get_auto_input());
3131 } else if (PARAM_IS ("punch-in")) {
3135 if ((location = _locations.auto_punch_location()) != 0) {
3137 if (Config->get_punch_in ()) {
3138 replace_event (Event::PunchIn, location->start());
3140 remove_event (location->start(), Event::PunchIn);
3144 } else if (PARAM_IS ("punch-out")) {
3148 if ((location = _locations.auto_punch_location()) != 0) {
3150 if (Config->get_punch_out()) {
3151 replace_event (Event::PunchOut, location->end());
3153 clear_events (Event::PunchOut);
3157 } else if (PARAM_IS ("edit-mode")) {
3159 Glib::Mutex::Lock lm (playlist_lock);
3161 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3162 (*i)->set_edit_mode (Config->get_edit_mode ());
3165 } else if (PARAM_IS ("use-video-sync")) {
3167 waiting_for_sync_offset = Config->get_use_video_sync();
3169 } else if (PARAM_IS ("mmc-control")) {
3171 poke_midi_thread ();
3173 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-device-id")) {
3175 set_mmc_receive_device_id (Config->get_mmc_receive_device_id());
3177 } else if (PARAM_IS ("mmc-send-device-id")) {
3179 set_mmc_send_device_id (Config->get_mmc_send_device_id());
3181 } else if (PARAM_IS ("midi-control")) {
3183 poke_midi_thread ();
3185 } else if (PARAM_IS ("raid-path")) {
3187 setup_raid_path (Config->get_raid_path());
3189 } else if (PARAM_IS ("smpte-format")) {
3193 } else if (PARAM_IS ("video-pullup")) {
3197 } else if (PARAM_IS ("seamless-loop")) {
3199 if (play_loop && transport_rolling()) {
3200 // to reset diskstreams etc
3201 request_play_loop (true);
3204 } else if (PARAM_IS ("rf-speed")) {
3206 cumulative_rf_motion = 0;
3209 } else if (PARAM_IS ("click-sound")) {
3211 setup_click_sounds (1);
3213 } else if (PARAM_IS ("click-emphasis-sound")) {
3215 setup_click_sounds (-1);
3217 } else if (PARAM_IS ("clicking")) {
3219 if (Config->get_clicking()) {
3220 if (_click_io && click_data) { // don't require emphasis data
3227 } else if (PARAM_IS ("send-mtc")) {
3229 /* only set the internal flag if we have
3233 if (_mtc_port != 0) {
3234 session_send_mtc = Config->get_send_mtc();
3235 if (session_send_mtc) {
3236 /* mark us ready to send */
3237 next_quarter_frame_to_send = 0;
3240 session_send_mtc = false;
3243 } else if (PARAM_IS ("send-mmc")) {
3245 /* only set the internal flag if we have
3249 if (_mmc_port != 0) {
3250 session_send_mmc = Config->get_send_mmc();
3253 session_send_mmc = false;
3256 } else if (PARAM_IS ("midi-feedback")) {
3258 /* only set the internal flag if we have
3262 if (_mtc_port != 0) {
3263 session_midi_feedback = Config->get_midi_feedback();
3266 } else if (PARAM_IS ("jack-time-master")) {
3268 engine().reset_timebase ();
3270 } else if (PARAM_IS ("native-file-header-format")) {
3272 if (!first_file_header_format_reset) {
3273 reset_native_file_format ();
3276 first_file_header_format_reset = false;
3278 } else if (PARAM_IS ("native-file-data-format")) {
3280 if (!first_file_data_format_reset) {
3281 reset_native_file_format ();
3284 first_file_data_format_reset = false;
3286 } else if (PARAM_IS ("slave-source")) {
3287 set_slave_source (Config->get_slave_source());
3288 } else if (PARAM_IS ("remote-model")) {
3289 set_remote_control_ids ();
3290 } else if (PARAM_IS ("denormal-model")) {
3292 } else if (PARAM_IS ("history-depth")) {
3293 set_history_depth (Config->get_history_depth());
3294 } else if (PARAM_IS ("sync-all-route-ordering")) {
3305 Session::set_history_depth (uint32_t d)
3307 _history.set_depth (d);