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 _requested_return_frame = -1;
142 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
143 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
144 _end_location_is_free = true;
145 g_atomic_int_set (&_record_status, Disabled);
146 loop_changing = false;
148 _last_roll_location = 0;
149 _last_record_location = 0;
150 pending_locate_frame = 0;
151 pending_locate_roll = false;
152 pending_locate_flush = false;
153 dstream_buffer_size = 0;
155 state_was_pending = false;
157 outbound_mtc_smpte_frame = 0;
158 next_quarter_frame_to_send = -1;
159 current_block_size = 0;
160 solo_update_disabled = false;
161 currently_soloing = false;
162 _have_captured = false;
163 _worst_output_latency = 0;
164 _worst_input_latency = 0;
165 _worst_track_latency = 0;
166 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
169 butler_mixdown_buffer = 0;
170 butler_gain_buffer = 0;
172 session_send_mmc = false;
173 session_send_mtc = false;
174 post_transport_work = PostTransportWork (0);
175 g_atomic_int_set (&butler_should_do_transport_work, 0);
176 g_atomic_int_set (&butler_active, 0);
177 g_atomic_int_set (&_playback_load, 100);
178 g_atomic_int_set (&_capture_load, 100);
179 g_atomic_int_set (&_playback_load_min, 100);
180 g_atomic_int_set (&_capture_load_min, 100);
182 waiting_to_start = false;
184 _gain_automation_buffer = 0;
185 _pan_automation_buffer = 0;
187 pending_abort = false;
188 destructive_index = 0;
190 first_file_data_format_reset = true;
191 first_file_header_format_reset = true;
192 butler_thread = (pthread_t) 0;
193 midi_thread = (pthread_t) 0;
195 AudioDiskstream::allocate_working_buffers();
197 /* default short fade = 15ms */
199 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
200 SndFileSource::setup_standard_crossfades (frame_rate());
202 last_mmc_step.tv_sec = 0;
203 last_mmc_step.tv_usec = 0;
206 /* click sounds are unset by default, which causes us to internal
207 waveforms for clicks.
211 click_emphasis_data = 0;
213 click_emphasis_length = 0;
216 process_function = &Session::process_with_events;
218 if (Config->get_use_video_sync()) {
219 waiting_for_sync_offset = true;
221 waiting_for_sync_offset = false;
224 _current_frame_rate = 48000;
225 _base_frame_rate = 48000;
229 _smpte_offset_negative = true;
230 last_smpte_valid = false;
234 last_rr_session_dir = session_dirs.begin();
235 refresh_disk_space ();
237 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
241 average_slave_delta = 1800;
242 have_first_delta_accumulator = false;
243 delta_accumulator_cnt = 0;
244 slave_state = Stopped;
246 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
248 /* These are all static "per-class" signals */
250 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
251 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
252 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
253 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
254 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
255 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
257 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
259 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
261 /* stop IO objects from doing stuff until we're ready for them */
263 IO::disable_panners ();
264 IO::disable_ports ();
265 IO::disable_connecting ();
269 Session::second_stage_init (bool new_session)
271 AudioFileSource::set_peak_dir (peak_dir());
274 if (load_state (_current_snapshot_name)) {
277 remove_empty_sounds ();
280 if (start_butler_thread()) {
284 if (start_midi_thread ()) {
288 // set_state() will call setup_raid_path(), but if it's a new session we need
289 // to call setup_raid_path() here.
291 if (set_state (*state_tree->root())) {
295 setup_raid_path(_path);
298 /* we can't save till after ::when_engine_running() is called,
299 because otherwise we save state with no connections made.
300 therefore, we reset _state_of_the_state because ::set_state()
301 will have cleared it.
303 we also have to include Loading so that any events that get
304 generated between here and the end of ::when_engine_running()
305 will be processed directly rather than queued.
308 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
310 // set_auto_input (true);
311 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
312 _locations.added.connect (mem_fun (this, &Session::locations_added));
313 setup_click_sounds (0);
314 setup_midi_control ();
316 /* Pay attention ... */
318 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
319 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
322 when_engine_running();
325 /* handle this one in a different way than all others, so that its clear what happened */
327 catch (AudioEngine::PortRegistrationFailure& err) {
336 send_full_time_code ();
337 _engine.transport_locate (0);
338 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
339 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
341 ControlProtocolManager::instance().set_session (*this);
344 _end_location_is_free = true;
346 _end_location_is_free = false;
353 Session::raid_path () const
357 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
362 return path.substr (0, path.length() - 1); // drop final colon
366 Session::setup_raid_path (string path)
368 string::size_type colon;
372 string::size_type len = path.length();
377 if (path.length() == 0) {
381 session_dirs.clear ();
383 for (string::size_type n = 0; n < len; ++n) {
384 if (path[n] == ':') {
391 /* no multiple search path, just one location (common case) */
395 session_dirs.push_back (sp);
402 if (fspath[fspath.length()-1] != '/') {
406 fspath += sound_dir (false);
408 AudioFileSource::set_search_path (fspath);
415 while ((colon = remaining.find_first_of (':')) != string::npos) {
418 sp.path = remaining.substr (0, colon);
419 session_dirs.push_back (sp);
421 /* add sounds to file search path */
424 if (fspath[fspath.length()-1] != '/') {
427 fspath += sound_dir (false);
430 remaining = remaining.substr (colon+1);
433 if (remaining.length()) {
440 if (fspath[fspath.length()-1] != '/') {
443 fspath += sound_dir (false);
446 session_dirs.push_back (sp);
449 /* set the AudioFileSource search path */
451 AudioFileSource::set_search_path (fspath);
453 /* reset the round-robin soundfile path thingie */
455 last_rr_session_dir = session_dirs.begin();
459 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
463 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
464 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
470 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
471 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
475 /* if this is is an existing session with an old "sounds" directory, just use it. see Session::sound_dir() for more details */
477 if (!Glib::file_test (old_sound_dir(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
481 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
482 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
487 dir = dead_sound_dir ();
489 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
490 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
496 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
497 error << string_compose(_("Session: cannot create session export dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
502 /* check new_session so we don't overwrite an existing one */
504 if (!mix_template.empty()) {
505 std::string in_path = mix_template;
507 ifstream in(in_path.c_str());
510 string out_path = _path;
512 out_path += _statefile_suffix;
514 ofstream out(out_path.c_str());
519 // okay, session is set up. Treat like normal saved
520 // session from now on.
526 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
532 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
539 /* set initial start + end point */
541 start_location->set_end (0);
542 _locations.add (start_location);
544 end_location->set_end (initial_length);
545 _locations.add (end_location);
547 _state_of_the_state = Clean;
549 if (save_state (_current_snapshot_name)) {
557 Session::load_diskstreams (const XMLNode& node)
560 XMLNodeConstIterator citer;
562 clist = node.children();
564 for (citer = clist.begin(); citer != clist.end(); ++citer) {
568 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
569 add_diskstream (dstream);
572 catch (failed_constructor& err) {
573 error << _("Session: could not load diskstream via XML state") << endmsg;
582 Session::maybe_write_autosave()
584 if (dirty() && record_status() != Recording) {
585 save_state("", true);
590 Session::remove_pending_capture_state ()
595 xml_path += _current_snapshot_name;
596 xml_path += _pending_suffix;
598 unlink (xml_path.c_str());
601 /** Rename a state file.
602 * @param snapshot_name Snapshot name.
605 Session::rename_state (string old_name, string new_name)
607 if (old_name == _current_snapshot_name || old_name == _name) {
608 /* refuse to rename the current snapshot or the "main" one */
612 const string old_xml_path = _path + old_name + _statefile_suffix;
613 const string new_xml_path = _path + new_name + _statefile_suffix;
615 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
616 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
620 /** Remove a state file.
621 * @param snapshot_name Snapshot name.
624 Session::remove_state (string snapshot_name)
626 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
627 /* refuse to remove the current snapshot or the "main" one */
631 const string xml_path = _path + snapshot_name + _statefile_suffix;
633 /* make a backup copy of the state file */
634 const string bak_path = xml_path + ".bak";
635 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
636 copy_file (xml_path, bak_path);
640 unlink (xml_path.c_str());
644 Session::save_state (string snapshot_name, bool pending)
650 if (_state_of_the_state & CannotSave) {
654 if (!_engine.connected ()) {
655 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
660 tree.set_root (&get_state());
662 if (snapshot_name.empty()) {
663 snapshot_name = _current_snapshot_name;
668 /* proper save: use _statefile_suffix (.ardour in English) */
670 xml_path += snapshot_name;
671 xml_path += _statefile_suffix;
673 /* make a backup copy of the old file */
677 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
678 copy_file (xml_path, bak_path);
683 /* pending save: use _pending_suffix (.pending in English) */
685 xml_path += snapshot_name;
686 xml_path += _pending_suffix;
693 tmp_path += snapshot_name;
696 // cerr << "actually writing state to " << xml_path << endl;
698 if (!tree.write (tmp_path)) {
699 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
700 unlink (tmp_path.c_str());
705 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
706 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
707 unlink (tmp_path.c_str());
714 save_history (snapshot_name);
716 bool was_dirty = dirty();
718 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
721 DirtyChanged (); /* EMIT SIGNAL */
724 StateSaved (snapshot_name); /* EMIT SIGNAL */
731 Session::restore_state (string snapshot_name)
733 if (load_state (snapshot_name) == 0) {
734 set_state (*state_tree->root());
741 Session::load_state (string snapshot_name)
750 state_was_pending = false;
752 /* check for leftover pending state from a crashed capture attempt */
755 xmlpath += snapshot_name;
756 xmlpath += _pending_suffix;
758 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
760 /* there is pending state from a crashed capture attempt */
762 if (AskAboutPendingState()) {
763 state_was_pending = true;
767 if (!state_was_pending) {
770 xmlpath += snapshot_name;
771 xmlpath += _statefile_suffix;
774 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
775 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
779 state_tree = new XMLTree;
783 if (!state_tree->read (xmlpath)) {
784 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
790 XMLNode& root (*state_tree->root());
792 if (root.name() != X_("Session")) {
793 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
799 const XMLProperty* prop;
802 if ((prop = root.property ("version")) == 0) {
803 /* no version implies very old version of Ardour */
807 major_version = atoi (prop->value()); // grab just the first number before the period
808 if (major_version < 2) {
817 backup_path += snapshot_name;
819 backup_path += _statefile_suffix;
821 /* don't make another copy if it already exists */
823 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
824 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
825 xmlpath, backup_path)
828 copy_file (xmlpath, backup_path);
830 /* if it fails, don't worry. right? */
838 Session::load_options (const XMLNode& node)
842 LocaleGuard lg (X_("POSIX"));
844 Config->set_variables (node, ConfigVariableBase::Session);
846 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
847 if ((prop = child->property ("val")) != 0) {
848 _end_location_is_free = (prop->value() == "yes");
856 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
858 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
859 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
861 return owner & modified_by_session_or_user;
865 Session::get_options () const
868 LocaleGuard lg (X_("POSIX"));
870 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
872 child = option_root.add_child ("end-marker-is-free");
873 child->add_property ("val", _end_location_is_free ? "yes" : "no");
885 Session::get_template()
887 /* if we don't disable rec-enable, diskstreams
888 will believe they need to store their capture
889 sources in their state node.
892 disable_record (false);
898 Session::state(bool full_state)
900 XMLNode* node = new XMLNode("Session");
903 // store libardour version, just in case
905 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
906 libardour2_major_version, libardour2_minor_version, libardour2_micro_version);
907 node->add_property("version", string(buf));
909 /* store configuration settings */
914 node->add_property ("name", _name);
916 if (session_dirs.size() > 1) {
920 vector<space_and_path>::iterator i = session_dirs.begin();
921 vector<space_and_path>::iterator next;
923 ++i; /* skip the first one */
927 while (i != session_dirs.end()) {
931 if (next != session_dirs.end()) {
941 child = node->add_child ("Path");
942 child->add_content (p);
946 /* save the ID counter */
948 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
949 node->add_property ("id-counter", buf);
951 /* various options */
953 node->add_child_nocopy (get_options());
955 child = node->add_child ("Sources");
958 Glib::Mutex::Lock sl (audio_source_lock);
960 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
962 /* Don't save information about AudioFileSources that are empty */
964 boost::shared_ptr<AudioFileSource> fs;
966 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
968 /* destructive file sources are OK if they are empty, because
969 we will re-use them every time.
972 if (!fs->destructive()) {
973 if (fs->length() == 0) {
979 child->add_child_nocopy (siter->second->get_state());
983 child = node->add_child ("Regions");
986 Glib::Mutex::Lock rl (region_lock);
988 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
990 /* only store regions not attached to playlists */
992 if (i->second->playlist() == 0) {
993 child->add_child_nocopy (i->second->state (true));
998 child = node->add_child ("DiskStreams");
1001 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1002 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1003 if (!(*i)->hidden()) {
1004 child->add_child_nocopy ((*i)->get_state());
1010 node->add_child_nocopy (_locations.get_state());
1012 // for a template, just create a new Locations, populate it
1013 // with the default start and end, and get the state for that.
1015 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1016 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1019 end->set_end(compute_initial_length());
1021 node->add_child_nocopy (loc.get_state());
1024 child = node->add_child ("Connections");
1026 Glib::Mutex::Lock lm (connection_lock);
1027 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1028 if (!(*i)->system_dependent()) {
1029 child->add_child_nocopy ((*i)->get_state());
1034 child = node->add_child ("Routes");
1036 boost::shared_ptr<RouteList> r = routes.reader ();
1038 RoutePublicOrderSorter cmp;
1039 RouteList public_order (*r);
1040 public_order.sort (cmp);
1042 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1043 if (!(*i)->hidden()) {
1045 child->add_child_nocopy ((*i)->get_state());
1047 child->add_child_nocopy ((*i)->get_template());
1054 child = node->add_child ("EditGroups");
1055 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1056 child->add_child_nocopy ((*i)->get_state());
1059 child = node->add_child ("MixGroups");
1060 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1061 child->add_child_nocopy ((*i)->get_state());
1064 child = node->add_child ("Playlists");
1065 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1066 if (!(*i)->hidden()) {
1067 if (!(*i)->empty()) {
1069 child->add_child_nocopy ((*i)->get_state());
1071 child->add_child_nocopy ((*i)->get_template());
1077 child = node->add_child ("UnusedPlaylists");
1078 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1079 if (!(*i)->hidden()) {
1080 if (!(*i)->empty()) {
1082 child->add_child_nocopy ((*i)->get_state());
1084 child->add_child_nocopy ((*i)->get_template());
1092 child = node->add_child ("Click");
1093 child->add_child_nocopy (_click_io->state (full_state));
1097 child = node->add_child ("NamedSelections");
1098 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1100 child->add_child_nocopy ((*i)->get_state());
1105 node->add_child_nocopy (_tempo_map->get_state());
1107 node->add_child_nocopy (get_control_protocol_state());
1110 node->add_child_copy (*_extra_xml);
1117 Session::get_control_protocol_state ()
1119 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1120 return cpm.get_state();
1124 Session::set_state (const XMLNode& node)
1128 const XMLProperty* prop;
1131 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1133 if (node.name() != X_("Session")){
1134 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1138 if ((prop = node.property ("name")) != 0) {
1139 _name = prop->value ();
1142 setup_raid_path(_path);
1144 if ((prop = node.property (X_("id-counter"))) != 0) {
1146 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1147 ID::init_counter (x);
1149 /* old sessions used a timebased counter, so fake
1150 the startup ID counter based on a standard
1155 ID::init_counter (now);
1159 IO::disable_ports ();
1160 IO::disable_connecting ();
1162 /* Object loading order:
1180 if (use_config_midi_ports ()) {
1183 if ((child = find_named_node (node, "extra")) != 0) {
1184 _extra_xml = new XMLNode (*child);
1187 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1188 load_options (*child);
1189 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1190 load_options (*child);
1192 error << _("Session: XML state has no options section") << endmsg;
1195 if ((child = find_named_node (node, "Locations")) == 0) {
1196 error << _("Session: XML state has no locations section") << endmsg;
1198 } else if (_locations.set_state (*child)) {
1204 if ((location = _locations.auto_loop_location()) != 0) {
1205 set_auto_loop_location (location);
1208 if ((location = _locations.auto_punch_location()) != 0) {
1209 set_auto_punch_location (location);
1212 if ((location = _locations.end_location()) == 0) {
1213 _locations.add (end_location);
1215 delete end_location;
1216 end_location = location;
1219 if ((location = _locations.start_location()) == 0) {
1220 _locations.add (start_location);
1222 delete start_location;
1223 start_location = location;
1226 AudioFileSource::set_header_position_offset (start_location->start());
1228 if ((child = find_named_node (node, "Sources")) == 0) {
1229 error << _("Session: XML state has no sources section") << endmsg;
1231 } else if (load_sources (*child)) {
1235 if ((child = find_named_node (node, "Regions")) == 0) {
1236 error << _("Session: XML state has no Regions section") << endmsg;
1238 } else if (load_regions (*child)) {
1242 if ((child = find_named_node (node, "Playlists")) == 0) {
1243 error << _("Session: XML state has no playlists section") << endmsg;
1245 } else if (load_playlists (*child)) {
1249 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1251 } else if (load_unused_playlists (*child)) {
1255 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1256 if (load_named_selections (*child)) {
1261 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1262 error << _("Session: XML state has no diskstreams section") << endmsg;
1264 } else if (load_diskstreams (*child)) {
1268 if ((child = find_named_node (node, "Connections")) == 0) {
1269 error << _("Session: XML state has no connections section") << endmsg;
1271 } else if (load_connections (*child)) {
1275 if ((child = find_named_node (node, "EditGroups")) == 0) {
1276 error << _("Session: XML state has no edit groups section") << endmsg;
1278 } else if (load_edit_groups (*child)) {
1282 if ((child = find_named_node (node, "MixGroups")) == 0) {
1283 error << _("Session: XML state has no mix groups section") << endmsg;
1285 } else if (load_mix_groups (*child)) {
1289 if ((child = find_named_node (node, "TempoMap")) == 0) {
1290 error << _("Session: XML state has no Tempo Map section") << endmsg;
1292 } else if (_tempo_map->set_state (*child)) {
1296 if ((child = find_named_node (node, "Routes")) == 0) {
1297 error << _("Session: XML state has no routes section") << endmsg;
1299 } else if (load_routes (*child)) {
1303 if ((child = find_named_node (node, "Click")) == 0) {
1304 warning << _("Session: XML state has no click section") << endmsg;
1305 } else if (_click_io) {
1306 _click_io->set_state (*child);
1309 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1310 ControlProtocolManager::instance().set_protocol_states (*child);
1313 /* here beginneth the second phase ... */
1315 StateReady (); /* EMIT SIGNAL */
1317 _state_of_the_state = Clean;
1319 if (state_was_pending) {
1320 save_state (_current_snapshot_name);
1321 remove_pending_capture_state ();
1322 state_was_pending = false;
1332 Session::load_routes (const XMLNode& node)
1335 XMLNodeConstIterator niter;
1336 RouteList new_routes;
1338 nlist = node.children();
1342 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1344 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1347 error << _("Session: cannot create Route from XML description.") << endmsg;
1351 new_routes.push_back (route);
1354 add_routes (new_routes);
1359 boost::shared_ptr<Route>
1360 Session::XMLRouteFactory (const XMLNode& node)
1362 if (node.name() != "Route") {
1363 return boost::shared_ptr<Route> ((Route*) 0);
1366 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1367 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1370 boost::shared_ptr<Route> x (new Route (*this, node));
1376 Session::load_regions (const XMLNode& node)
1379 XMLNodeConstIterator niter;
1380 boost::shared_ptr<AudioRegion> region;
1382 nlist = node.children();
1386 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1387 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1388 error << _("Session: cannot create Region from XML description.") << endmsg;
1395 boost::shared_ptr<AudioRegion>
1396 Session::XMLRegionFactory (const XMLNode& node, bool full)
1398 const XMLProperty* prop;
1399 boost::shared_ptr<Source> source;
1400 boost::shared_ptr<AudioSource> as;
1402 SourceList master_sources;
1403 uint32_t nchans = 1;
1406 if (node.name() != X_("Region")) {
1407 return boost::shared_ptr<AudioRegion>();
1410 if ((prop = node.property (X_("channels"))) != 0) {
1411 nchans = atoi (prop->value().c_str());
1415 if ((prop = node.property ("name")) == 0) {
1416 cerr << "no name for this region\n";
1420 if ((prop = node.property (X_("source-0"))) == 0) {
1421 if ((prop = node.property ("source")) == 0) {
1422 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1423 return boost::shared_ptr<AudioRegion>();
1427 PBD::ID s_id (prop->value());
1429 if ((source = source_by_id (s_id)) == 0) {
1430 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1431 return boost::shared_ptr<AudioRegion>();
1434 as = boost::dynamic_pointer_cast<AudioSource>(source);
1436 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1437 return boost::shared_ptr<AudioRegion>();
1440 sources.push_back (as);
1442 /* pickup other channels */
1444 for (uint32_t n=1; n < nchans; ++n) {
1445 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1446 if ((prop = node.property (buf)) != 0) {
1448 PBD::ID id2 (prop->value());
1450 if ((source = source_by_id (id2)) == 0) {
1451 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1452 return boost::shared_ptr<AudioRegion>();
1455 as = boost::dynamic_pointer_cast<AudioSource>(source);
1457 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1458 return boost::shared_ptr<AudioRegion>();
1460 sources.push_back (as);
1464 for (uint32_t n=0; n < nchans; ++n) {
1465 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1466 if ((prop = node.property (buf)) != 0) {
1468 PBD::ID id2 (prop->value());
1470 if ((source = source_by_id (id2)) == 0) {
1471 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1472 return boost::shared_ptr<AudioRegion>();
1475 as = boost::dynamic_pointer_cast<AudioSource>(source);
1477 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1478 return boost::shared_ptr<AudioRegion>();
1480 master_sources.push_back (as);
1485 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1487 /* a final detail: this is the one and only place that we know how long missing files are */
1489 if (region->whole_file()) {
1490 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1491 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1493 sfp->set_length (region->length());
1498 if (!master_sources.empty()) {
1499 if (master_sources.size() != nchans) {
1500 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1502 region->set_master_sources (master_sources);
1510 catch (failed_constructor& err) {
1511 return boost::shared_ptr<AudioRegion>();
1516 Session::get_sources_as_xml ()
1519 XMLNode* node = new XMLNode (X_("Sources"));
1520 Glib::Mutex::Lock lm (audio_source_lock);
1522 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1523 node->add_child_nocopy (i->second->get_state());
1526 /* XXX get MIDI and other sources here */
1532 Session::path_from_region_name (string name, string identifier)
1534 char buf[PATH_MAX+1];
1536 string dir = discover_best_sound_dir ();
1538 for (n = 0; n < 999999; ++n) {
1539 if (identifier.length()) {
1540 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1541 identifier.c_str(), n);
1543 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1546 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1551 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1560 Session::load_sources (const XMLNode& node)
1563 XMLNodeConstIterator niter;
1564 boost::shared_ptr<Source> source;
1566 nlist = node.children();
1570 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1573 if ((source = XMLSourceFactory (**niter)) == 0) {
1574 error << _("Session: cannot create Source from XML description.") << endmsg;
1578 catch (non_existent_source& err) {
1579 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1580 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1587 boost::shared_ptr<Source>
1588 Session::XMLSourceFactory (const XMLNode& node)
1590 if (node.name() != "Source") {
1591 return boost::shared_ptr<Source>();
1595 return SourceFactory::create (*this, node);
1598 catch (failed_constructor& err) {
1599 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1600 return boost::shared_ptr<Source>();
1605 Session::save_template (string template_name)
1608 string xml_path, bak_path, template_path;
1610 if (_state_of_the_state & CannotSave) {
1615 string dir = template_dir();
1617 if ((dp = opendir (dir.c_str()))) {
1620 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1621 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1626 tree.set_root (&get_template());
1629 xml_path += template_name;
1630 xml_path += _template_suffix;
1632 ifstream in(xml_path.c_str());
1635 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1641 if (!tree.write (xml_path)) {
1642 error << _("mix template not saved") << endmsg;
1650 Session::rename_template (string old_name, string new_name)
1652 string old_path = template_dir() + old_name + _template_suffix;
1653 string new_path = template_dir() + new_name + _template_suffix;
1655 return rename (old_path.c_str(), new_path.c_str());
1659 Session::delete_template (string name)
1661 string template_path = template_dir();
1662 template_path += name;
1663 template_path += _template_suffix;
1665 return remove (template_path.c_str());
1669 Session::refresh_disk_space ()
1672 struct statfs statfsbuf;
1673 vector<space_and_path>::iterator i;
1674 Glib::Mutex::Lock lm (space_lock);
1677 /* get freespace on every FS that is part of the session path */
1679 _total_free_4k_blocks = 0;
1681 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1682 statfs ((*i).path.c_str(), &statfsbuf);
1684 scale = statfsbuf.f_bsize/4096.0;
1686 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1687 _total_free_4k_blocks += (*i).blocks;
1693 Session::ensure_sound_dir (string path, string& result)
1698 /* Ensure that the parent directory exists */
1700 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1701 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1705 /* Ensure that the sounds directory exists */
1709 result += sound_dir_name;
1711 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1712 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1718 dead += dead_sound_dir_name;
1720 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1721 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1727 peak += peak_dir_name;
1729 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1730 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1734 /* callers expect this to be terminated ... */
1741 Session::discover_best_sound_dir (bool destructive)
1743 vector<space_and_path>::iterator i;
1746 /* handle common case without system calls */
1748 if (session_dirs.size() == 1) {
1752 /* OK, here's the algorithm we're following here:
1754 We want to select which directory to use for
1755 the next file source to be created. Ideally,
1756 we'd like to use a round-robin process so as to
1757 get maximum performance benefits from splitting
1758 the files across multiple disks.
1760 However, in situations without much diskspace, an
1761 RR approach may end up filling up a filesystem
1762 with new files while others still have space.
1763 Its therefore important to pay some attention to
1764 the freespace in the filesystem holding each
1765 directory as well. However, if we did that by
1766 itself, we'd keep creating new files in the file
1767 system with the most space until it was as full
1768 as all others, thus negating any performance
1769 benefits of this RAID-1 like approach.
1771 So, we use a user-configurable space threshold. If
1772 there are at least 2 filesystems with more than this
1773 much space available, we use RR selection between them.
1774 If not, then we pick the filesystem with the most space.
1776 This gets a good balance between the two
1780 refresh_disk_space ();
1782 int free_enough = 0;
1784 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1785 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1790 if (free_enough >= 2) {
1792 bool found_it = false;
1794 /* use RR selection process, ensuring that the one
1798 i = last_rr_session_dir;
1801 if (++i == session_dirs.end()) {
1802 i = session_dirs.begin();
1805 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1806 if (ensure_sound_dir ((*i).path, result) == 0) {
1807 last_rr_session_dir = i;
1813 } while (i != last_rr_session_dir);
1816 result = sound_dir();
1821 /* pick FS with the most freespace (and that
1822 seems to actually work ...)
1825 vector<space_and_path> sorted;
1826 space_and_path_ascending_cmp cmp;
1828 sorted = session_dirs;
1829 sort (sorted.begin(), sorted.end(), cmp);
1831 for (i = sorted.begin(); i != sorted.end(); ++i) {
1832 if (ensure_sound_dir ((*i).path, result) == 0) {
1833 last_rr_session_dir = i;
1838 /* if the above fails, fall back to the most simplistic solution */
1840 if (i == sorted.end()) {
1849 Session::load_playlists (const XMLNode& node)
1852 XMLNodeConstIterator niter;
1853 boost::shared_ptr<Playlist> playlist;
1855 nlist = node.children();
1859 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1861 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1862 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1870 Session::load_unused_playlists (const XMLNode& node)
1873 XMLNodeConstIterator niter;
1874 boost::shared_ptr<Playlist> playlist;
1876 nlist = node.children();
1880 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1882 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1883 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1887 // now manually untrack it
1889 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1896 boost::shared_ptr<Playlist>
1897 Session::XMLPlaylistFactory (const XMLNode& node)
1900 return PlaylistFactory::create (*this, node);
1903 catch (failed_constructor& err) {
1904 return boost::shared_ptr<Playlist>();
1909 Session::load_named_selections (const XMLNode& node)
1912 XMLNodeConstIterator niter;
1915 nlist = node.children();
1919 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1921 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1922 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1930 Session::XMLNamedSelectionFactory (const XMLNode& node)
1933 return new NamedSelection (*this, node);
1936 catch (failed_constructor& err) {
1942 Session::dead_sound_dir () const
1945 res += dead_sound_dir_name;
1951 Session::old_sound_dir (bool with_path) const
1959 res += old_sound_dir_name;
1965 Session::sound_dir (bool with_path) const
1976 res += interchange_dir_name;
1978 res += legalize_for_path (_name);
1980 res += sound_dir_name;
1988 /* if this already exists, don't check for the old session sound directory */
1990 if (Glib::file_test (full, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
1994 /* possibly support old session structure */
1997 string old_withpath;
1999 old_nopath += old_sound_dir_name;
2002 old_withpath = _path;
2003 old_withpath += old_sound_dir_name;
2005 if (Glib::file_test (old_withpath.c_str(), Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2007 return old_withpath;
2012 /* ok, old "sounds" directory isn't there, return the new path */
2018 Session::peak_dir () const
2021 res += peak_dir_name;
2027 Session::automation_dir () const
2030 res += "automation/";
2035 Session::template_dir ()
2037 string path = get_user_ardour_path();
2038 path += "templates/";
2044 Session::export_dir () const
2047 res += export_dir_name;
2053 Session::suffixed_search_path (string suffix, bool data)
2057 path += get_user_ardour_path();
2058 if (path[path.length()-1] != ':') {
2063 path += get_system_data_path();
2065 path += get_system_module_path();
2068 vector<string> split_path;
2070 split (path, split_path, ':');
2073 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2078 if (distance (i, split_path.end()) != 1) {
2087 Session::template_path ()
2089 return suffixed_search_path (X_("templates"), true);
2093 Session::control_protocol_path ()
2095 return suffixed_search_path (X_("surfaces"), false);
2099 Session::load_connections (const XMLNode& node)
2101 XMLNodeList nlist = node.children();
2102 XMLNodeConstIterator niter;
2106 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2107 if ((*niter)->name() == "InputConnection") {
2108 add_connection (new ARDOUR::InputConnection (**niter));
2109 } else if ((*niter)->name() == "OutputConnection") {
2110 add_connection (new ARDOUR::OutputConnection (**niter));
2112 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2121 Session::load_edit_groups (const XMLNode& node)
2123 return load_route_groups (node, true);
2127 Session::load_mix_groups (const XMLNode& node)
2129 return load_route_groups (node, false);
2133 Session::load_route_groups (const XMLNode& node, bool edit)
2135 XMLNodeList nlist = node.children();
2136 XMLNodeConstIterator niter;
2141 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2142 if ((*niter)->name() == "RouteGroup") {
2144 rg = add_edit_group ("");
2145 rg->set_state (**niter);
2147 rg = add_mix_group ("");
2148 rg->set_state (**niter);
2157 state_file_filter (const string &str, void *arg)
2159 return (str.length() > strlen(Session::statefile_suffix()) &&
2160 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2164 bool operator()(const string* a, const string* b) {
2170 remove_end(string* state)
2172 string statename(*state);
2174 string::size_type start,end;
2175 if ((start = statename.find_last_of ('/')) != string::npos) {
2176 statename = statename.substr (start+1);
2179 if ((end = statename.rfind(".ardour")) == string::npos) {
2180 end = statename.length();
2183 return new string(statename.substr (0, end));
2187 Session::possible_states (string path)
2189 PathScanner scanner;
2190 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2192 transform(states->begin(), states->end(), states->begin(), remove_end);
2195 sort (states->begin(), states->end(), cmp);
2201 Session::possible_states () const
2203 return possible_states(_path);
2207 Session::auto_save()
2209 save_state (_current_snapshot_name);
2213 Session::add_edit_group (string name)
2215 RouteGroup* rg = new RouteGroup (*this, name);
2216 edit_groups.push_back (rg);
2217 edit_group_added (rg); /* EMIT SIGNAL */
2223 Session::add_mix_group (string name)
2225 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2226 mix_groups.push_back (rg);
2227 mix_group_added (rg); /* EMIT SIGNAL */
2233 Session::remove_edit_group (RouteGroup& rg)
2235 list<RouteGroup*>::iterator i;
2237 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2238 (*i)->apply (&Route::drop_edit_group, this);
2239 edit_groups.erase (i);
2240 edit_group_removed (); /* EMIT SIGNAL */
2247 Session::remove_mix_group (RouteGroup& rg)
2249 list<RouteGroup*>::iterator i;
2251 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2252 (*i)->apply (&Route::drop_mix_group, this);
2253 mix_groups.erase (i);
2254 mix_group_removed (); /* EMIT SIGNAL */
2261 Session::mix_group_by_name (string name)
2263 list<RouteGroup *>::iterator i;
2265 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2266 if ((*i)->name() == name) {
2274 Session::edit_group_by_name (string name)
2276 list<RouteGroup *>::iterator i;
2278 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2279 if ((*i)->name() == name) {
2287 Session::begin_reversible_command (string name)
2289 current_trans = new UndoTransaction;
2290 current_trans->set_name (name);
2294 Session::commit_reversible_command (Command *cmd)
2299 current_trans->add_command (cmd);
2302 gettimeofday (&now, 0);
2303 current_trans->set_timestamp (now);
2305 _history.add (current_trans);
2308 Session::GlobalRouteBooleanState
2309 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2311 GlobalRouteBooleanState s;
2312 boost::shared_ptr<RouteList> r = routes.reader ();
2314 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2315 if (!(*i)->hidden()) {
2316 RouteBooleanState v;
2319 Route* r = (*i).get();
2320 v.second = (r->*method)();
2329 Session::GlobalRouteMeterState
2330 Session::get_global_route_metering ()
2332 GlobalRouteMeterState s;
2333 boost::shared_ptr<RouteList> r = routes.reader ();
2335 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2336 if (!(*i)->hidden()) {
2340 v.second = (*i)->meter_point();
2350 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2352 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2354 boost::shared_ptr<Route> r = (i->first.lock());
2357 r->set_meter_point (i->second, arg);
2363 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2365 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2367 boost::shared_ptr<Route> r = (i->first.lock());
2370 Route* rp = r.get();
2371 (rp->*method) (i->second, arg);
2377 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2379 set_global_route_boolean (s, &Route::set_mute, src);
2383 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2385 set_global_route_boolean (s, &Route::set_solo, src);
2389 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2391 set_global_route_boolean (s, &Route::set_record_enable, src);
2396 Session::global_mute_memento (void* src)
2398 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2402 Session::global_metering_memento (void* src)
2404 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2408 Session::global_solo_memento (void* src)
2410 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2414 Session::global_record_enable_memento (void* src)
2416 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2421 template_filter (const string &str, void *arg)
2423 return (str.length() > strlen(Session::template_suffix()) &&
2424 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2428 Session::get_template_list (list<string> &template_names)
2430 vector<string *> *templates;
2431 PathScanner scanner;
2434 path = template_path ();
2436 templates = scanner (path, template_filter, 0, false, true);
2438 vector<string*>::iterator i;
2439 for (i = templates->begin(); i != templates->end(); ++i) {
2440 string fullpath = *(*i);
2443 start = fullpath.find_last_of ('/') + 1;
2444 if ((end = fullpath.find_last_of ('.')) <0) {
2445 end = fullpath.length();
2448 template_names.push_back(fullpath.substr(start, (end-start)));
2453 Session::read_favorite_dirs (FavoriteDirs & favs)
2455 string path = get_user_ardour_path();
2456 path += "/favorite_dirs";
2458 ifstream fav (path.c_str());
2463 if (errno != ENOENT) {
2464 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2475 getline(fav, newfav);
2481 favs.push_back (newfav);
2488 Session::write_favorite_dirs (FavoriteDirs & favs)
2490 string path = get_user_ardour_path();
2491 path += "/favorite_dirs";
2493 ofstream fav (path.c_str());
2499 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2500 fav << (*i) << endl;
2507 accept_all_non_peak_files (const string& path, void *arg)
2509 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2513 accept_all_state_files (const string& path, void *arg)
2515 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2519 Session::find_all_sources (string path, set<string>& result)
2524 if (!tree.read (path)) {
2528 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2533 XMLNodeConstIterator niter;
2535 nlist = node->children();
2539 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2543 if ((prop = (*niter)->property (X_("name"))) == 0) {
2547 if (prop->value()[0] == '/') {
2548 /* external file, ignore */
2552 string path = _path; /* /-terminated */
2553 path += sound_dir_name;
2555 path += prop->value();
2557 result.insert (path);
2564 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2566 PathScanner scanner;
2567 vector<string*>* state_files;
2569 string this_snapshot_path;
2575 if (ripped[ripped.length()-1] == '/') {
2576 ripped = ripped.substr (0, ripped.length() - 1);
2579 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2581 if (state_files == 0) {
2586 this_snapshot_path = _path;
2587 this_snapshot_path += _current_snapshot_name;
2588 this_snapshot_path += _statefile_suffix;
2590 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2592 if (exclude_this_snapshot && **i == this_snapshot_path) {
2596 if (find_all_sources (**i, result) < 0) {
2604 struct RegionCounter {
2605 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2606 AudioSourceList::iterator iter;
2607 boost::shared_ptr<Region> region;
2610 RegionCounter() : count (0) {}
2614 Session::cleanup_sources (Session::cleanup_report& rep)
2616 vector<boost::shared_ptr<Source> > dead_sources;
2617 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2618 PathScanner scanner;
2620 vector<space_and_path>::iterator i;
2621 vector<space_and_path>::iterator nexti;
2622 vector<string*>* soundfiles;
2623 vector<string> unused;
2624 set<string> all_sources;
2629 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2631 /* step 1: consider deleting all unused playlists */
2633 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2636 status = AskAboutPlaylistDeletion (*x);
2645 playlists_tbd.push_back (*x);
2649 /* leave it alone */
2654 /* now delete any that were marked for deletion */
2656 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2657 (*x)->drop_references ();
2660 playlists_tbd.clear ();
2662 /* step 2: find all un-used sources */
2667 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2669 AudioSourceList::iterator tmp;
2674 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2678 if (!i->second->used() && i->second->length() > 0) {
2679 dead_sources.push_back (i->second);
2680 i->second->GoingAway();
2686 /* build a list of all the possible sound directories for the session */
2688 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2693 sound_path += (*i).path;
2694 sound_path += sound_dir (false);
2696 if (nexti != session_dirs.end()) {
2703 /* now do the same thing for the files that ended up in the sounds dir(s)
2704 but are not referenced as sources in any snapshot.
2707 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2709 if (soundfiles == 0) {
2713 /* find all sources, but don't use this snapshot because the
2714 state file on disk still references sources we may have already
2718 find_all_sources_across_snapshots (all_sources, true);
2720 /* add our current source list
2723 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2724 boost::shared_ptr<AudioFileSource> fs;
2726 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2727 all_sources.insert (fs->path());
2731 char tmppath1[PATH_MAX+1];
2732 char tmppath2[PATH_MAX+1];
2734 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2739 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2741 realpath(spath.c_str(), tmppath1);
2742 realpath((*i).c_str(), tmppath2);
2744 if (strcmp(tmppath1, tmppath2) == 0) {
2751 unused.push_back (spath);
2755 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2757 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2758 struct stat statbuf;
2760 rep.paths.push_back (*x);
2761 if (stat ((*x).c_str(), &statbuf) == 0) {
2762 rep.space += statbuf.st_size;
2767 /* don't move the file across filesystems, just
2768 stick it in the `dead_sound_dir_name' directory
2769 on whichever filesystem it was already on.
2772 if ((*x).find ("/sounds/") != string::npos) {
2774 /* old school, go up 1 level */
2776 newpath = Glib::path_get_dirname (*x); // "sounds"
2777 newpath = Glib::path_get_dirname (newpath); // "session-name"
2781 /* new school, go up 4 levels */
2783 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2784 newpath = Glib::path_get_dirname (newpath); // "session-name"
2785 newpath = Glib::path_get_dirname (newpath); // "interchange"
2786 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2790 newpath += dead_sound_dir_name;
2792 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2793 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2798 newpath += Glib::path_get_basename ((*x));
2800 if (access (newpath.c_str(), F_OK) == 0) {
2802 /* the new path already exists, try versioning */
2804 char buf[PATH_MAX+1];
2808 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2811 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2812 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2816 if (version == 999) {
2817 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2821 newpath = newpath_v;
2826 /* it doesn't exist, or we can't read it or something */
2830 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2831 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2832 (*x), newpath, strerror (errno))
2837 /* see if there an easy to find peakfile for this file, and remove it.
2840 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2841 peakpath += ".peak";
2843 if (access (peakpath.c_str(), W_OK) == 0) {
2844 if (::unlink (peakpath.c_str()) != 0) {
2845 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2846 peakpath, _path, strerror (errno))
2848 /* try to back out */
2849 rename (newpath.c_str(), _path.c_str());
2857 /* dump the history list */
2861 /* save state so we don't end up a session file
2862 referring to non-existent sources.
2868 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2873 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2875 vector<space_and_path>::iterator i;
2876 string dead_sound_dir;
2877 struct dirent* dentry;
2878 struct stat statbuf;
2884 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2886 dead_sound_dir = (*i).path;
2887 dead_sound_dir += dead_sound_dir_name;
2889 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2893 while ((dentry = readdir (dead)) != 0) {
2895 /* avoid '.' and '..' */
2897 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2898 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2904 fullpath = dead_sound_dir;
2906 fullpath += dentry->d_name;
2908 if (stat (fullpath.c_str(), &statbuf)) {
2912 if (!S_ISREG (statbuf.st_mode)) {
2916 if (unlink (fullpath.c_str())) {
2917 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2918 fullpath, strerror (errno))
2922 rep.paths.push_back (dentry->d_name);
2923 rep.space += statbuf.st_size;
2934 Session::set_dirty ()
2936 bool was_dirty = dirty();
2938 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2941 DirtyChanged(); /* EMIT SIGNAL */
2947 Session::set_clean ()
2949 bool was_dirty = dirty();
2951 _state_of_the_state = Clean;
2954 DirtyChanged(); /* EMIT SIGNAL */
2959 Session::set_deletion_in_progress ()
2961 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2965 Session::add_controllable (Controllable* c)
2967 /* this adds a controllable to the list managed by the Session.
2968 this is a subset of those managed by the Controllable class
2969 itself, and represents the only ones whose state will be saved
2970 as part of the session.
2973 Glib::Mutex::Lock lm (controllables_lock);
2974 controllables.insert (c);
2978 Session::remove_controllable (Controllable* c)
2980 if (_state_of_the_state | Deletion) {
2984 Glib::Mutex::Lock lm (controllables_lock);
2986 Controllables::iterator x = controllables.find (c);
2988 if (x != controllables.end()) {
2989 controllables.erase (x);
2994 Session::controllable_by_id (const PBD::ID& id)
2996 Glib::Mutex::Lock lm (controllables_lock);
2998 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2999 if ((*i)->id() == id) {
3008 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3010 Stateful::add_instant_xml (node, dir);
3011 Config->add_instant_xml (node, get_user_ardour_path());
3015 Session::save_history (string snapshot_name)
3021 if (snapshot_name.empty()) {
3022 snapshot_name = _current_snapshot_name;
3025 xml_path = _path + snapshot_name + ".history";
3027 bak_path = xml_path + ".bak";
3029 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && ::rename (xml_path.c_str(), bak_path.c_str())) {
3030 error << _("could not backup old history file, current history not saved.") << endmsg;
3034 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3038 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3040 if (!tree.write (xml_path))
3042 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3044 /* don't leave a corrupt file lying around if it is
3048 if (unlink (xml_path.c_str())) {
3049 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
3051 if (rename (bak_path.c_str(), xml_path.c_str()))
3053 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
3064 Session::restore_history (string snapshot_name)
3069 if (snapshot_name.empty()) {
3070 snapshot_name = _current_snapshot_name;
3074 xmlpath = _path + snapshot_name + ".history";
3075 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
3077 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3081 if (!tree.read (xmlpath)) {
3082 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
3086 /* replace history */
3089 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3092 UndoTransaction* ut = new UndoTransaction ();
3095 ut->set_name(t->property("name")->value());
3096 stringstream ss(t->property("tv_sec")->value());
3098 ss.str(t->property("tv_usec")->value());
3100 ut->set_timestamp(tv);
3102 for (XMLNodeConstIterator child_it = t->children().begin();
3103 child_it != t->children().end();
3106 XMLNode *n = *child_it;
3109 if (n->name() == "MementoCommand" ||
3110 n->name() == "MementoUndoCommand" ||
3111 n->name() == "MementoRedoCommand") {
3113 if ((c = memento_command_factory(n))) {
3117 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3119 if ((c = global_state_command_factory (*n))) {
3120 ut->add_command (c);
3125 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3136 Session::config_changed (const char* parameter_name)
3138 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3140 if (PARAM_IS ("seamless-loop")) {
3142 } else if (PARAM_IS ("rf-speed")) {
3144 } else if (PARAM_IS ("auto-loop")) {
3146 } else if (PARAM_IS ("auto-input")) {
3148 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3149 /* auto-input only makes a difference if we're rolling */
3151 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3153 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3154 if ((*i)->record_enabled ()) {
3155 (*i)->monitor_input (!Config->get_auto_input());
3160 } else if (PARAM_IS ("punch-in")) {
3164 if ((location = _locations.auto_punch_location()) != 0) {
3166 if (Config->get_punch_in ()) {
3167 replace_event (Event::PunchIn, location->start());
3169 remove_event (location->start(), Event::PunchIn);
3173 } else if (PARAM_IS ("punch-out")) {
3177 if ((location = _locations.auto_punch_location()) != 0) {
3179 if (Config->get_punch_out()) {
3180 replace_event (Event::PunchOut, location->end());
3182 clear_events (Event::PunchOut);
3186 } else if (PARAM_IS ("edit-mode")) {
3188 Glib::Mutex::Lock lm (playlist_lock);
3190 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3191 (*i)->set_edit_mode (Config->get_edit_mode ());
3194 } else if (PARAM_IS ("use-video-sync")) {
3196 waiting_for_sync_offset = Config->get_use_video_sync();
3198 } else if (PARAM_IS ("mmc-control")) {
3200 poke_midi_thread ();
3202 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-device-id")) {
3204 set_mmc_receive_device_id (Config->get_mmc_receive_device_id());
3206 } else if (PARAM_IS ("mmc-send-device-id")) {
3208 set_mmc_send_device_id (Config->get_mmc_send_device_id());
3210 } else if (PARAM_IS ("midi-control")) {
3212 poke_midi_thread ();
3214 } else if (PARAM_IS ("raid-path")) {
3216 setup_raid_path (Config->get_raid_path());
3218 } else if (PARAM_IS ("smpte-format")) {
3222 } else if (PARAM_IS ("video-pullup")) {
3226 } else if (PARAM_IS ("seamless-loop")) {
3228 if (play_loop && transport_rolling()) {
3229 // to reset diskstreams etc
3230 request_play_loop (true);
3233 } else if (PARAM_IS ("rf-speed")) {
3235 cumulative_rf_motion = 0;
3238 } else if (PARAM_IS ("click-sound")) {
3240 setup_click_sounds (1);
3242 } else if (PARAM_IS ("click-emphasis-sound")) {
3244 setup_click_sounds (-1);
3246 } else if (PARAM_IS ("clicking")) {
3248 if (Config->get_clicking()) {
3249 if (_click_io && click_data) { // don't require emphasis data
3256 } else if (PARAM_IS ("send-mtc")) {
3258 /* only set the internal flag if we have
3262 if (_mtc_port != 0) {
3263 session_send_mtc = Config->get_send_mtc();
3264 if (session_send_mtc) {
3265 /* mark us ready to send */
3266 next_quarter_frame_to_send = 0;
3269 session_send_mtc = false;
3272 } else if (PARAM_IS ("send-mmc")) {
3274 /* only set the internal flag if we have
3278 if (_mmc_port != 0) {
3279 session_send_mmc = Config->get_send_mmc();
3282 session_send_mmc = false;
3285 } else if (PARAM_IS ("midi-feedback")) {
3287 /* only set the internal flag if we have
3291 if (_mtc_port != 0) {
3292 session_midi_feedback = Config->get_midi_feedback();
3295 } else if (PARAM_IS ("jack-time-master")) {
3297 engine().reset_timebase ();
3299 } else if (PARAM_IS ("native-file-header-format")) {
3301 if (!first_file_header_format_reset) {
3302 reset_native_file_format ();
3305 first_file_header_format_reset = false;
3307 } else if (PARAM_IS ("native-file-data-format")) {
3309 if (!first_file_data_format_reset) {
3310 reset_native_file_format ();
3313 first_file_data_format_reset = false;
3315 } else if (PARAM_IS ("slave-source")) {
3316 set_slave_source (Config->get_slave_source());
3317 } else if (PARAM_IS ("remote-model")) {
3318 set_remote_control_ids ();
3319 } else if (PARAM_IS ("denormal-model")) {
3321 } else if (PARAM_IS ("history-depth")) {
3322 set_history_depth (Config->get_history_depth());
3323 } else if (PARAM_IS ("sync-all-route-ordering")) {
3334 Session::set_history_depth (uint32_t d)
3336 _history.set_depth (d);