2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <sigc++/bind.h>
27 #include <cstdio> /* snprintf(3) ... grrr */
42 #include <sys/param.h>
43 #include <sys/mount.h>
47 #include <glibmm/thread.h>
49 #include <midi++/mmc.h>
50 #include <midi++/port.h>
52 #include <pbd/error.h>
53 #include <pbd/pathscanner.h>
54 #include <pbd/pthread_utils.h>
55 #include <pbd/strsplit.h>
56 #include <pbd/stacktrace.h>
57 #include <pbd/copyfile.h>
59 #include <ardour/audioengine.h>
60 #include <ardour/configuration.h>
61 #include <ardour/session.h>
62 #include <ardour/audio_diskstream.h>
63 #include <ardour/utils.h>
64 #include <ardour/audioplaylist.h>
65 #include <ardour/audiofilesource.h>
66 #include <ardour/silentfilesource.h>
67 #include <ardour/sndfilesource.h>
68 #include <ardour/sndfile_helpers.h>
69 #include <ardour/auditioner.h>
70 #include <ardour/export.h>
71 #include <ardour/redirect.h>
72 #include <ardour/send.h>
73 #include <ardour/insert.h>
74 #include <ardour/connection.h>
75 #include <ardour/slave.h>
76 #include <ardour/tempo.h>
77 #include <ardour/audio_track.h>
78 #include <ardour/cycle_timer.h>
79 #include <ardour/utils.h>
80 #include <ardour/named_selection.h>
81 #include <ardour/version.h>
82 #include <ardour/location.h>
83 #include <ardour/audioregion.h>
84 #include <ardour/crossfade.h>
85 #include <ardour/control_protocol_manager.h>
86 #include <ardour/region_factory.h>
87 #include <ardour/source_factory.h>
88 #include <ardour/playlist_factory.h>
90 #include <control_protocol/control_protocol.h>
96 using namespace ARDOUR;
100 Session::first_stage_init (string fullpath, string snapshot_name)
102 if (fullpath.length() == 0) {
104 throw failed_constructor();
107 char buf[PATH_MAX+1];
108 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
109 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
111 throw failed_constructor();
116 if (_path[_path.length()-1] != '/') {
120 set_history_depth (Config->get_history_depth());
123 /* these two are just provisional settings. set_state()
124 will likely override them.
127 _name = _current_snapshot_name = snapshot_name;
129 _current_frame_rate = _engine.frame_rate ();
130 _tempo_map = new TempoMap (_current_frame_rate);
131 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
133 g_atomic_int_set (&processing_prohibited, 0);
135 _transport_speed = 0;
136 _last_transport_speed = 0;
137 auto_play_legal = false;
138 transport_sub_state = 0;
139 _transport_frame = 0;
141 _requested_return_frame = -1;
142 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
143 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
144 _end_location_is_free = true;
145 g_atomic_int_set (&_record_status, Disabled);
146 loop_changing = false;
148 _last_roll_location = 0;
149 _last_record_location = 0;
150 pending_locate_frame = 0;
151 pending_locate_roll = false;
152 pending_locate_flush = false;
153 dstream_buffer_size = 0;
155 state_was_pending = false;
157 outbound_mtc_smpte_frame = 0;
158 next_quarter_frame_to_send = -1;
159 current_block_size = 0;
160 solo_update_disabled = false;
161 currently_soloing = false;
162 _have_captured = false;
163 _worst_output_latency = 0;
164 _worst_input_latency = 0;
165 _worst_track_latency = 0;
166 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
170 butler_mixdown_buffer = 0;
171 butler_gain_buffer = 0;
173 session_send_mmc = false;
174 session_send_mtc = false;
175 post_transport_work = PostTransportWork (0);
176 g_atomic_int_set (&butler_should_do_transport_work, 0);
177 g_atomic_int_set (&butler_active, 0);
178 g_atomic_int_set (&_playback_load, 100);
179 g_atomic_int_set (&_capture_load, 100);
180 g_atomic_int_set (&_playback_load_min, 100);
181 g_atomic_int_set (&_capture_load_min, 100);
183 waiting_to_start = false;
185 _gain_automation_buffer = 0;
186 _pan_automation_buffer = 0;
188 pending_abort = false;
189 destructive_index = 0;
191 first_file_data_format_reset = true;
192 first_file_header_format_reset = true;
193 butler_thread = (pthread_t) 0;
194 midi_thread = (pthread_t) 0;
196 AudioDiskstream::allocate_working_buffers();
198 /* default short fade = 15ms */
200 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
201 SndFileSource::setup_standard_crossfades (frame_rate());
203 last_mmc_step.tv_sec = 0;
204 last_mmc_step.tv_usec = 0;
207 /* click sounds are unset by default, which causes us to internal
208 waveforms for clicks.
212 click_emphasis_data = 0;
214 click_emphasis_length = 0;
217 process_function = &Session::process_with_events;
219 if (Config->get_use_video_sync()) {
220 waiting_for_sync_offset = true;
222 waiting_for_sync_offset = false;
225 _current_frame_rate = 48000;
226 _base_frame_rate = 48000;
230 _smpte_offset_negative = true;
231 last_smpte_valid = false;
235 last_rr_session_dir = session_dirs.begin();
236 refresh_disk_space ();
238 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
242 average_slave_delta = 1800;
243 have_first_delta_accumulator = false;
244 delta_accumulator_cnt = 0;
245 slave_state = Stopped;
247 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
249 /* These are all static "per-class" signals */
251 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
252 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
253 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
254 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
255 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
256 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
258 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
260 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
262 /* stop IO objects from doing stuff until we're ready for them */
264 IO::disable_panners ();
265 IO::disable_ports ();
266 IO::disable_connecting ();
270 Session::second_stage_init (bool new_session)
272 AudioFileSource::set_peak_dir (peak_dir());
275 if (load_state (_current_snapshot_name)) {
278 remove_empty_sounds ();
281 if (start_butler_thread()) {
285 if (start_midi_thread ()) {
289 // set_state() will call setup_raid_path(), but if it's a new session we need
290 // to call setup_raid_path() here.
293 if (set_state (*state_tree->root())) {
297 setup_raid_path(_path);
300 /* we can't save till after ::when_engine_running() is called,
301 because otherwise we save state with no connections made.
302 therefore, we reset _state_of_the_state because ::set_state()
303 will have cleared it.
305 we also have to include Loading so that any events that get
306 generated between here and the end of ::when_engine_running()
307 will be processed directly rather than queued.
310 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
313 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
314 _locations.added.connect (mem_fun (this, &Session::locations_added));
315 setup_click_sounds (0);
316 setup_midi_control ();
318 /* Pay attention ... */
320 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
321 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
324 when_engine_running();
327 /* handle this one in a different way than all others, so that its clear what happened */
329 catch (AudioEngine::PortRegistrationFailure& err) {
338 send_full_time_code ();
339 _engine.transport_locate (0);
340 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
341 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
343 ControlProtocolManager::instance().set_session (*this);
346 _end_location_is_free = true;
348 _end_location_is_free = false;
351 _state_of_the_state = Clean;
354 DirtyChanged (); /* EMIT SIGNAL */
356 if (state_was_pending) {
357 save_state (_current_snapshot_name);
358 remove_pending_capture_state ();
359 state_was_pending = false;
366 Session::raid_path () const
370 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
375 return path.substr (0, path.length() - 1); // drop final colon
379 Session::setup_raid_path (string path)
381 string::size_type colon;
385 string::size_type len = path.length();
390 if (path.length() == 0) {
394 session_dirs.clear ();
396 for (string::size_type n = 0; n < len; ++n) {
397 if (path[n] == ':') {
404 /* no multiple search path, just one location (common case) */
408 session_dirs.push_back (sp);
415 if (fspath[fspath.length()-1] != '/') {
419 fspath += sound_dir (false);
421 AudioFileSource::set_search_path (fspath);
428 while ((colon = remaining.find_first_of (':')) != string::npos) {
431 sp.path = remaining.substr (0, colon);
432 session_dirs.push_back (sp);
434 /* add sounds to file search path */
437 if (fspath[fspath.length()-1] != '/') {
440 fspath += sound_dir (false);
443 remaining = remaining.substr (colon+1);
446 if (remaining.length()) {
453 if (fspath[fspath.length()-1] != '/') {
456 fspath += sound_dir (false);
459 session_dirs.push_back (sp);
462 /* set the AudioFileSource search path */
464 AudioFileSource::set_search_path (fspath);
466 /* reset the round-robin soundfile path thingie */
468 last_rr_session_dir = session_dirs.begin();
472 Session::ensure_subdirs ()
478 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
479 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
483 /* if this is is an existing session with an old "sounds" directory, just use it. see Session::sound_dir() for more details */
485 if (!Glib::file_test (old_sound_dir(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
489 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
490 error << string_compose(_("Session: cannot create session sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
495 dir = dead_sound_dir ();
497 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
498 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
504 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
505 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
509 dir = analysis_dir ();
511 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
512 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
520 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
523 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
524 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
528 if (ensure_subdirs ()) {
532 /* check new_session so we don't overwrite an existing one */
534 if (!mix_template.empty()) {
535 std::string in_path = mix_template;
537 ifstream in(in_path.c_str());
540 string out_path = _path;
542 out_path += _statefile_suffix;
544 ofstream out(out_path.c_str());
549 // okay, session is set up. Treat like normal saved
550 // session from now on.
556 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
562 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
569 /* set initial start + end point */
571 start_location->set_end (0);
572 _locations.add (start_location);
574 end_location->set_end (initial_length);
575 _locations.add (end_location);
577 _state_of_the_state = Clean;
585 Session::load_diskstreams (const XMLNode& node)
588 XMLNodeConstIterator citer;
590 clist = node.children();
592 for (citer = clist.begin(); citer != clist.end(); ++citer) {
596 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
597 add_diskstream (dstream);
600 catch (failed_constructor& err) {
601 error << _("Session: could not load diskstream via XML state") << endmsg;
610 Session::maybe_write_autosave()
612 if (dirty() && record_status() != Recording) {
613 save_state("", true);
618 Session::remove_pending_capture_state ()
623 xml_path += _current_snapshot_name;
624 xml_path += _pending_suffix;
626 unlink (xml_path.c_str());
629 /** Rename a state file.
630 * @param snapshot_name Snapshot name.
633 Session::rename_state (string old_name, string new_name)
635 if (old_name == _current_snapshot_name || old_name == _name) {
636 /* refuse to rename the current snapshot or the "main" one */
640 const string old_xml_path = _path + old_name + _statefile_suffix;
641 const string new_xml_path = _path + new_name + _statefile_suffix;
643 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
644 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
648 /** Remove a state file.
649 * @param snapshot_name Snapshot name.
652 Session::remove_state (string snapshot_name)
654 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
655 /* refuse to remove the current snapshot or the "main" one */
659 const string xml_path = _path + snapshot_name + _statefile_suffix;
661 /* make a backup copy of the state file */
662 const string bak_path = xml_path + ".bak";
663 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
664 copy_file (xml_path, bak_path);
668 unlink (xml_path.c_str());
672 Session::save_state (string snapshot_name, bool pending)
678 if (_state_of_the_state & CannotSave) {
682 if (!_engine.connected ()) {
683 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
688 tree.set_root (&get_state());
690 if (snapshot_name.empty()) {
691 snapshot_name = _current_snapshot_name;
696 /* proper save: use _statefile_suffix (.ardour in English) */
698 xml_path += snapshot_name;
699 xml_path += _statefile_suffix;
701 /* make a backup copy of the old file */
705 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
706 copy_file (xml_path, bak_path);
711 /* pending save: use _pending_suffix (.pending in English) */
713 xml_path += snapshot_name;
714 xml_path += _pending_suffix;
721 tmp_path += snapshot_name;
724 // cerr << "actually writing state to " << xml_path << endl;
726 if (!tree.write (tmp_path)) {
727 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
728 unlink (tmp_path.c_str());
733 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
734 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
735 unlink (tmp_path.c_str());
742 save_history (snapshot_name);
744 bool was_dirty = dirty();
746 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
750 DirtyChanged (); /* EMIT SIGNAL */
753 StateSaved (snapshot_name); /* EMIT SIGNAL */
760 Session::restore_state (string snapshot_name)
762 if (load_state (snapshot_name) == 0) {
763 set_state (*state_tree->root());
770 Session::load_state (string snapshot_name)
779 state_was_pending = false;
781 /* check for leftover pending state from a crashed capture attempt */
784 xmlpath += snapshot_name;
785 xmlpath += _pending_suffix;
787 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
789 /* there is pending state from a crashed capture attempt */
791 if (AskAboutPendingState()) {
792 state_was_pending = true;
796 if (!state_was_pending) {
799 xmlpath += snapshot_name;
800 xmlpath += _statefile_suffix;
803 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
804 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
808 state_tree = new XMLTree;
812 if (!state_tree->read (xmlpath)) {
813 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
819 XMLNode& root (*state_tree->root());
821 if (root.name() != X_("Session")) {
822 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
828 const XMLProperty* prop;
831 if ((prop = root.property ("version")) == 0) {
832 /* no version implies very old version of Ardour */
836 major_version = atoi (prop->value()); // grab just the first number before the period
837 if (major_version < 2) {
846 backup_path += snapshot_name;
848 backup_path += _statefile_suffix;
850 /* don't make another copy if it already exists */
852 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
853 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
854 xmlpath, backup_path)
857 copy_file (xmlpath, backup_path);
859 /* if it fails, don't worry. right? */
867 Session::load_options (const XMLNode& node)
871 LocaleGuard lg (X_("POSIX"));
873 Config->set_variables (node, ConfigVariableBase::Session);
875 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
876 if ((prop = child->property ("val")) != 0) {
877 _end_location_is_free = (prop->value() == "yes");
885 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
887 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
888 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
890 return owner & modified_by_session_or_user;
894 Session::get_options () const
897 LocaleGuard lg (X_("POSIX"));
899 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
901 child = option_root.add_child ("end-marker-is-free");
902 child->add_property ("val", _end_location_is_free ? "yes" : "no");
914 Session::get_template()
916 /* if we don't disable rec-enable, diskstreams
917 will believe they need to store their capture
918 sources in their state node.
921 disable_record (false);
927 Session::state(bool full_state)
929 XMLNode* node = new XMLNode("Session");
932 // store libardour version, just in case
934 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
935 libardour2_major_version, libardour2_minor_version, libardour2_micro_version);
936 node->add_property("version", string(buf));
938 /* store configuration settings */
943 node->add_property ("name", _name);
945 if (session_dirs.size() > 1) {
949 vector<space_and_path>::iterator i = session_dirs.begin();
950 vector<space_and_path>::iterator next;
952 ++i; /* skip the first one */
956 while (i != session_dirs.end()) {
960 if (next != session_dirs.end()) {
970 child = node->add_child ("Path");
971 child->add_content (p);
975 /* save the ID counter */
977 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
978 node->add_property ("id-counter", buf);
980 /* various options */
982 node->add_child_nocopy (get_options());
984 child = node->add_child ("Sources");
987 Glib::Mutex::Lock sl (audio_source_lock);
989 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
991 /* Don't save information about AudioFileSources that are empty */
993 boost::shared_ptr<AudioFileSource> fs;
995 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
997 /* destructive file sources are OK if they are empty, because
998 we will re-use them every time.
1001 if (!fs->destructive()) {
1002 if (fs->length() == 0) {
1008 child->add_child_nocopy (siter->second->get_state());
1012 child = node->add_child ("Regions");
1015 Glib::Mutex::Lock rl (region_lock);
1017 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1019 /* only store regions not attached to playlists */
1021 if (i->second->playlist() == 0) {
1022 child->add_child_nocopy (i->second->state (true));
1027 child = node->add_child ("DiskStreams");
1030 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1031 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1032 if (!(*i)->hidden()) {
1033 child->add_child_nocopy ((*i)->get_state());
1039 node->add_child_nocopy (_locations.get_state());
1041 // for a template, just create a new Locations, populate it
1042 // with the default start and end, and get the state for that.
1044 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1045 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1048 end->set_end(compute_initial_length());
1050 node->add_child_nocopy (loc.get_state());
1053 child = node->add_child ("Connections");
1055 Glib::Mutex::Lock lm (connection_lock);
1056 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1057 if (!(*i)->system_dependent()) {
1058 child->add_child_nocopy ((*i)->get_state());
1063 child = node->add_child ("Routes");
1065 boost::shared_ptr<RouteList> r = routes.reader ();
1067 RoutePublicOrderSorter cmp;
1068 RouteList public_order (*r);
1069 public_order.sort (cmp);
1071 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1072 if (!(*i)->hidden()) {
1074 child->add_child_nocopy ((*i)->get_state());
1076 child->add_child_nocopy ((*i)->get_template());
1083 child = node->add_child ("EditGroups");
1084 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1085 child->add_child_nocopy ((*i)->get_state());
1088 child = node->add_child ("MixGroups");
1089 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1090 child->add_child_nocopy ((*i)->get_state());
1093 child = node->add_child ("Playlists");
1094 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1095 if (!(*i)->hidden()) {
1096 if (!(*i)->empty()) {
1098 child->add_child_nocopy ((*i)->get_state());
1100 child->add_child_nocopy ((*i)->get_template());
1106 child = node->add_child ("UnusedPlaylists");
1107 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1108 if (!(*i)->hidden()) {
1109 if (!(*i)->empty()) {
1111 child->add_child_nocopy ((*i)->get_state());
1113 child->add_child_nocopy ((*i)->get_template());
1121 child = node->add_child ("Click");
1122 child->add_child_nocopy (_click_io->state (full_state));
1126 child = node->add_child ("NamedSelections");
1127 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1129 child->add_child_nocopy ((*i)->get_state());
1134 node->add_child_nocopy (_tempo_map->get_state());
1136 node->add_child_nocopy (get_control_protocol_state());
1139 node->add_child_copy (*_extra_xml);
1146 Session::get_control_protocol_state ()
1148 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1149 return cpm.get_state();
1153 Session::set_state (const XMLNode& node)
1157 const XMLProperty* prop;
1160 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1163 if (node.name() != X_("Session")){
1164 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1168 if ((prop = node.property ("name")) != 0) {
1169 _name = prop->value ();
1172 setup_raid_path(_path);
1174 if ((prop = node.property (X_("id-counter"))) != 0) {
1176 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1177 ID::init_counter (x);
1179 /* old sessions used a timebased counter, so fake
1180 the startup ID counter based on a standard
1185 ID::init_counter (now);
1189 IO::disable_ports ();
1190 IO::disable_connecting ();
1192 /* Object loading order:
1210 if (use_config_midi_ports ()) {
1213 if ((child = find_named_node (node, "extra")) != 0) {
1214 _extra_xml = new XMLNode (*child);
1217 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1218 load_options (*child);
1219 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1220 load_options (*child);
1222 error << _("Session: XML state has no options section") << endmsg;
1225 if ((child = find_named_node (node, "Locations")) == 0) {
1226 error << _("Session: XML state has no locations section") << endmsg;
1228 } else if (_locations.set_state (*child)) {
1234 if ((location = _locations.auto_loop_location()) != 0) {
1235 set_auto_loop_location (location);
1238 if ((location = _locations.auto_punch_location()) != 0) {
1239 set_auto_punch_location (location);
1242 if ((location = _locations.end_location()) == 0) {
1243 _locations.add (end_location);
1245 delete end_location;
1246 end_location = location;
1249 if ((location = _locations.start_location()) == 0) {
1250 _locations.add (start_location);
1252 delete start_location;
1253 start_location = location;
1256 AudioFileSource::set_header_position_offset (start_location->start());
1258 if ((child = find_named_node (node, "Sources")) == 0) {
1259 error << _("Session: XML state has no sources section") << endmsg;
1261 } else if (load_sources (*child)) {
1265 if ((child = find_named_node (node, "Regions")) == 0) {
1266 error << _("Session: XML state has no Regions section") << endmsg;
1268 } else if (load_regions (*child)) {
1272 if ((child = find_named_node (node, "Playlists")) == 0) {
1273 error << _("Session: XML state has no playlists section") << endmsg;
1275 } else if (load_playlists (*child)) {
1279 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1281 } else if (load_unused_playlists (*child)) {
1285 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1286 if (load_named_selections (*child)) {
1291 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1292 error << _("Session: XML state has no diskstreams section") << endmsg;
1294 } else if (load_diskstreams (*child)) {
1298 if ((child = find_named_node (node, "Connections")) == 0) {
1299 error << _("Session: XML state has no connections section") << endmsg;
1301 } else if (load_connections (*child)) {
1305 if ((child = find_named_node (node, "EditGroups")) == 0) {
1306 error << _("Session: XML state has no edit groups section") << endmsg;
1308 } else if (load_edit_groups (*child)) {
1312 if ((child = find_named_node (node, "MixGroups")) == 0) {
1313 error << _("Session: XML state has no mix groups section") << endmsg;
1315 } else if (load_mix_groups (*child)) {
1319 if ((child = find_named_node (node, "TempoMap")) == 0) {
1320 error << _("Session: XML state has no Tempo Map section") << endmsg;
1322 } else if (_tempo_map->set_state (*child)) {
1326 if ((child = find_named_node (node, "Routes")) == 0) {
1327 error << _("Session: XML state has no routes section") << endmsg;
1329 } else if (load_routes (*child)) {
1333 if ((child = find_named_node (node, "Click")) == 0) {
1334 warning << _("Session: XML state has no click section") << endmsg;
1335 } else if (_click_io) {
1336 _click_io->set_state (*child);
1339 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1340 ControlProtocolManager::instance().set_protocol_states (*child);
1343 /* here beginneth the second phase ... */
1345 StateReady (); /* EMIT SIGNAL */
1354 Session::load_routes (const XMLNode& node)
1357 XMLNodeConstIterator niter;
1358 RouteList new_routes;
1360 nlist = node.children();
1364 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1366 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1369 error << _("Session: cannot create Route from XML description.") << endmsg;
1373 new_routes.push_back (route);
1376 add_routes (new_routes, false);
1381 boost::shared_ptr<Route>
1382 Session::XMLRouteFactory (const XMLNode& node)
1384 if (node.name() != "Route") {
1385 return boost::shared_ptr<Route> ((Route*) 0);
1388 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1389 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1392 boost::shared_ptr<Route> x (new Route (*this, node));
1398 Session::load_regions (const XMLNode& node)
1401 XMLNodeConstIterator niter;
1402 boost::shared_ptr<AudioRegion> region;
1404 nlist = node.children();
1408 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1409 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1410 error << _("Session: cannot create Region from XML description.");
1411 const XMLProperty *name = (**niter).property("name");
1414 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1424 boost::shared_ptr<AudioRegion>
1425 Session::XMLRegionFactory (const XMLNode& node, bool full)
1427 const XMLProperty* prop;
1428 boost::shared_ptr<Source> source;
1429 boost::shared_ptr<AudioSource> as;
1431 SourceList master_sources;
1432 uint32_t nchans = 1;
1435 if (node.name() != X_("Region")) {
1436 return boost::shared_ptr<AudioRegion>();
1439 if ((prop = node.property (X_("channels"))) != 0) {
1440 nchans = atoi (prop->value().c_str());
1444 if ((prop = node.property ("name")) == 0) {
1445 cerr << "no name for this region\n";
1449 if ((prop = node.property (X_("source-0"))) == 0) {
1450 if ((prop = node.property ("source")) == 0) {
1451 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1452 return boost::shared_ptr<AudioRegion>();
1456 PBD::ID s_id (prop->value());
1458 if ((source = source_by_id (s_id)) == 0) {
1459 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1460 return boost::shared_ptr<AudioRegion>();
1463 as = boost::dynamic_pointer_cast<AudioSource>(source);
1465 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1466 return boost::shared_ptr<AudioRegion>();
1469 sources.push_back (as);
1471 /* pickup other channels */
1473 for (uint32_t n=1; n < nchans; ++n) {
1474 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1475 if ((prop = node.property (buf)) != 0) {
1477 PBD::ID id2 (prop->value());
1479 if ((source = source_by_id (id2)) == 0) {
1480 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1481 return boost::shared_ptr<AudioRegion>();
1484 as = boost::dynamic_pointer_cast<AudioSource>(source);
1486 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1487 return boost::shared_ptr<AudioRegion>();
1489 sources.push_back (as);
1493 for (uint32_t n=0; n < nchans; ++n) {
1494 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1495 if ((prop = node.property (buf)) != 0) {
1497 PBD::ID id2 (prop->value());
1499 if ((source = source_by_id (id2)) == 0) {
1500 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1501 return boost::shared_ptr<AudioRegion>();
1504 as = boost::dynamic_pointer_cast<AudioSource>(source);
1506 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1507 return boost::shared_ptr<AudioRegion>();
1509 master_sources.push_back (as);
1514 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1516 /* a final detail: this is the one and only place that we know how long missing files are */
1518 if (region->whole_file()) {
1519 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1520 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1522 sfp->set_length (region->length());
1527 if (!master_sources.empty()) {
1528 if (master_sources.size() != nchans) {
1529 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1531 region->set_master_sources (master_sources);
1539 catch (failed_constructor& err) {
1540 return boost::shared_ptr<AudioRegion>();
1545 Session::get_sources_as_xml ()
1548 XMLNode* node = new XMLNode (X_("Sources"));
1549 Glib::Mutex::Lock lm (audio_source_lock);
1551 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1552 node->add_child_nocopy (i->second->get_state());
1555 /* XXX get MIDI and other sources here */
1561 Session::path_from_region_name (string name, string identifier)
1563 char buf[PATH_MAX+1];
1565 string dir = discover_best_sound_dir ();
1567 for (n = 0; n < 999999; ++n) {
1568 if (identifier.length()) {
1569 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1570 identifier.c_str(), n);
1572 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1575 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1580 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1589 Session::load_sources (const XMLNode& node)
1592 XMLNodeConstIterator niter;
1593 boost::shared_ptr<Source> source;
1595 nlist = node.children();
1599 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1602 if ((source = XMLSourceFactory (**niter)) == 0) {
1603 error << _("Session: cannot create Source from XML description.") << endmsg;
1607 catch (non_existent_source& err) {
1608 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1609 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1616 boost::shared_ptr<Source>
1617 Session::XMLSourceFactory (const XMLNode& node)
1619 if (node.name() != "Source") {
1620 return boost::shared_ptr<Source>();
1624 return SourceFactory::create (*this, node);
1627 catch (failed_constructor& err) {
1628 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1629 return boost::shared_ptr<Source>();
1634 Session::save_template (string template_name)
1637 string xml_path, bak_path, template_path;
1639 if (_state_of_the_state & CannotSave) {
1644 string dir = template_dir();
1646 if ((dp = opendir (dir.c_str()))) {
1649 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1650 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1655 tree.set_root (&get_template());
1658 xml_path += template_name;
1659 xml_path += _template_suffix;
1661 ifstream in(xml_path.c_str());
1664 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1670 if (!tree.write (xml_path)) {
1671 error << _("mix template not saved") << endmsg;
1679 Session::rename_template (string old_name, string new_name)
1681 string old_path = template_dir() + old_name + _template_suffix;
1682 string new_path = template_dir() + new_name + _template_suffix;
1684 return rename (old_path.c_str(), new_path.c_str());
1688 Session::delete_template (string name)
1690 string template_path = template_dir();
1691 template_path += name;
1692 template_path += _template_suffix;
1694 return remove (template_path.c_str());
1698 Session::refresh_disk_space ()
1701 struct statfs statfsbuf;
1702 vector<space_and_path>::iterator i;
1703 Glib::Mutex::Lock lm (space_lock);
1706 /* get freespace on every FS that is part of the session path */
1708 _total_free_4k_blocks = 0;
1710 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1711 statfs ((*i).path.c_str(), &statfsbuf);
1713 scale = statfsbuf.f_bsize/4096.0;
1715 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1716 _total_free_4k_blocks += (*i).blocks;
1722 Session::ensure_sound_dir (string path, string& result)
1727 /* Ensure that the parent directory exists */
1729 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1730 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1734 /* Ensure that the sounds directory exists */
1738 result += sound_dir_name;
1740 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1741 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1747 dead += dead_sound_dir_name;
1749 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1750 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1756 peak += peak_dir_name;
1758 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1759 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1763 /* callers expect this to be terminated ... */
1770 Session::discover_best_sound_dir (bool destructive)
1772 vector<space_and_path>::iterator i;
1775 /* handle common case without system calls */
1777 if (session_dirs.size() == 1) {
1781 /* OK, here's the algorithm we're following here:
1783 We want to select which directory to use for
1784 the next file source to be created. Ideally,
1785 we'd like to use a round-robin process so as to
1786 get maximum performance benefits from splitting
1787 the files across multiple disks.
1789 However, in situations without much diskspace, an
1790 RR approach may end up filling up a filesystem
1791 with new files while others still have space.
1792 Its therefore important to pay some attention to
1793 the freespace in the filesystem holding each
1794 directory as well. However, if we did that by
1795 itself, we'd keep creating new files in the file
1796 system with the most space until it was as full
1797 as all others, thus negating any performance
1798 benefits of this RAID-1 like approach.
1800 So, we use a user-configurable space threshold. If
1801 there are at least 2 filesystems with more than this
1802 much space available, we use RR selection between them.
1803 If not, then we pick the filesystem with the most space.
1805 This gets a good balance between the two
1809 refresh_disk_space ();
1811 int free_enough = 0;
1813 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1814 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1819 if (free_enough >= 2) {
1821 bool found_it = false;
1823 /* use RR selection process, ensuring that the one
1827 i = last_rr_session_dir;
1830 if (++i == session_dirs.end()) {
1831 i = session_dirs.begin();
1834 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1835 if (ensure_sound_dir ((*i).path, result) == 0) {
1836 last_rr_session_dir = i;
1842 } while (i != last_rr_session_dir);
1845 result = sound_dir();
1850 /* pick FS with the most freespace (and that
1851 seems to actually work ...)
1854 vector<space_and_path> sorted;
1855 space_and_path_ascending_cmp cmp;
1857 sorted = session_dirs;
1858 sort (sorted.begin(), sorted.end(), cmp);
1860 for (i = sorted.begin(); i != sorted.end(); ++i) {
1861 if (ensure_sound_dir ((*i).path, result) == 0) {
1862 last_rr_session_dir = i;
1867 /* if the above fails, fall back to the most simplistic solution */
1869 if (i == sorted.end()) {
1878 Session::load_playlists (const XMLNode& node)
1881 XMLNodeConstIterator niter;
1882 boost::shared_ptr<Playlist> playlist;
1884 nlist = node.children();
1888 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1890 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1891 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1899 Session::load_unused_playlists (const XMLNode& node)
1902 XMLNodeConstIterator niter;
1903 boost::shared_ptr<Playlist> playlist;
1905 nlist = node.children();
1909 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1911 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1912 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1916 // now manually untrack it
1918 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1925 boost::shared_ptr<Playlist>
1926 Session::XMLPlaylistFactory (const XMLNode& node)
1929 return PlaylistFactory::create (*this, node);
1932 catch (failed_constructor& err) {
1933 return boost::shared_ptr<Playlist>();
1938 Session::load_named_selections (const XMLNode& node)
1941 XMLNodeConstIterator niter;
1944 nlist = node.children();
1948 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1950 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1951 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1959 Session::XMLNamedSelectionFactory (const XMLNode& node)
1962 return new NamedSelection (*this, node);
1965 catch (failed_constructor& err) {
1971 Session::dead_sound_dir () const
1974 res += dead_sound_dir_name;
1980 Session::old_sound_dir (bool with_path) const
1988 res += old_sound_dir_name;
1994 Session::sound_dir (bool with_path) const
2005 res += interchange_dir_name;
2007 res += legalize_for_path (_name);
2009 res += sound_dir_name;
2017 /* if this already exists, don't check for the old session sound directory */
2019 if (Glib::file_test (full, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2023 /* possibly support old session structure */
2026 string old_withpath;
2028 old_nopath += old_sound_dir_name;
2031 old_withpath = _path;
2032 old_withpath += old_sound_dir_name;
2034 if (Glib::file_test (old_withpath.c_str(), Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2036 return old_withpath;
2041 /* ok, old "sounds" directory isn't there, return the new path */
2047 Session::peak_dir () const
2050 res += peak_dir_name;
2056 Session::automation_dir () const
2059 res += "automation/";
2064 Session::analysis_dir () const
2072 Session::template_dir ()
2074 string path = get_user_ardour_path();
2075 path += "templates/";
2081 Session::export_dir () const
2084 res += export_dir_name;
2090 Session::suffixed_search_path (string suffix, bool data)
2094 path += get_user_ardour_path();
2095 if (path[path.length()-1] != ':') {
2100 path += get_system_data_path();
2102 path += get_system_module_path();
2105 vector<string> split_path;
2107 split (path, split_path, ':');
2110 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2115 if (distance (i, split_path.end()) != 1) {
2124 Session::template_path ()
2126 return suffixed_search_path (X_("templates"), true);
2130 Session::control_protocol_path ()
2132 return suffixed_search_path (X_("surfaces"), false);
2136 Session::load_connections (const XMLNode& node)
2138 XMLNodeList nlist = node.children();
2139 XMLNodeConstIterator niter;
2143 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2144 if ((*niter)->name() == "InputConnection") {
2145 add_connection (new ARDOUR::InputConnection (**niter));
2146 } else if ((*niter)->name() == "OutputConnection") {
2147 add_connection (new ARDOUR::OutputConnection (**niter));
2149 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2158 Session::load_edit_groups (const XMLNode& node)
2160 return load_route_groups (node, true);
2164 Session::load_mix_groups (const XMLNode& node)
2166 return load_route_groups (node, false);
2170 Session::load_route_groups (const XMLNode& node, bool edit)
2172 XMLNodeList nlist = node.children();
2173 XMLNodeConstIterator niter;
2178 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2179 if ((*niter)->name() == "RouteGroup") {
2181 rg = add_edit_group ("");
2182 rg->set_state (**niter);
2184 rg = add_mix_group ("");
2185 rg->set_state (**niter);
2194 state_file_filter (const string &str, void *arg)
2196 return (str.length() > strlen(Session::statefile_suffix()) &&
2197 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2201 bool operator()(const string* a, const string* b) {
2207 remove_end(string* state)
2209 string statename(*state);
2211 string::size_type start,end;
2212 if ((start = statename.find_last_of ('/')) != string::npos) {
2213 statename = statename.substr (start+1);
2216 if ((end = statename.rfind(".ardour")) == string::npos) {
2217 end = statename.length();
2220 return new string(statename.substr (0, end));
2224 Session::possible_states (string path)
2226 PathScanner scanner;
2227 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2229 transform(states->begin(), states->end(), states->begin(), remove_end);
2232 sort (states->begin(), states->end(), cmp);
2238 Session::possible_states () const
2240 return possible_states(_path);
2244 Session::auto_save()
2246 save_state (_current_snapshot_name);
2250 Session::add_edit_group (string name)
2252 RouteGroup* rg = new RouteGroup (*this, name);
2253 edit_groups.push_back (rg);
2254 edit_group_added (rg); /* EMIT SIGNAL */
2260 Session::add_mix_group (string name)
2262 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2263 mix_groups.push_back (rg);
2264 mix_group_added (rg); /* EMIT SIGNAL */
2270 Session::remove_edit_group (RouteGroup& rg)
2272 list<RouteGroup*>::iterator i;
2274 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2275 (*i)->apply (&Route::drop_edit_group, this);
2276 edit_groups.erase (i);
2277 edit_group_removed (); /* EMIT SIGNAL */
2284 Session::remove_mix_group (RouteGroup& rg)
2286 list<RouteGroup*>::iterator i;
2288 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2289 (*i)->apply (&Route::drop_mix_group, this);
2290 mix_groups.erase (i);
2291 mix_group_removed (); /* EMIT SIGNAL */
2298 Session::mix_group_by_name (string name)
2300 list<RouteGroup *>::iterator i;
2302 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2303 if ((*i)->name() == name) {
2311 Session::edit_group_by_name (string name)
2313 list<RouteGroup *>::iterator i;
2315 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2316 if ((*i)->name() == name) {
2324 Session::begin_reversible_command (string name)
2326 current_trans = new UndoTransaction;
2327 current_trans->set_name (name);
2331 Session::commit_reversible_command (Command *cmd)
2336 current_trans->add_command (cmd);
2339 if (current_trans->empty()) {
2343 gettimeofday (&now, 0);
2344 current_trans->set_timestamp (now);
2346 _history.add (current_trans);
2349 Session::GlobalRouteBooleanState
2350 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2352 GlobalRouteBooleanState s;
2353 boost::shared_ptr<RouteList> r = routes.reader ();
2355 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2356 if (!(*i)->hidden()) {
2357 RouteBooleanState v;
2360 Route* r = (*i).get();
2361 v.second = (r->*method)();
2370 Session::GlobalRouteMeterState
2371 Session::get_global_route_metering ()
2373 GlobalRouteMeterState s;
2374 boost::shared_ptr<RouteList> r = routes.reader ();
2376 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2377 if (!(*i)->hidden()) {
2381 v.second = (*i)->meter_point();
2391 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2393 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2395 boost::shared_ptr<Route> r = (i->first.lock());
2398 r->set_meter_point (i->second, arg);
2404 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2406 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2408 boost::shared_ptr<Route> r = (i->first.lock());
2411 Route* rp = r.get();
2412 (rp->*method) (i->second, arg);
2418 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2420 set_global_route_boolean (s, &Route::set_mute, src);
2424 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2426 set_global_route_boolean (s, &Route::set_solo, src);
2430 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2432 set_global_route_boolean (s, &Route::set_record_enable, src);
2437 Session::global_mute_memento (void* src)
2439 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2443 Session::global_metering_memento (void* src)
2445 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2449 Session::global_solo_memento (void* src)
2451 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2455 Session::global_record_enable_memento (void* src)
2457 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2462 template_filter (const string &str, void *arg)
2464 return (str.length() > strlen(Session::template_suffix()) &&
2465 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2469 Session::get_template_list (list<string> &template_names)
2471 vector<string *> *templates;
2472 PathScanner scanner;
2475 path = template_path ();
2477 templates = scanner (path, template_filter, 0, false, true);
2479 vector<string*>::iterator i;
2480 for (i = templates->begin(); i != templates->end(); ++i) {
2481 string fullpath = *(*i);
2484 start = fullpath.find_last_of ('/') + 1;
2485 if ((end = fullpath.find_last_of ('.')) <0) {
2486 end = fullpath.length();
2489 template_names.push_back(fullpath.substr(start, (end-start)));
2494 Session::read_favorite_dirs (FavoriteDirs & favs)
2496 string path = get_user_ardour_path();
2497 path += "/favorite_dirs";
2499 ifstream fav (path.c_str());
2504 if (errno != ENOENT) {
2505 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2516 getline(fav, newfav);
2522 favs.push_back (newfav);
2529 Session::write_favorite_dirs (FavoriteDirs & favs)
2531 string path = get_user_ardour_path();
2532 path += "/favorite_dirs";
2534 ofstream fav (path.c_str());
2540 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2541 fav << (*i) << endl;
2548 accept_all_non_peak_files (const string& path, void *arg)
2550 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2554 accept_all_state_files (const string& path, void *arg)
2556 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2560 Session::find_all_sources (string path, set<string>& result)
2565 if (!tree.read (path)) {
2569 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2574 XMLNodeConstIterator niter;
2576 nlist = node->children();
2580 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2584 if ((prop = (*niter)->property (X_("name"))) == 0) {
2588 if (prop->value()[0] == '/') {
2589 /* external file, ignore */
2593 string path = _path; /* /-terminated */
2594 path += sound_dir_name;
2596 path += prop->value();
2598 result.insert (path);
2605 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2607 PathScanner scanner;
2608 vector<string*>* state_files;
2610 string this_snapshot_path;
2616 if (ripped[ripped.length()-1] == '/') {
2617 ripped = ripped.substr (0, ripped.length() - 1);
2620 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2622 if (state_files == 0) {
2627 this_snapshot_path = _path;
2628 this_snapshot_path += _current_snapshot_name;
2629 this_snapshot_path += _statefile_suffix;
2631 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2633 if (exclude_this_snapshot && **i == this_snapshot_path) {
2637 if (find_all_sources (**i, result) < 0) {
2645 struct RegionCounter {
2646 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2647 AudioSourceList::iterator iter;
2648 boost::shared_ptr<Region> region;
2651 RegionCounter() : count (0) {}
2655 Session::cleanup_sources (Session::cleanup_report& rep)
2657 vector<boost::shared_ptr<Source> > dead_sources;
2658 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2659 PathScanner scanner;
2661 vector<space_and_path>::iterator i;
2662 vector<space_and_path>::iterator nexti;
2663 vector<string*>* soundfiles;
2664 vector<string> unused;
2665 set<string> all_sources;
2670 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2673 /* step 1: consider deleting all unused playlists */
2675 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2678 status = AskAboutPlaylistDeletion (*x);
2687 playlists_tbd.push_back (*x);
2691 /* leave it alone */
2696 /* now delete any that were marked for deletion */
2698 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2699 (*x)->drop_references ();
2702 playlists_tbd.clear ();
2704 /* step 2: find all un-used sources */
2709 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2711 AudioSourceList::iterator tmp;
2716 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2720 if (!i->second->used() && i->second->length() > 0) {
2721 dead_sources.push_back (i->second);
2722 i->second->GoingAway();
2728 /* build a list of all the possible sound directories for the session */
2730 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2735 sound_path += (*i).path;
2736 sound_path += sound_dir (false);
2738 if (nexti != session_dirs.end()) {
2745 /* now do the same thing for the files that ended up in the sounds dir(s)
2746 but are not referenced as sources in any snapshot.
2749 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2751 if (soundfiles == 0) {
2755 /* find all sources, but don't use this snapshot because the
2756 state file on disk still references sources we may have already
2760 find_all_sources_across_snapshots (all_sources, true);
2762 /* add our current source list
2765 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2766 boost::shared_ptr<AudioFileSource> fs;
2768 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2769 all_sources.insert (fs->path());
2773 char tmppath1[PATH_MAX+1];
2774 char tmppath2[PATH_MAX+1];
2776 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2781 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2783 realpath(spath.c_str(), tmppath1);
2784 realpath((*i).c_str(), tmppath2);
2786 if (strcmp(tmppath1, tmppath2) == 0) {
2793 unused.push_back (spath);
2797 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2799 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2800 struct stat statbuf;
2802 rep.paths.push_back (*x);
2803 if (stat ((*x).c_str(), &statbuf) == 0) {
2804 rep.space += statbuf.st_size;
2809 /* don't move the file across filesystems, just
2810 stick it in the `dead_sound_dir_name' directory
2811 on whichever filesystem it was already on.
2814 if ((*x).find ("/sounds/") != string::npos) {
2816 /* old school, go up 1 level */
2818 newpath = Glib::path_get_dirname (*x); // "sounds"
2819 newpath = Glib::path_get_dirname (newpath); // "session-name"
2823 /* new school, go up 4 levels */
2825 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2826 newpath = Glib::path_get_dirname (newpath); // "session-name"
2827 newpath = Glib::path_get_dirname (newpath); // "interchange"
2828 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2832 newpath += dead_sound_dir_name;
2834 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2835 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2840 newpath += Glib::path_get_basename ((*x));
2842 if (access (newpath.c_str(), F_OK) == 0) {
2844 /* the new path already exists, try versioning */
2846 char buf[PATH_MAX+1];
2850 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2853 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2854 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2858 if (version == 999) {
2859 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2863 newpath = newpath_v;
2868 /* it doesn't exist, or we can't read it or something */
2872 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2873 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2874 (*x), newpath, strerror (errno))
2879 /* see if there an easy to find peakfile for this file, and remove it.
2882 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2883 peakpath += ".peak";
2885 if (access (peakpath.c_str(), W_OK) == 0) {
2886 if (::unlink (peakpath.c_str()) != 0) {
2887 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2888 peakpath, _path, strerror (errno))
2890 /* try to back out */
2891 rename (newpath.c_str(), _path.c_str());
2899 /* dump the history list */
2903 /* save state so we don't end up a session file
2904 referring to non-existent sources.
2910 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2916 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2918 vector<space_and_path>::iterator i;
2919 string dead_sound_dir;
2920 struct dirent* dentry;
2921 struct stat statbuf;
2927 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2929 dead_sound_dir = (*i).path;
2930 dead_sound_dir += dead_sound_dir_name;
2932 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2936 while ((dentry = readdir (dead)) != 0) {
2938 /* avoid '.' and '..' */
2940 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2941 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2947 fullpath = dead_sound_dir;
2949 fullpath += dentry->d_name;
2951 if (stat (fullpath.c_str(), &statbuf)) {
2955 if (!S_ISREG (statbuf.st_mode)) {
2959 if (unlink (fullpath.c_str())) {
2960 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2961 fullpath, strerror (errno))
2965 rep.paths.push_back (dentry->d_name);
2966 rep.space += statbuf.st_size;
2977 Session::set_dirty ()
2979 bool was_dirty = dirty();
2981 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2985 DirtyChanged(); /* EMIT SIGNAL */
2991 Session::set_clean ()
2993 bool was_dirty = dirty();
2995 _state_of_the_state = Clean;
2999 DirtyChanged(); /* EMIT SIGNAL */
3004 Session::set_deletion_in_progress ()
3006 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3011 Session::add_controllable (Controllable* c)
3013 /* this adds a controllable to the list managed by the Session.
3014 this is a subset of those managed by the Controllable class
3015 itself, and represents the only ones whose state will be saved
3016 as part of the session.
3019 Glib::Mutex::Lock lm (controllables_lock);
3020 controllables.insert (c);
3024 Session::remove_controllable (Controllable* c)
3026 if (_state_of_the_state | Deletion) {
3030 Glib::Mutex::Lock lm (controllables_lock);
3032 Controllables::iterator x = controllables.find (c);
3034 if (x != controllables.end()) {
3035 controllables.erase (x);
3040 Session::controllable_by_id (const PBD::ID& id)
3042 Glib::Mutex::Lock lm (controllables_lock);
3044 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3045 if ((*i)->id() == id) {
3054 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3056 Stateful::add_instant_xml (node, dir);
3057 Config->add_instant_xml (node, get_user_ardour_path());
3061 Session::save_history (string snapshot_name)
3067 if (snapshot_name.empty()) {
3068 snapshot_name = _current_snapshot_name;
3071 xml_path = _path + snapshot_name + ".history";
3073 bak_path = xml_path + ".bak";
3075 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && ::rename (xml_path.c_str(), bak_path.c_str())) {
3076 error << _("could not backup old history file, current history not saved.") << endmsg;
3080 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3084 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3086 if (!tree.write (xml_path))
3088 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3090 /* don't leave a corrupt file lying around if it is
3094 if (unlink (xml_path.c_str())) {
3095 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
3097 if (rename (bak_path.c_str(), xml_path.c_str()))
3099 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
3110 Session::restore_history (string snapshot_name)
3115 if (snapshot_name.empty()) {
3116 snapshot_name = _current_snapshot_name;
3120 xmlpath = _path + snapshot_name + ".history";
3121 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
3123 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3127 if (!tree.read (xmlpath)) {
3128 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
3132 /* replace history */
3135 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3138 UndoTransaction* ut = new UndoTransaction ();
3141 ut->set_name(t->property("name")->value());
3142 stringstream ss(t->property("tv_sec")->value());
3144 ss.str(t->property("tv_usec")->value());
3146 ut->set_timestamp(tv);
3148 for (XMLNodeConstIterator child_it = t->children().begin();
3149 child_it != t->children().end();
3152 XMLNode *n = *child_it;
3155 if (n->name() == "MementoCommand" ||
3156 n->name() == "MementoUndoCommand" ||
3157 n->name() == "MementoRedoCommand") {
3159 if ((c = memento_command_factory(n))) {
3163 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3165 if ((c = global_state_command_factory (*n))) {
3166 ut->add_command (c);
3171 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3182 Session::config_changed (const char* parameter_name)
3184 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3186 if (PARAM_IS ("seamless-loop")) {
3188 } else if (PARAM_IS ("rf-speed")) {
3190 } else if (PARAM_IS ("auto-loop")) {
3192 } else if (PARAM_IS ("auto-input")) {
3194 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3195 /* auto-input only makes a difference if we're rolling */
3197 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3199 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3200 if ((*i)->record_enabled ()) {
3201 (*i)->monitor_input (!Config->get_auto_input());
3206 } else if (PARAM_IS ("punch-in")) {
3210 if ((location = _locations.auto_punch_location()) != 0) {
3212 if (Config->get_punch_in ()) {
3213 replace_event (Event::PunchIn, location->start());
3215 remove_event (location->start(), Event::PunchIn);
3219 } else if (PARAM_IS ("punch-out")) {
3223 if ((location = _locations.auto_punch_location()) != 0) {
3225 if (Config->get_punch_out()) {
3226 replace_event (Event::PunchOut, location->end());
3228 clear_events (Event::PunchOut);
3232 } else if (PARAM_IS ("edit-mode")) {
3234 Glib::Mutex::Lock lm (playlist_lock);
3236 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3237 (*i)->set_edit_mode (Config->get_edit_mode ());
3240 } else if (PARAM_IS ("use-video-sync")) {
3242 waiting_for_sync_offset = Config->get_use_video_sync();
3244 } else if (PARAM_IS ("mmc-control")) {
3246 poke_midi_thread ();
3248 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-device-id")) {
3250 set_mmc_receive_device_id (Config->get_mmc_receive_device_id());
3252 } else if (PARAM_IS ("mmc-send-device-id")) {
3254 set_mmc_send_device_id (Config->get_mmc_send_device_id());
3256 } else if (PARAM_IS ("midi-control")) {
3258 poke_midi_thread ();
3260 } else if (PARAM_IS ("raid-path")) {
3262 setup_raid_path (Config->get_raid_path());
3264 } else if (PARAM_IS ("smpte-format")) {
3268 } else if (PARAM_IS ("video-pullup")) {
3272 } else if (PARAM_IS ("seamless-loop")) {
3274 if (play_loop && transport_rolling()) {
3275 // to reset diskstreams etc
3276 request_play_loop (true);
3279 } else if (PARAM_IS ("rf-speed")) {
3281 cumulative_rf_motion = 0;
3284 } else if (PARAM_IS ("click-sound")) {
3286 setup_click_sounds (1);
3288 } else if (PARAM_IS ("click-emphasis-sound")) {
3290 setup_click_sounds (-1);
3292 } else if (PARAM_IS ("clicking")) {
3294 if (Config->get_clicking()) {
3295 if (_click_io && click_data) { // don't require emphasis data
3302 } else if (PARAM_IS ("send-mtc")) {
3304 /* only set the internal flag if we have
3308 if (_mtc_port != 0) {
3309 session_send_mtc = Config->get_send_mtc();
3310 if (session_send_mtc) {
3311 /* mark us ready to send */
3312 next_quarter_frame_to_send = 0;
3315 session_send_mtc = false;
3318 } else if (PARAM_IS ("send-mmc")) {
3320 /* only set the internal flag if we have
3324 if (_mmc_port != 0) {
3325 session_send_mmc = Config->get_send_mmc();
3328 session_send_mmc = false;
3331 } else if (PARAM_IS ("midi-feedback")) {
3333 /* only set the internal flag if we have
3337 if (_mtc_port != 0) {
3338 session_midi_feedback = Config->get_midi_feedback();
3341 } else if (PARAM_IS ("jack-time-master")) {
3343 engine().reset_timebase ();
3345 } else if (PARAM_IS ("native-file-header-format")) {
3347 if (!first_file_header_format_reset) {
3348 reset_native_file_format ();
3351 first_file_header_format_reset = false;
3353 } else if (PARAM_IS ("native-file-data-format")) {
3355 if (!first_file_data_format_reset) {
3356 reset_native_file_format ();
3359 first_file_data_format_reset = false;
3361 } else if (PARAM_IS ("slave-source")) {
3362 set_slave_source (Config->get_slave_source());
3363 } else if (PARAM_IS ("remote-model")) {
3364 set_remote_control_ids ();
3365 } else if (PARAM_IS ("denormal-model")) {
3367 } else if (PARAM_IS ("history-depth")) {
3368 set_history_depth (Config->get_history_depth());
3369 } else if (PARAM_IS ("sync-all-route-ordering")) {
3380 Session::set_history_depth (uint32_t d)
3382 _history.set_depth (d);