2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <sigc++/bind.h>
27 #include <cstdio> /* snprintf(3) ... grrr */
42 #include <sys/param.h>
43 #include <sys/mount.h>
48 #include <midi++/mmc.h>
49 #include <midi++/port.h>
50 #include <pbd/error.h>
52 #include <glibmm/thread.h>
53 #include <pbd/pathscanner.h>
54 #include <pbd/pthread_utils.h>
55 #include <pbd/strsplit.h>
56 #include <pbd/stacktrace.h>
57 #include <pbd/copyfile.h>
59 #include <ardour/audioengine.h>
60 #include <ardour/configuration.h>
61 #include <ardour/session.h>
62 #include <ardour/audio_diskstream.h>
63 #include <ardour/utils.h>
64 #include <ardour/audioplaylist.h>
65 #include <ardour/audiofilesource.h>
66 #include <ardour/silentfilesource.h>
67 #include <ardour/sndfilesource.h>
68 #include <ardour/sndfile_helpers.h>
69 #include <ardour/auditioner.h>
70 #include <ardour/export.h>
71 #include <ardour/redirect.h>
72 #include <ardour/send.h>
73 #include <ardour/insert.h>
74 #include <ardour/connection.h>
75 #include <ardour/slave.h>
76 #include <ardour/tempo.h>
77 #include <ardour/audio_track.h>
78 #include <ardour/cycle_timer.h>
79 #include <ardour/utils.h>
80 #include <ardour/named_selection.h>
81 #include <ardour/version.h>
82 #include <ardour/location.h>
83 #include <ardour/audioregion.h>
84 #include <ardour/crossfade.h>
85 #include <ardour/control_protocol_manager.h>
86 #include <ardour/region_factory.h>
87 #include <ardour/source_factory.h>
88 #include <ardour/playlist_factory.h>
90 #include <control_protocol/control_protocol.h>
96 using namespace ARDOUR;
100 Session::first_stage_init (string fullpath, string snapshot_name)
102 if (fullpath.length() == 0) {
104 throw failed_constructor();
107 char buf[PATH_MAX+1];
108 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
109 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
111 throw failed_constructor();
116 if (_path[_path.length()-1] != '/') {
120 /* these two are just provisional settings. set_state()
121 will likely override them.
124 _name = _current_snapshot_name = snapshot_name;
126 _current_frame_rate = _engine.frame_rate ();
127 _tempo_map = new TempoMap (_current_frame_rate);
128 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
130 g_atomic_int_set (&processing_prohibited, 0);
132 _transport_speed = 0;
133 _last_transport_speed = 0;
134 auto_play_legal = false;
135 transport_sub_state = 0;
136 _transport_frame = 0;
138 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
139 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
140 _end_location_is_free = true;
141 g_atomic_int_set (&_record_status, Disabled);
142 loop_changing = false;
144 _last_roll_location = 0;
145 _last_record_location = 0;
146 pending_locate_frame = 0;
147 pending_locate_roll = false;
148 pending_locate_flush = false;
149 dstream_buffer_size = 0;
151 state_was_pending = false;
153 outbound_mtc_smpte_frame = 0;
154 next_quarter_frame_to_send = -1;
155 current_block_size = 0;
156 solo_update_disabled = false;
157 currently_soloing = false;
158 _have_captured = false;
159 _worst_output_latency = 0;
160 _worst_input_latency = 0;
161 _worst_track_latency = 0;
162 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
164 butler_mixdown_buffer = 0;
165 butler_gain_buffer = 0;
167 session_send_mmc = false;
168 session_send_mtc = false;
169 post_transport_work = PostTransportWork (0);
170 g_atomic_int_set (&butler_should_do_transport_work, 0);
171 g_atomic_int_set (&butler_active, 0);
172 g_atomic_int_set (&_playback_load, 100);
173 g_atomic_int_set (&_capture_load, 100);
174 g_atomic_int_set (&_playback_load_min, 100);
175 g_atomic_int_set (&_capture_load_min, 100);
177 waiting_to_start = false;
179 _gain_automation_buffer = 0;
180 _pan_automation_buffer = 0;
182 pending_abort = false;
183 destructive_index = 0;
185 first_file_data_format_reset = true;
186 first_file_header_format_reset = true;
187 butler_thread = (pthread_t) 0;
188 midi_thread = (pthread_t) 0;
190 AudioDiskstream::allocate_working_buffers();
192 /* default short fade = 15ms */
194 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
195 SndFileSource::setup_standard_crossfades (frame_rate());
197 last_mmc_step.tv_sec = 0;
198 last_mmc_step.tv_usec = 0;
201 /* click sounds are unset by default, which causes us to internal
202 waveforms for clicks.
206 click_emphasis_data = 0;
208 click_emphasis_length = 0;
211 process_function = &Session::process_with_events;
213 if (Config->get_use_video_sync()) {
214 waiting_for_sync_offset = true;
216 waiting_for_sync_offset = false;
219 _current_frame_rate = 48000;
220 _base_frame_rate = 48000;
224 _smpte_offset_negative = true;
225 last_smpte_valid = false;
229 last_rr_session_dir = session_dirs.begin();
230 refresh_disk_space ();
232 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
236 average_slave_delta = 1800;
237 have_first_delta_accumulator = false;
238 delta_accumulator_cnt = 0;
239 slave_state = Stopped;
241 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
243 /* These are all static "per-class" signals */
245 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
246 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
247 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
248 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
249 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
250 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
252 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
254 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
256 /* stop IO objects from doing stuff until we're ready for them */
258 IO::disable_panners ();
259 IO::disable_ports ();
260 IO::disable_connecting ();
264 Session::second_stage_init (bool new_session)
266 AudioFileSource::set_peak_dir (peak_dir());
269 if (load_state (_current_snapshot_name)) {
272 remove_empty_sounds ();
275 if (start_butler_thread()) {
279 if (start_midi_thread ()) {
283 // set_state() will call setup_raid_path(), but if it's a new session we need
284 // to call setup_raid_path() here.
286 if (set_state (*state_tree->root())) {
290 setup_raid_path(_path);
293 /* we can't save till after ::when_engine_running() is called,
294 because otherwise we save state with no connections made.
295 therefore, we reset _state_of_the_state because ::set_state()
296 will have cleared it.
298 we also have to include Loading so that any events that get
299 generated between here and the end of ::when_engine_running()
300 will be processed directly rather than queued.
303 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
305 // set_auto_input (true);
306 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
307 _locations.added.connect (mem_fun (this, &Session::locations_added));
308 setup_click_sounds (0);
309 setup_midi_control ();
311 /* Pay attention ... */
313 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
314 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
317 when_engine_running();
320 /* handle this one in a different way than all others, so that its clear what happened */
322 catch (AudioEngine::PortRegistrationFailure& err) {
323 error << _("Unable to create all required ports")
332 send_full_time_code ();
333 _engine.transport_locate (0);
334 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
335 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
337 ControlProtocolManager::instance().set_session (*this);
340 _end_location_is_free = true;
342 _end_location_is_free = false;
349 Session::raid_path () const
353 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
358 return path.substr (0, path.length() - 1); // drop final colon
362 Session::setup_raid_path (string path)
364 string::size_type colon;
368 string::size_type len = path.length();
373 if (path.length() == 0) {
377 session_dirs.clear ();
379 for (string::size_type n = 0; n < len; ++n) {
380 if (path[n] == ':') {
387 /* no multiple search path, just one location (common case) */
391 session_dirs.push_back (sp);
398 if (fspath[fspath.length()-1] != '/') {
402 fspath += sound_dir (false);
404 AudioFileSource::set_search_path (fspath);
411 while ((colon = remaining.find_first_of (':')) != string::npos) {
414 sp.path = remaining.substr (0, colon);
415 session_dirs.push_back (sp);
417 /* add sounds to file search path */
420 if (fspath[fspath.length()-1] != '/') {
423 fspath += sound_dir (false);
426 remaining = remaining.substr (colon+1);
429 if (remaining.length()) {
436 if (fspath[fspath.length()-1] != '/') {
439 fspath += sound_dir (false);
442 session_dirs.push_back (sp);
445 /* set the AudioFileSource search path */
447 AudioFileSource::set_search_path (fspath);
449 /* reset the round-robin soundfile path thingie */
451 last_rr_session_dir = session_dirs.begin();
455 Session::create (bool& new_session, string* mix_template, nframes_t initial_length)
459 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
460 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
466 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
467 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
471 /* if this is is an existing session with an old "sounds" directory, just use it. see Session::sound_dir() for more details */
473 if (!Glib::file_test (old_sound_dir(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
477 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
478 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
483 dir = dead_sound_dir ();
485 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
486 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
490 dir = automation_dir ();
492 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
493 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
499 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
500 error << string_compose(_("Session: cannot create session export dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
505 /* check new_session so we don't overwrite an existing one */
508 std::string in_path = *mix_template;
510 ifstream in(in_path.c_str());
513 string out_path = _path;
515 out_path += _statefile_suffix;
517 ofstream out(out_path.c_str());
522 // okay, session is set up. Treat like normal saved
523 // session from now on.
529 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
535 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
542 /* set initial start + end point */
544 start_location->set_end (0);
545 _locations.add (start_location);
547 end_location->set_end (initial_length);
548 _locations.add (end_location);
550 _state_of_the_state = Clean;
552 if (save_state (_current_snapshot_name)) {
560 Session::load_diskstreams (const XMLNode& node)
563 XMLNodeConstIterator citer;
565 clist = node.children();
567 for (citer = clist.begin(); citer != clist.end(); ++citer) {
571 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
572 add_diskstream (dstream);
575 catch (failed_constructor& err) {
576 error << _("Session: could not load diskstream via XML state") << endmsg;
585 Session::remove_pending_capture_state ()
590 xml_path += _current_snapshot_name;
591 xml_path += _pending_suffix;
593 unlink (xml_path.c_str());
596 /** Rename a state file.
597 * @param snapshot_name Snapshot name.
600 Session::rename_state (string old_name, string new_name)
602 if (old_name == _current_snapshot_name || old_name == _name) {
603 /* refuse to rename the current snapshot or the "main" one */
607 const string old_xml_path = _path + old_name + _statefile_suffix;
608 const string new_xml_path = _path + new_name + _statefile_suffix;
610 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
611 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
615 /** Remove a state file.
616 * @param snapshot_name Snapshot name.
619 Session::remove_state (string snapshot_name)
621 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
622 /* refuse to remove the current snapshot or the "main" one */
626 const string xml_path = _path + snapshot_name + _statefile_suffix;
628 /* make a backup copy of the state file */
629 const string bak_path = xml_path + ".bak";
630 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
631 copy_file (xml_path, bak_path);
635 unlink (xml_path.c_str());
639 Session::save_state (string snapshot_name, bool pending)
645 if (_state_of_the_state & CannotSave) {
649 if (!_engine.connected ()) {
650 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
655 tree.set_root (&get_state());
657 if (snapshot_name.empty()) {
658 snapshot_name = _current_snapshot_name;
663 /* proper save: use _statefile_suffix (.ardour in English) */
665 xml_path += snapshot_name;
666 xml_path += _statefile_suffix;
668 /* make a backup copy of the old file */
672 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
673 copy_file (xml_path, bak_path);
678 /* pending save: use _pending_suffix (.pending in English) */
680 xml_path += snapshot_name;
681 xml_path += _pending_suffix;
688 tmp_path += snapshot_name;
691 cerr << "actually writing state\n";
693 if (!tree.write (tmp_path)) {
694 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
695 unlink (tmp_path.c_str());
700 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
701 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
702 unlink (tmp_path.c_str());
709 save_history (snapshot_name);
711 bool was_dirty = dirty();
713 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
716 DirtyChanged (); /* EMIT SIGNAL */
719 StateSaved (snapshot_name); /* EMIT SIGNAL */
726 Session::restore_state (string snapshot_name)
728 if (load_state (snapshot_name) == 0) {
729 set_state (*state_tree->root());
736 Session::load_state (string snapshot_name)
745 state_was_pending = false;
747 /* check for leftover pending state from a crashed capture attempt */
750 xmlpath += snapshot_name;
751 xmlpath += _pending_suffix;
753 if (!access (xmlpath.c_str(), F_OK)) {
755 /* there is pending state from a crashed capture attempt */
757 if (AskAboutPendingState()) {
758 state_was_pending = true;
762 if (!state_was_pending) {
765 xmlpath += snapshot_name;
766 xmlpath += _statefile_suffix;
769 if (access (xmlpath.c_str(), F_OK)) {
770 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
774 state_tree = new XMLTree;
778 if (!state_tree->read (xmlpath)) {
779 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
785 XMLNode& root (*state_tree->root());
787 if (root.name() != X_("Session")) {
788 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
794 const XMLProperty* prop;
797 if ((prop = root.property ("version")) == 0) {
798 /* no version implies very old version of Ardour */
802 major_version = atoi (prop->value()); // grab just the first number before the period
803 if (major_version < 2) {
811 backup_path = xmlpath;
814 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
815 xmlpath, backup_path)
818 copy_file (xmlpath, backup_path);
820 /* if it fails, don't worry. right? */
827 Session::load_options (const XMLNode& node)
831 LocaleGuard lg (X_("POSIX"));
833 Config->set_variables (node, ConfigVariableBase::Session);
835 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
836 if ((prop = child->property ("val")) != 0) {
837 _end_location_is_free = (prop->value() == "yes");
845 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
847 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
848 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
850 return owner & modified_by_session_or_user;
854 Session::get_options () const
857 LocaleGuard lg (X_("POSIX"));
859 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
861 child = option_root.add_child ("end-marker-is-free");
862 child->add_property ("val", _end_location_is_free ? "yes" : "no");
874 Session::get_template()
876 /* if we don't disable rec-enable, diskstreams
877 will believe they need to store their capture
878 sources in their state node.
881 disable_record (false);
887 Session::state(bool full_state)
889 XMLNode* node = new XMLNode("Session");
892 // store libardour version, just in case
894 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
895 libardour_major_version, libardour_minor_version, libardour_micro_version);
896 node->add_property("version", string(buf));
898 /* store configuration settings */
903 node->add_property ("name", _name);
905 if (session_dirs.size() > 1) {
909 vector<space_and_path>::iterator i = session_dirs.begin();
910 vector<space_and_path>::iterator next;
912 ++i; /* skip the first one */
916 while (i != session_dirs.end()) {
920 if (next != session_dirs.end()) {
930 child = node->add_child ("Path");
931 child->add_content (p);
935 /* save the ID counter */
937 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
938 node->add_property ("id-counter", buf);
940 /* various options */
942 node->add_child_nocopy (get_options());
944 child = node->add_child ("Sources");
947 Glib::Mutex::Lock sl (audio_source_lock);
949 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
951 /* Don't save information about AudioFileSources that are empty */
953 boost::shared_ptr<AudioFileSource> fs;
955 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
957 /* destructive file sources are OK if they are empty, because
958 we will re-use them every time.
961 if (!fs->destructive()) {
962 if (fs->length() == 0) {
968 child->add_child_nocopy (siter->second->get_state());
972 child = node->add_child ("Regions");
975 Glib::Mutex::Lock rl (region_lock);
977 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
979 /* only store regions not attached to playlists */
981 if (i->second->playlist() == 0) {
982 child->add_child_nocopy (i->second->state (true));
987 child = node->add_child ("DiskStreams");
990 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
991 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
992 if (!(*i)->hidden()) {
993 child->add_child_nocopy ((*i)->get_state());
999 node->add_child_nocopy (_locations.get_state());
1001 // for a template, just create a new Locations, populate it
1002 // with the default start and end, and get the state for that.
1004 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1005 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1008 end->set_end(compute_initial_length());
1010 node->add_child_nocopy (loc.get_state());
1013 child = node->add_child ("Connections");
1015 Glib::Mutex::Lock lm (connection_lock);
1016 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1017 if (!(*i)->system_dependent()) {
1018 child->add_child_nocopy ((*i)->get_state());
1023 child = node->add_child ("Routes");
1025 boost::shared_ptr<RouteList> r = routes.reader ();
1027 RoutePublicOrderSorter cmp;
1028 RouteList public_order (*r);
1029 public_order.sort (cmp);
1031 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1032 if (!(*i)->hidden()) {
1034 child->add_child_nocopy ((*i)->get_state());
1036 child->add_child_nocopy ((*i)->get_template());
1043 child = node->add_child ("EditGroups");
1044 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1045 child->add_child_nocopy ((*i)->get_state());
1048 child = node->add_child ("MixGroups");
1049 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1050 child->add_child_nocopy ((*i)->get_state());
1053 child = node->add_child ("Playlists");
1054 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1055 if (!(*i)->hidden()) {
1056 if (!(*i)->empty()) {
1058 child->add_child_nocopy ((*i)->get_state());
1060 child->add_child_nocopy ((*i)->get_template());
1066 child = node->add_child ("UnusedPlaylists");
1067 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1068 if (!(*i)->hidden()) {
1069 if (!(*i)->empty()) {
1071 child->add_child_nocopy ((*i)->get_state());
1073 child->add_child_nocopy ((*i)->get_template());
1081 child = node->add_child ("Click");
1082 child->add_child_nocopy (_click_io->state (full_state));
1086 child = node->add_child ("NamedSelections");
1087 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1089 child->add_child_nocopy ((*i)->get_state());
1094 node->add_child_nocopy (_tempo_map->get_state());
1096 node->add_child_nocopy (get_control_protocol_state());
1099 node->add_child_copy (*_extra_xml);
1106 Session::get_control_protocol_state ()
1108 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1109 return cpm.get_state();
1113 Session::set_state (const XMLNode& node)
1117 const XMLProperty* prop;
1120 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1122 if (node.name() != X_("Session")){
1123 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1127 if ((prop = node.property ("name")) != 0) {
1128 _name = prop->value ();
1131 setup_raid_path(_path);
1133 if ((prop = node.property (X_("id-counter"))) != 0) {
1135 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1136 ID::init_counter (x);
1138 /* old sessions used a timebased counter, so fake
1139 the startup ID counter based on a standard
1144 ID::init_counter (now);
1148 IO::disable_ports ();
1149 IO::disable_connecting ();
1151 /* Object loading order:
1169 if (use_config_midi_ports ()) {
1172 if ((child = find_named_node (node, "extra")) != 0) {
1173 _extra_xml = new XMLNode (*child);
1176 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1177 load_options (*child);
1178 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1179 load_options (*child);
1181 error << _("Session: XML state has no options section") << endmsg;
1184 if ((child = find_named_node (node, "Locations")) == 0) {
1185 error << _("Session: XML state has no locations section") << endmsg;
1187 } else if (_locations.set_state (*child)) {
1193 if ((location = _locations.auto_loop_location()) != 0) {
1194 set_auto_loop_location (location);
1197 if ((location = _locations.auto_punch_location()) != 0) {
1198 set_auto_punch_location (location);
1201 if ((location = _locations.end_location()) == 0) {
1202 _locations.add (end_location);
1204 delete end_location;
1205 end_location = location;
1208 if ((location = _locations.start_location()) == 0) {
1209 _locations.add (start_location);
1211 delete start_location;
1212 start_location = location;
1215 AudioFileSource::set_header_position_offset (start_location->start());
1217 if ((child = find_named_node (node, "Sources")) == 0) {
1218 error << _("Session: XML state has no sources section") << endmsg;
1220 } else if (load_sources (*child)) {
1224 if ((child = find_named_node (node, "Regions")) == 0) {
1225 error << _("Session: XML state has no Regions section") << endmsg;
1227 } else if (load_regions (*child)) {
1231 if ((child = find_named_node (node, "Playlists")) == 0) {
1232 error << _("Session: XML state has no playlists section") << endmsg;
1234 } else if (load_playlists (*child)) {
1238 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1240 } else if (load_unused_playlists (*child)) {
1244 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1245 if (load_named_selections (*child)) {
1250 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1251 error << _("Session: XML state has no diskstreams section") << endmsg;
1253 } else if (load_diskstreams (*child)) {
1257 if ((child = find_named_node (node, "Connections")) == 0) {
1258 error << _("Session: XML state has no connections section") << endmsg;
1260 } else if (load_connections (*child)) {
1264 if ((child = find_named_node (node, "EditGroups")) == 0) {
1265 error << _("Session: XML state has no edit groups section") << endmsg;
1267 } else if (load_edit_groups (*child)) {
1271 if ((child = find_named_node (node, "MixGroups")) == 0) {
1272 error << _("Session: XML state has no mix groups section") << endmsg;
1274 } else if (load_mix_groups (*child)) {
1278 if ((child = find_named_node (node, "TempoMap")) == 0) {
1279 error << _("Session: XML state has no Tempo Map section") << endmsg;
1281 } else if (_tempo_map->set_state (*child)) {
1285 if ((child = find_named_node (node, "Routes")) == 0) {
1286 error << _("Session: XML state has no routes section") << endmsg;
1288 } else if (load_routes (*child)) {
1292 if ((child = find_named_node (node, "Click")) == 0) {
1293 warning << _("Session: XML state has no click section") << endmsg;
1294 } else if (_click_io) {
1295 _click_io->set_state (*child);
1298 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1299 ControlProtocolManager::instance().set_protocol_states (*child);
1302 /* here beginneth the second phase ... */
1304 StateReady (); /* EMIT SIGNAL */
1306 _state_of_the_state = Clean;
1308 if (state_was_pending) {
1309 save_state (_current_snapshot_name);
1310 remove_pending_capture_state ();
1311 state_was_pending = false;
1321 Session::load_routes (const XMLNode& node)
1324 XMLNodeConstIterator niter;
1325 RouteList new_routes;
1327 nlist = node.children();
1331 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1333 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1336 error << _("Session: cannot create Route from XML description.") << endmsg;
1340 new_routes.push_back (route);
1343 add_routes (new_routes);
1348 boost::shared_ptr<Route>
1349 Session::XMLRouteFactory (const XMLNode& node)
1351 if (node.name() != "Route") {
1352 return boost::shared_ptr<Route> ((Route*) 0);
1355 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1356 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1359 boost::shared_ptr<Route> x (new Route (*this, node));
1365 Session::load_regions (const XMLNode& node)
1368 XMLNodeConstIterator niter;
1369 boost::shared_ptr<AudioRegion> region;
1371 nlist = node.children();
1375 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1376 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1377 error << _("Session: cannot create Region from XML description.") << endmsg;
1384 boost::shared_ptr<AudioRegion>
1385 Session::XMLRegionFactory (const XMLNode& node, bool full)
1387 const XMLProperty* prop;
1388 boost::shared_ptr<Source> source;
1389 boost::shared_ptr<AudioSource> as;
1391 uint32_t nchans = 1;
1394 if (node.name() != X_("Region")) {
1395 return boost::shared_ptr<AudioRegion>();
1398 if ((prop = node.property (X_("channels"))) != 0) {
1399 nchans = atoi (prop->value().c_str());
1403 if ((prop = node.property ("name")) == 0) {
1404 cerr << "no name for this region\n";
1408 if ((prop = node.property (X_("source-0"))) == 0) {
1409 if ((prop = node.property ("source")) == 0) {
1410 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1411 return boost::shared_ptr<AudioRegion>();
1415 PBD::ID s_id (prop->value());
1417 if ((source = source_by_id (s_id)) == 0) {
1418 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1419 return boost::shared_ptr<AudioRegion>();
1422 as = boost::dynamic_pointer_cast<AudioSource>(source);
1424 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1425 return boost::shared_ptr<AudioRegion>();
1428 sources.push_back (as);
1430 /* pickup other channels */
1432 for (uint32_t n=1; n < nchans; ++n) {
1433 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1434 if ((prop = node.property (buf)) != 0) {
1436 PBD::ID id2 (prop->value());
1438 if ((source = source_by_id (id2)) == 0) {
1439 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1440 return boost::shared_ptr<AudioRegion>();
1443 as = boost::dynamic_pointer_cast<AudioSource>(source);
1445 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1446 return boost::shared_ptr<AudioRegion>();
1448 sources.push_back (as);
1453 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1455 /* a final detail: this is the one and only place that we know how long missing files are */
1457 if (region->whole_file()) {
1458 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1459 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1461 sfp->set_length (region->length());
1471 catch (failed_constructor& err) {
1472 return boost::shared_ptr<AudioRegion>();
1477 Session::get_sources_as_xml ()
1480 XMLNode* node = new XMLNode (X_("Sources"));
1481 Glib::Mutex::Lock lm (audio_source_lock);
1483 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1484 node->add_child_nocopy (i->second->get_state());
1487 /* XXX get MIDI and other sources here */
1493 Session::path_from_region_name (string name, string identifier)
1495 char buf[PATH_MAX+1];
1497 string dir = discover_best_sound_dir ();
1499 for (n = 0; n < 999999; ++n) {
1500 if (identifier.length()) {
1501 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1502 identifier.c_str(), n);
1504 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1507 if (!g_file_test (buf, G_FILE_TEST_EXISTS)) {
1512 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1521 Session::load_sources (const XMLNode& node)
1524 XMLNodeConstIterator niter;
1525 boost::shared_ptr<Source> source;
1527 nlist = node.children();
1531 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1534 if ((source = XMLSourceFactory (**niter)) == 0) {
1535 error << _("Session: cannot create Source from XML description.") << endmsg;
1539 catch (non_existent_source& err) {
1540 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1541 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1548 boost::shared_ptr<Source>
1549 Session::XMLSourceFactory (const XMLNode& node)
1551 if (node.name() != "Source") {
1552 return boost::shared_ptr<Source>();
1556 return SourceFactory::create (*this, node);
1559 catch (failed_constructor& err) {
1560 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1561 return boost::shared_ptr<Source>();
1566 Session::save_template (string template_name)
1569 string xml_path, bak_path, template_path;
1571 if (_state_of_the_state & CannotSave) {
1576 string dir = template_dir();
1578 if ((dp = opendir (dir.c_str()))) {
1581 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1582 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1587 tree.set_root (&get_template());
1590 xml_path += template_name;
1591 xml_path += _template_suffix;
1593 ifstream in(xml_path.c_str());
1596 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1602 if (!tree.write (xml_path)) {
1603 error << _("mix template not saved") << endmsg;
1611 Session::rename_template (string old_name, string new_name)
1613 string old_path = template_dir() + old_name + _template_suffix;
1614 string new_path = template_dir() + new_name + _template_suffix;
1616 return rename (old_path.c_str(), new_path.c_str());
1620 Session::delete_template (string name)
1622 string template_path = template_dir();
1623 template_path += name;
1624 template_path += _template_suffix;
1626 return remove (template_path.c_str());
1630 Session::refresh_disk_space ()
1633 struct statfs statfsbuf;
1634 vector<space_and_path>::iterator i;
1635 Glib::Mutex::Lock lm (space_lock);
1638 /* get freespace on every FS that is part of the session path */
1640 _total_free_4k_blocks = 0;
1642 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1643 statfs ((*i).path.c_str(), &statfsbuf);
1645 scale = statfsbuf.f_bsize/4096.0;
1647 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1648 _total_free_4k_blocks += (*i).blocks;
1654 Session::ensure_sound_dir (string path, string& result)
1659 /* Ensure that the parent directory exists */
1661 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1662 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1666 /* Ensure that the sounds directory exists */
1670 result += sound_dir_name;
1672 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1673 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1679 dead += dead_sound_dir_name;
1681 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1682 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1688 peak += peak_dir_name;
1690 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1691 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1695 /* callers expect this to be terminated ... */
1702 Session::discover_best_sound_dir (bool destructive)
1704 vector<space_and_path>::iterator i;
1707 /* handle common case without system calls */
1709 if (session_dirs.size() == 1) {
1713 /* OK, here's the algorithm we're following here:
1715 We want to select which directory to use for
1716 the next file source to be created. Ideally,
1717 we'd like to use a round-robin process so as to
1718 get maximum performance benefits from splitting
1719 the files across multiple disks.
1721 However, in situations without much diskspace, an
1722 RR approach may end up filling up a filesystem
1723 with new files while others still have space.
1724 Its therefore important to pay some attention to
1725 the freespace in the filesystem holding each
1726 directory as well. However, if we did that by
1727 itself, we'd keep creating new files in the file
1728 system with the most space until it was as full
1729 as all others, thus negating any performance
1730 benefits of this RAID-1 like approach.
1732 So, we use a user-configurable space threshold. If
1733 there are at least 2 filesystems with more than this
1734 much space available, we use RR selection between them.
1735 If not, then we pick the filesystem with the most space.
1737 This gets a good balance between the two
1741 refresh_disk_space ();
1743 int free_enough = 0;
1745 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1746 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1751 if (free_enough >= 2) {
1753 bool found_it = false;
1755 /* use RR selection process, ensuring that the one
1759 i = last_rr_session_dir;
1762 if (++i == session_dirs.end()) {
1763 i = session_dirs.begin();
1766 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1767 if (ensure_sound_dir ((*i).path, result) == 0) {
1768 last_rr_session_dir = i;
1774 } while (i != last_rr_session_dir);
1777 result = sound_dir();
1782 /* pick FS with the most freespace (and that
1783 seems to actually work ...)
1786 vector<space_and_path> sorted;
1787 space_and_path_ascending_cmp cmp;
1789 sorted = session_dirs;
1790 sort (sorted.begin(), sorted.end(), cmp);
1792 for (i = sorted.begin(); i != sorted.end(); ++i) {
1793 if (ensure_sound_dir ((*i).path, result) == 0) {
1794 last_rr_session_dir = i;
1799 /* if the above fails, fall back to the most simplistic solution */
1801 if (i == sorted.end()) {
1810 Session::load_playlists (const XMLNode& node)
1813 XMLNodeConstIterator niter;
1814 boost::shared_ptr<Playlist> playlist;
1816 nlist = node.children();
1820 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1822 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1823 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1831 Session::load_unused_playlists (const XMLNode& node)
1834 XMLNodeConstIterator niter;
1835 boost::shared_ptr<Playlist> playlist;
1837 nlist = node.children();
1841 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1843 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1844 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1848 // now manually untrack it
1850 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1857 boost::shared_ptr<Playlist>
1858 Session::XMLPlaylistFactory (const XMLNode& node)
1861 return PlaylistFactory::create (*this, node);
1864 catch (failed_constructor& err) {
1865 return boost::shared_ptr<Playlist>();
1870 Session::load_named_selections (const XMLNode& node)
1873 XMLNodeConstIterator niter;
1876 nlist = node.children();
1880 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1882 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1883 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1891 Session::XMLNamedSelectionFactory (const XMLNode& node)
1894 return new NamedSelection (*this, node);
1897 catch (failed_constructor& err) {
1903 Session::dead_sound_dir () const
1906 res += dead_sound_dir_name;
1912 Session::old_sound_dir (bool with_path) const
1920 res += old_sound_dir_name;
1926 Session::sound_dir (bool with_path) const
1937 res += interchange_dir_name;
1939 res += legalize_for_path (_name);
1941 res += sound_dir_name;
1949 /* if this already exists, don't check for the old session sound directory */
1951 if (Glib::file_test (full, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
1955 /* possibly support old session structure */
1958 string old_withpath;
1960 old_nopath += old_sound_dir_name;
1963 old_withpath = _path;
1964 old_withpath += old_sound_dir_name;
1966 if (Glib::file_test (old_withpath.c_str(), Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
1968 return old_withpath;
1973 /* ok, old "sounds" directory isn't there, return the new path */
1979 Session::peak_dir () const
1982 res += peak_dir_name;
1988 Session::automation_dir () const
1991 res += "automation/";
1996 Session::template_dir ()
1998 string path = get_user_ardour_path();
1999 path += "templates/";
2005 Session::export_dir () const
2008 res += export_dir_name;
2014 Session::suffixed_search_path (string suffix, bool data)
2018 path += get_user_ardour_path();
2019 if (path[path.length()-1] != ':') {
2024 path += get_system_data_path();
2026 path += get_system_module_path();
2029 vector<string> split_path;
2031 split (path, split_path, ':');
2034 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2039 if (distance (i, split_path.end()) != 1) {
2048 Session::template_path ()
2050 return suffixed_search_path (X_("templates"), true);
2054 Session::control_protocol_path ()
2056 return suffixed_search_path (X_("surfaces"), false);
2060 Session::load_connections (const XMLNode& node)
2062 XMLNodeList nlist = node.children();
2063 XMLNodeConstIterator niter;
2067 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2068 if ((*niter)->name() == "InputConnection") {
2069 add_connection (new ARDOUR::InputConnection (**niter));
2070 } else if ((*niter)->name() == "OutputConnection") {
2071 add_connection (new ARDOUR::OutputConnection (**niter));
2073 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2082 Session::load_edit_groups (const XMLNode& node)
2084 return load_route_groups (node, true);
2088 Session::load_mix_groups (const XMLNode& node)
2090 return load_route_groups (node, false);
2094 Session::load_route_groups (const XMLNode& node, bool edit)
2096 XMLNodeList nlist = node.children();
2097 XMLNodeConstIterator niter;
2102 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2103 if ((*niter)->name() == "RouteGroup") {
2105 rg = add_edit_group ("");
2106 rg->set_state (**niter);
2108 rg = add_mix_group ("");
2109 rg->set_state (**niter);
2118 state_file_filter (const string &str, void *arg)
2120 return (str.length() > strlen(Session::statefile_suffix()) &&
2121 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2125 bool operator()(const string* a, const string* b) {
2131 remove_end(string* state)
2133 string statename(*state);
2135 string::size_type start,end;
2136 if ((start = statename.find_last_of ('/')) != string::npos) {
2137 statename = statename.substr (start+1);
2140 if ((end = statename.rfind(".ardour")) == string::npos) {
2141 end = statename.length();
2144 return new string(statename.substr (0, end));
2148 Session::possible_states (string path)
2150 PathScanner scanner;
2151 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2153 transform(states->begin(), states->end(), states->begin(), remove_end);
2156 sort (states->begin(), states->end(), cmp);
2162 Session::possible_states () const
2164 return possible_states(_path);
2168 Session::auto_save()
2170 save_state (_current_snapshot_name);
2174 Session::add_edit_group (string name)
2176 RouteGroup* rg = new RouteGroup (*this, name);
2177 edit_groups.push_back (rg);
2178 edit_group_added (rg); /* EMIT SIGNAL */
2184 Session::add_mix_group (string name)
2186 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2187 mix_groups.push_back (rg);
2188 mix_group_added (rg); /* EMIT SIGNAL */
2194 Session::remove_edit_group (RouteGroup& rg)
2196 list<RouteGroup*>::iterator i;
2198 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2199 (*i)->apply (&Route::drop_edit_group, this);
2200 edit_groups.erase (i);
2201 edit_group_removed (); /* EMIT SIGNAL */
2208 Session::remove_mix_group (RouteGroup& rg)
2210 list<RouteGroup*>::iterator i;
2212 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2213 (*i)->apply (&Route::drop_mix_group, this);
2214 mix_groups.erase (i);
2215 mix_group_removed (); /* EMIT SIGNAL */
2222 Session::mix_group_by_name (string name)
2224 list<RouteGroup *>::iterator i;
2226 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2227 if ((*i)->name() == name) {
2235 Session::edit_group_by_name (string name)
2237 list<RouteGroup *>::iterator i;
2239 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2240 if ((*i)->name() == name) {
2248 Session::begin_reversible_command (string name)
2250 current_trans = new UndoTransaction;
2251 current_trans->set_name (name);
2255 Session::commit_reversible_command (Command *cmd)
2260 current_trans->add_command (cmd);
2263 gettimeofday (&now, 0);
2264 current_trans->set_timestamp (now);
2266 _history.add (current_trans);
2269 Session::GlobalRouteBooleanState
2270 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2272 GlobalRouteBooleanState s;
2273 boost::shared_ptr<RouteList> r = routes.reader ();
2275 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2276 if (!(*i)->hidden()) {
2277 RouteBooleanState v;
2280 Route* r = (*i).get();
2281 v.second = (r->*method)();
2290 Session::GlobalRouteMeterState
2291 Session::get_global_route_metering ()
2293 GlobalRouteMeterState s;
2294 boost::shared_ptr<RouteList> r = routes.reader ();
2296 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2297 if (!(*i)->hidden()) {
2301 v.second = (*i)->meter_point();
2311 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2313 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2315 boost::shared_ptr<Route> r = (i->first.lock());
2318 r->set_meter_point (i->second, arg);
2324 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2326 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2328 boost::shared_ptr<Route> r = (i->first.lock());
2331 Route* rp = r.get();
2332 (rp->*method) (i->second, arg);
2338 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2340 set_global_route_boolean (s, &Route::set_mute, src);
2344 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2346 set_global_route_boolean (s, &Route::set_solo, src);
2350 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2352 set_global_route_boolean (s, &Route::set_record_enable, src);
2357 Session::global_mute_memento (void* src)
2359 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2363 Session::global_metering_memento (void* src)
2365 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2369 Session::global_solo_memento (void* src)
2371 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2375 Session::global_record_enable_memento (void* src)
2377 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2382 template_filter (const string &str, void *arg)
2384 return (str.length() > strlen(Session::template_suffix()) &&
2385 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2389 Session::get_template_list (list<string> &template_names)
2391 vector<string *> *templates;
2392 PathScanner scanner;
2395 path = template_path ();
2397 templates = scanner (path, template_filter, 0, false, true);
2399 vector<string*>::iterator i;
2400 for (i = templates->begin(); i != templates->end(); ++i) {
2401 string fullpath = *(*i);
2404 start = fullpath.find_last_of ('/') + 1;
2405 if ((end = fullpath.find_last_of ('.')) <0) {
2406 end = fullpath.length();
2409 template_names.push_back(fullpath.substr(start, (end-start)));
2414 Session::read_favorite_dirs (FavoriteDirs & favs)
2416 string path = get_user_ardour_path();
2417 path += "/favorite_dirs";
2419 ifstream fav (path.c_str());
2424 if (errno != ENOENT) {
2425 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2436 getline(fav, newfav);
2442 favs.push_back (newfav);
2449 Session::write_favorite_dirs (FavoriteDirs & favs)
2451 string path = get_user_ardour_path();
2452 path += "/favorite_dirs";
2454 ofstream fav (path.c_str());
2460 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2461 fav << (*i) << endl;
2468 accept_all_non_peak_files (const string& path, void *arg)
2470 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2474 accept_all_state_files (const string& path, void *arg)
2476 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2480 Session::find_all_sources (string path, set<string>& result)
2485 if (!tree.read (path)) {
2489 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2494 XMLNodeConstIterator niter;
2496 nlist = node->children();
2500 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2504 if ((prop = (*niter)->property (X_("name"))) == 0) {
2508 if (prop->value()[0] == '/') {
2509 /* external file, ignore */
2513 string path = _path; /* /-terminated */
2514 path += sound_dir_name;
2516 path += prop->value();
2518 result.insert (path);
2525 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2527 PathScanner scanner;
2528 vector<string*>* state_files;
2530 string this_snapshot_path;
2536 if (ripped[ripped.length()-1] == '/') {
2537 ripped = ripped.substr (0, ripped.length() - 1);
2540 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2542 if (state_files == 0) {
2547 this_snapshot_path = _path;
2548 this_snapshot_path += _current_snapshot_name;
2549 this_snapshot_path += _statefile_suffix;
2551 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2553 if (exclude_this_snapshot && **i == this_snapshot_path) {
2557 if (find_all_sources (**i, result) < 0) {
2565 struct RegionCounter {
2566 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2567 AudioSourceList::iterator iter;
2568 boost::shared_ptr<Region> region;
2571 RegionCounter() : count (0) {}
2575 Session::cleanup_sources (Session::cleanup_report& rep)
2577 vector<boost::shared_ptr<Source> > dead_sources;
2578 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2579 PathScanner scanner;
2581 vector<space_and_path>::iterator i;
2582 vector<space_and_path>::iterator nexti;
2583 vector<string*>* soundfiles;
2584 vector<string> unused;
2585 set<string> all_sources;
2590 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2592 /* step 1: consider deleting all unused playlists */
2594 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2597 status = AskAboutPlaylistDeletion (*x);
2606 playlists_tbd.push_back (*x);
2610 /* leave it alone */
2615 /* now delete any that were marked for deletion */
2617 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2618 (*x)->drop_references ();
2621 playlists_tbd.clear ();
2623 /* step 2: find all un-used sources */
2628 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2630 AudioSourceList::iterator tmp;
2635 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2639 if (!i->second->used() && i->second->length() > 0) {
2640 dead_sources.push_back (i->second);
2641 i->second->GoingAway();
2647 /* build a list of all the possible sound directories for the session */
2649 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2654 sound_path += (*i).path;
2655 sound_path += sound_dir (false);
2657 if (nexti != session_dirs.end()) {
2664 /* now do the same thing for the files that ended up in the sounds dir(s)
2665 but are not referenced as sources in any snapshot.
2668 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2670 if (soundfiles == 0) {
2674 /* find all sources, but don't use this snapshot because the
2675 state file on disk still references sources we may have already
2679 find_all_sources_across_snapshots (all_sources, true);
2681 /* add our current source list
2684 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2685 boost::shared_ptr<AudioFileSource> fs;
2687 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2688 all_sources.insert (fs->path());
2692 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2697 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2706 unused.push_back (spath);
2710 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2712 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2713 struct stat statbuf;
2715 rep.paths.push_back (*x);
2716 if (stat ((*x).c_str(), &statbuf) == 0) {
2717 rep.space += statbuf.st_size;
2722 /* don't move the file across filesystems, just
2723 stick it in the `dead_sound_dir_name' directory
2724 on whichever filesystem it was already on.
2727 if ((*x).find ("/sounds/") != string::npos) {
2729 /* old school, go up 1 level */
2731 newpath = Glib::path_get_dirname (*x); // "sounds"
2732 newpath = Glib::path_get_dirname (newpath); // "session-name"
2736 /* new school, go up 4 levels */
2738 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2739 newpath = Glib::path_get_dirname (newpath); // "session-name"
2740 newpath = Glib::path_get_dirname (newpath); // "interchange"
2741 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2745 newpath += dead_sound_dir_name;
2747 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2748 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2753 newpath += Glib::path_get_basename ((*x));
2755 if (access (newpath.c_str(), F_OK) == 0) {
2757 /* the new path already exists, try versioning */
2759 char buf[PATH_MAX+1];
2763 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2766 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2767 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2771 if (version == 999) {
2772 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2776 newpath = newpath_v;
2781 /* it doesn't exist, or we can't read it or something */
2785 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2786 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2787 (*x), newpath, strerror (errno))
2792 /* see if there an easy to find peakfile for this file, and remove it.
2795 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2796 peakpath += ".peak";
2798 if (access (peakpath.c_str(), W_OK) == 0) {
2799 if (::unlink (peakpath.c_str()) != 0) {
2800 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2801 peakpath, _path, strerror (errno))
2803 /* try to back out */
2804 rename (newpath.c_str(), _path.c_str());
2812 /* dump the history list */
2816 /* save state so we don't end up a session file
2817 referring to non-existent sources.
2823 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2828 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2830 vector<space_and_path>::iterator i;
2831 string dead_sound_dir;
2832 struct dirent* dentry;
2833 struct stat statbuf;
2839 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2841 dead_sound_dir = (*i).path;
2842 dead_sound_dir += dead_sound_dir_name;
2844 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2848 while ((dentry = readdir (dead)) != 0) {
2850 /* avoid '.' and '..' */
2852 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2853 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2859 fullpath = dead_sound_dir;
2861 fullpath += dentry->d_name;
2863 if (stat (fullpath.c_str(), &statbuf)) {
2867 if (!S_ISREG (statbuf.st_mode)) {
2871 if (unlink (fullpath.c_str())) {
2872 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2873 fullpath, strerror (errno))
2877 rep.paths.push_back (dentry->d_name);
2878 rep.space += statbuf.st_size;
2889 Session::set_dirty ()
2891 bool was_dirty = dirty();
2893 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2896 DirtyChanged(); /* EMIT SIGNAL */
2902 Session::set_clean ()
2904 bool was_dirty = dirty();
2906 _state_of_the_state = Clean;
2909 DirtyChanged(); /* EMIT SIGNAL */
2914 Session::set_deletion_in_progress ()
2916 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2920 Session::add_controllable (Controllable* c)
2922 /* this adds a controllable to the list managed by the Session.
2923 this is a subset of those managed by the Controllable class
2924 itself, and represents the only ones whose state will be saved
2925 as part of the session.
2928 Glib::Mutex::Lock lm (controllables_lock);
2929 controllables.insert (c);
2933 Session::remove_controllable (Controllable* c)
2935 if (_state_of_the_state | Deletion) {
2939 Glib::Mutex::Lock lm (controllables_lock);
2941 Controllables::iterator x = controllables.find (c);
2943 if (x != controllables.end()) {
2944 controllables.erase (x);
2949 Session::controllable_by_id (const PBD::ID& id)
2951 Glib::Mutex::Lock lm (controllables_lock);
2953 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2954 if ((*i)->id() == id) {
2963 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2965 Stateful::add_instant_xml (node, dir);
2966 Config->add_instant_xml (node, get_user_ardour_path());
2971 Session::save_history (string snapshot_name)
2977 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2979 if (snapshot_name.empty()) {
2980 snapshot_name = _current_snapshot_name;
2983 xml_path = _path + snapshot_name + ".history";
2985 bak_path = xml_path + ".bak";
2987 if ((access (xml_path.c_str(), F_OK) == 0) &&
2988 (rename (xml_path.c_str(), bak_path.c_str())))
2990 error << _("could not backup old history file, current history not saved.") << endmsg;
2994 if (!tree.write (xml_path))
2996 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2998 /* don't leave a corrupt file lying around if it is
3002 if (unlink (xml_path.c_str())) {
3003 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
3005 if (rename (bak_path.c_str(), xml_path.c_str()))
3007 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
3018 Session::restore_history (string snapshot_name)
3023 if (snapshot_name.empty()) {
3024 snapshot_name = _current_snapshot_name;
3028 xmlpath = _path + snapshot_name + ".history";
3029 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
3031 if (access (xmlpath.c_str(), F_OK)) {
3032 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
3036 if (!tree.read (xmlpath)) {
3037 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
3041 /* replace history */
3044 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3047 UndoTransaction* ut = new UndoTransaction ();
3050 ut->set_name(t->property("name")->value());
3051 stringstream ss(t->property("tv_sec")->value());
3053 ss.str(t->property("tv_usec")->value());
3055 ut->set_timestamp(tv);
3057 for (XMLNodeConstIterator child_it = t->children().begin();
3058 child_it != t->children().end();
3061 XMLNode *n = *child_it;
3064 if (n->name() == "MementoCommand" ||
3065 n->name() == "MementoUndoCommand" ||
3066 n->name() == "MementoRedoCommand") {
3068 if ((c = memento_command_factory(n))) {
3072 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3074 if ((c = global_state_command_factory (*n))) {
3075 ut->add_command (c);
3080 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3091 Session::config_changed (const char* parameter_name)
3093 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3095 if (PARAM_IS ("seamless-loop")) {
3097 } else if (PARAM_IS ("rf-speed")) {
3099 } else if (PARAM_IS ("auto-loop")) {
3101 } else if (PARAM_IS ("auto-input")) {
3103 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3104 /* auto-input only makes a difference if we're rolling */
3106 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3108 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3109 if ((*i)->record_enabled ()) {
3110 (*i)->monitor_input (!Config->get_auto_input());
3115 } else if (PARAM_IS ("punch-in")) {
3119 if ((location = _locations.auto_punch_location()) != 0) {
3121 if (Config->get_punch_in ()) {
3122 replace_event (Event::PunchIn, location->start());
3124 remove_event (location->start(), Event::PunchIn);
3128 } else if (PARAM_IS ("punch-out")) {
3132 if ((location = _locations.auto_punch_location()) != 0) {
3134 if (Config->get_punch_out()) {
3135 replace_event (Event::PunchOut, location->end());
3137 clear_events (Event::PunchOut);
3141 } else if (PARAM_IS ("edit-mode")) {
3143 Glib::Mutex::Lock lm (playlist_lock);
3145 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3146 (*i)->set_edit_mode (Config->get_edit_mode ());
3149 } else if (PARAM_IS ("use-video-sync")) {
3151 if (transport_stopped()) {
3152 if (Config->get_use_video_sync()) {
3153 waiting_for_sync_offset = true;
3157 } else if (PARAM_IS ("mmc-control")) {
3159 poke_midi_thread ();
3161 } else if (PARAM_IS ("mmc-device-id")) {
3164 mmc->set_device_id (Config->get_mmc_device_id());
3167 } else if (PARAM_IS ("midi-control")) {
3169 poke_midi_thread ();
3171 } else if (PARAM_IS ("raid-path")) {
3173 setup_raid_path (Config->get_raid_path());
3175 } else if (PARAM_IS ("smpte-format")) {
3179 } else if (PARAM_IS ("video-pullup")) {
3183 } else if (PARAM_IS ("seamless-loop")) {
3185 if (play_loop && transport_rolling()) {
3186 // to reset diskstreams etc
3187 request_play_loop (true);
3190 } else if (PARAM_IS ("rf-speed")) {
3192 cumulative_rf_motion = 0;
3195 } else if (PARAM_IS ("click-sound")) {
3197 setup_click_sounds (1);
3199 } else if (PARAM_IS ("click-emphasis-sound")) {
3201 setup_click_sounds (-1);
3203 } else if (PARAM_IS ("clicking")) {
3205 if (Config->get_clicking()) {
3206 if (_click_io && click_data) { // don't require emphasis data
3213 } else if (PARAM_IS ("send-mtc")) {
3215 /* only set the internal flag if we have
3219 if (_mtc_port != 0) {
3220 session_send_mtc = Config->get_send_mtc();
3221 if (session_send_mtc) {
3222 /* mark us ready to send */
3223 next_quarter_frame_to_send = 0;
3226 session_send_mtc = false;
3229 } else if (PARAM_IS ("send-mmc")) {
3231 /* only set the internal flag if we have
3235 if (_mmc_port != 0) {
3236 session_send_mmc = Config->get_send_mmc();
3239 session_send_mmc = false;
3242 } else if (PARAM_IS ("midi-feedback")) {
3244 /* only set the internal flag if we have
3248 if (_mtc_port != 0) {
3249 session_midi_feedback = Config->get_midi_feedback();
3252 } else if (PARAM_IS ("jack-time-master")) {
3254 engine().reset_timebase ();
3256 } else if (PARAM_IS ("native-file-header-format")) {
3258 if (!first_file_header_format_reset) {
3259 reset_native_file_format ();
3262 first_file_header_format_reset = false;
3264 } else if (PARAM_IS ("native-file-data-format")) {
3266 if (!first_file_data_format_reset) {
3267 reset_native_file_format ();
3270 first_file_data_format_reset = false;
3272 } else if (PARAM_IS ("slave-source")) {
3273 set_slave_source (Config->get_slave_source());
3274 } else if (PARAM_IS ("remote-model")) {
3275 set_remote_control_ids ();