2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <sigc++/bind.h>
27 #include <cstdio> /* snprintf(3) ... grrr */
42 #include <sys/param.h>
43 #include <sys/mount.h>
48 #include <midi++/mmc.h>
49 #include <midi++/port.h>
50 #include <pbd/error.h>
52 #include <glibmm/thread.h>
53 #include <pbd/pathscanner.h>
54 #include <pbd/pthread_utils.h>
55 #include <pbd/strsplit.h>
56 #include <pbd/stacktrace.h>
57 #include <pbd/copyfile.h>
59 #include <ardour/audioengine.h>
60 #include <ardour/configuration.h>
61 #include <ardour/session.h>
62 #include <ardour/audio_diskstream.h>
63 #include <ardour/utils.h>
64 #include <ardour/audioplaylist.h>
65 #include <ardour/audiofilesource.h>
66 #include <ardour/silentfilesource.h>
67 #include <ardour/sndfilesource.h>
68 #include <ardour/sndfile_helpers.h>
69 #include <ardour/auditioner.h>
70 #include <ardour/export.h>
71 #include <ardour/redirect.h>
72 #include <ardour/send.h>
73 #include <ardour/insert.h>
74 #include <ardour/connection.h>
75 #include <ardour/slave.h>
76 #include <ardour/tempo.h>
77 #include <ardour/audio_track.h>
78 #include <ardour/cycle_timer.h>
79 #include <ardour/utils.h>
80 #include <ardour/named_selection.h>
81 #include <ardour/version.h>
82 #include <ardour/location.h>
83 #include <ardour/audioregion.h>
84 #include <ardour/crossfade.h>
85 #include <ardour/control_protocol_manager.h>
86 #include <ardour/region_factory.h>
87 #include <ardour/source_factory.h>
88 #include <ardour/playlist_factory.h>
90 #include <control_protocol/control_protocol.h>
96 using namespace ARDOUR;
100 Session::first_stage_init (string fullpath, string snapshot_name)
102 if (fullpath.length() == 0) {
104 throw failed_constructor();
107 char buf[PATH_MAX+1];
108 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
109 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
111 throw failed_constructor();
116 if (_path[_path.length()-1] != '/') {
120 /* these two are just provisional settings. set_state()
121 will likely override them.
124 _name = _current_snapshot_name = snapshot_name;
126 _current_frame_rate = _engine.frame_rate ();
127 _tempo_map = new TempoMap (_current_frame_rate);
128 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
130 g_atomic_int_set (&processing_prohibited, 0);
132 _transport_speed = 0;
133 _last_transport_speed = 0;
134 auto_play_legal = false;
135 transport_sub_state = 0;
136 _transport_frame = 0;
138 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
139 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
140 _end_location_is_free = true;
141 g_atomic_int_set (&_record_status, Disabled);
142 loop_changing = false;
144 _last_roll_location = 0;
145 _last_record_location = 0;
146 pending_locate_frame = 0;
147 pending_locate_roll = false;
148 pending_locate_flush = false;
149 dstream_buffer_size = 0;
151 state_was_pending = false;
153 outbound_mtc_smpte_frame = 0;
154 next_quarter_frame_to_send = -1;
155 current_block_size = 0;
156 solo_update_disabled = false;
157 currently_soloing = false;
158 _have_captured = false;
159 _worst_output_latency = 0;
160 _worst_input_latency = 0;
161 _worst_track_latency = 0;
162 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
164 butler_mixdown_buffer = 0;
165 butler_gain_buffer = 0;
167 session_send_mmc = false;
168 session_send_mtc = false;
169 post_transport_work = PostTransportWork (0);
170 g_atomic_int_set (&butler_should_do_transport_work, 0);
171 g_atomic_int_set (&butler_active, 0);
172 g_atomic_int_set (&_playback_load, 100);
173 g_atomic_int_set (&_capture_load, 100);
174 g_atomic_int_set (&_playback_load_min, 100);
175 g_atomic_int_set (&_capture_load_min, 100);
177 waiting_to_start = false;
179 _gain_automation_buffer = 0;
180 _pan_automation_buffer = 0;
182 pending_abort = false;
183 destructive_index = 0;
185 first_file_data_format_reset = true;
186 first_file_header_format_reset = true;
187 butler_thread = (pthread_t) 0;
188 midi_thread = (pthread_t) 0;
190 AudioDiskstream::allocate_working_buffers();
192 /* default short fade = 15ms */
194 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
195 SndFileSource::setup_standard_crossfades (frame_rate());
197 last_mmc_step.tv_sec = 0;
198 last_mmc_step.tv_usec = 0;
201 /* click sounds are unset by default, which causes us to internal
202 waveforms for clicks.
206 click_emphasis_data = 0;
208 click_emphasis_length = 0;
211 process_function = &Session::process_with_events;
213 if (Config->get_use_video_sync()) {
214 waiting_for_sync_offset = true;
216 waiting_for_sync_offset = false;
219 _current_frame_rate = 48000;
220 _base_frame_rate = 48000;
224 _smpte_offset_negative = true;
225 last_smpte_valid = false;
229 last_rr_session_dir = session_dirs.begin();
230 refresh_disk_space ();
232 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
236 average_slave_delta = 1800;
237 have_first_delta_accumulator = false;
238 delta_accumulator_cnt = 0;
239 slave_state = Stopped;
241 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
243 /* These are all static "per-class" signals */
245 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
246 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
247 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
248 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
249 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
250 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
252 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
254 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
256 /* stop IO objects from doing stuff until we're ready for them */
258 IO::disable_panners ();
259 IO::disable_ports ();
260 IO::disable_connecting ();
264 Session::second_stage_init (bool new_session)
266 AudioFileSource::set_peak_dir (peak_dir());
269 if (load_state (_current_snapshot_name)) {
272 remove_empty_sounds ();
275 if (start_butler_thread()) {
279 if (start_midi_thread ()) {
283 // set_state() will call setup_raid_path(), but if it's a new session we need
284 // to call setup_raid_path() here.
286 if (set_state (*state_tree->root())) {
290 setup_raid_path(_path);
293 /* we can't save till after ::when_engine_running() is called,
294 because otherwise we save state with no connections made.
295 therefore, we reset _state_of_the_state because ::set_state()
296 will have cleared it.
298 we also have to include Loading so that any events that get
299 generated between here and the end of ::when_engine_running()
300 will be processed directly rather than queued.
303 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
305 // set_auto_input (true);
306 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
307 _locations.added.connect (mem_fun (this, &Session::locations_added));
308 setup_click_sounds (0);
309 setup_midi_control ();
311 /* Pay attention ... */
313 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
314 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
317 when_engine_running();
320 /* handle this one in a different way than all others, so that its clear what happened */
322 catch (AudioEngine::PortRegistrationFailure& err) {
323 error << _("Unable to create all required ports")
332 send_full_time_code ();
333 _engine.transport_locate (0);
334 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
335 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
337 ControlProtocolManager::instance().set_session (*this);
340 _end_location_is_free = true;
342 _end_location_is_free = false;
349 Session::raid_path () const
353 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
358 return path.substr (0, path.length() - 1); // drop final colon
362 Session::setup_raid_path (string path)
364 string::size_type colon;
368 string::size_type len = path.length();
373 if (path.length() == 0) {
377 session_dirs.clear ();
379 for (string::size_type n = 0; n < len; ++n) {
380 if (path[n] == ':') {
387 /* no multiple search path, just one location (common case) */
391 session_dirs.push_back (sp);
398 if (fspath[fspath.length()-1] != '/') {
402 fspath += sound_dir (false);
404 AudioFileSource::set_search_path (fspath);
411 while ((colon = remaining.find_first_of (':')) != string::npos) {
414 sp.path = remaining.substr (0, colon);
415 session_dirs.push_back (sp);
417 /* add sounds to file search path */
420 if (fspath[fspath.length()-1] != '/') {
423 fspath += sound_dir (false);
426 remaining = remaining.substr (colon+1);
429 if (remaining.length()) {
436 if (fspath[fspath.length()-1] != '/') {
439 fspath += sound_dir (false);
442 session_dirs.push_back (sp);
445 /* set the AudioFileSource search path */
447 AudioFileSource::set_search_path (fspath);
449 /* reset the round-robin soundfile path thingie */
451 last_rr_session_dir = session_dirs.begin();
455 Session::create (bool& new_session, string* mix_template, nframes_t initial_length)
459 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
460 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
466 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
467 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
471 /* if this is is an existing session with an old "sounds" directory, just use it. see Session::sound_dir() for more details */
473 if (!Glib::file_test (old_sound_dir(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
477 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
478 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
483 dir = dead_sound_dir ();
485 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
486 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
492 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
493 error << string_compose(_("Session: cannot create session export dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
498 /* check new_session so we don't overwrite an existing one */
501 std::string in_path = *mix_template;
503 ifstream in(in_path.c_str());
506 string out_path = _path;
508 out_path += _statefile_suffix;
510 ofstream out(out_path.c_str());
515 // okay, session is set up. Treat like normal saved
516 // session from now on.
522 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
528 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
535 /* set initial start + end point */
537 start_location->set_end (0);
538 _locations.add (start_location);
540 end_location->set_end (initial_length);
541 _locations.add (end_location);
543 _state_of_the_state = Clean;
545 if (save_state (_current_snapshot_name)) {
553 Session::load_diskstreams (const XMLNode& node)
556 XMLNodeConstIterator citer;
558 clist = node.children();
560 for (citer = clist.begin(); citer != clist.end(); ++citer) {
564 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
565 add_diskstream (dstream);
568 catch (failed_constructor& err) {
569 error << _("Session: could not load diskstream via XML state") << endmsg;
578 Session::remove_pending_capture_state ()
583 xml_path += _current_snapshot_name;
584 xml_path += _pending_suffix;
586 unlink (xml_path.c_str());
589 /** Rename a state file.
590 * @param snapshot_name Snapshot name.
593 Session::rename_state (string old_name, string new_name)
595 if (old_name == _current_snapshot_name || old_name == _name) {
596 /* refuse to rename the current snapshot or the "main" one */
600 const string old_xml_path = _path + old_name + _statefile_suffix;
601 const string new_xml_path = _path + new_name + _statefile_suffix;
603 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
604 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
608 /** Remove a state file.
609 * @param snapshot_name Snapshot name.
612 Session::remove_state (string snapshot_name)
614 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
615 /* refuse to remove the current snapshot or the "main" one */
619 const string xml_path = _path + snapshot_name + _statefile_suffix;
621 /* make a backup copy of the state file */
622 const string bak_path = xml_path + ".bak";
623 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
624 copy_file (xml_path, bak_path);
628 unlink (xml_path.c_str());
632 Session::save_state (string snapshot_name, bool pending)
638 if (_state_of_the_state & CannotSave) {
642 if (!_engine.connected ()) {
643 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
648 tree.set_root (&get_state());
650 if (snapshot_name.empty()) {
651 snapshot_name = _current_snapshot_name;
656 /* proper save: use _statefile_suffix (.ardour in English) */
658 xml_path += snapshot_name;
659 xml_path += _statefile_suffix;
661 /* make a backup copy of the old file */
665 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
666 copy_file (xml_path, bak_path);
671 /* pending save: use _pending_suffix (.pending in English) */
673 xml_path += snapshot_name;
674 xml_path += _pending_suffix;
681 tmp_path += snapshot_name;
684 cerr << "actually writing state\n";
686 if (!tree.write (tmp_path)) {
687 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
688 unlink (tmp_path.c_str());
693 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
694 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
695 unlink (tmp_path.c_str());
702 save_history (snapshot_name);
704 bool was_dirty = dirty();
706 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
709 DirtyChanged (); /* EMIT SIGNAL */
712 StateSaved (snapshot_name); /* EMIT SIGNAL */
719 Session::restore_state (string snapshot_name)
721 if (load_state (snapshot_name) == 0) {
722 set_state (*state_tree->root());
729 Session::load_state (string snapshot_name)
738 state_was_pending = false;
740 /* check for leftover pending state from a crashed capture attempt */
743 xmlpath += snapshot_name;
744 xmlpath += _pending_suffix;
746 if (!access (xmlpath.c_str(), F_OK)) {
748 /* there is pending state from a crashed capture attempt */
750 if (AskAboutPendingState()) {
751 state_was_pending = true;
755 if (!state_was_pending) {
758 xmlpath += snapshot_name;
759 xmlpath += _statefile_suffix;
762 if (access (xmlpath.c_str(), F_OK)) {
763 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
767 state_tree = new XMLTree;
771 if (!state_tree->read (xmlpath)) {
772 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
778 XMLNode& root (*state_tree->root());
780 if (root.name() != X_("Session")) {
781 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
787 const XMLProperty* prop;
790 if ((prop = root.property ("version")) == 0) {
791 /* no version implies very old version of Ardour */
795 major_version = atoi (prop->value()); // grab just the first number before the period
796 if (major_version < 2) {
804 backup_path = xmlpath;
807 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
808 xmlpath, backup_path)
811 copy_file (xmlpath, backup_path);
813 /* if it fails, don't worry. right? */
820 Session::load_options (const XMLNode& node)
824 LocaleGuard lg (X_("POSIX"));
826 Config->set_variables (node, ConfigVariableBase::Session);
828 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
829 if ((prop = child->property ("val")) != 0) {
830 _end_location_is_free = (prop->value() == "yes");
838 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
840 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
841 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
843 return owner & modified_by_session_or_user;
847 Session::get_options () const
850 LocaleGuard lg (X_("POSIX"));
852 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
854 child = option_root.add_child ("end-marker-is-free");
855 child->add_property ("val", _end_location_is_free ? "yes" : "no");
867 Session::get_template()
869 /* if we don't disable rec-enable, diskstreams
870 will believe they need to store their capture
871 sources in their state node.
874 disable_record (false);
880 Session::state(bool full_state)
882 XMLNode* node = new XMLNode("Session");
885 // store libardour version, just in case
887 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
888 libardour_major_version, libardour_minor_version, libardour_micro_version);
889 node->add_property("version", string(buf));
891 /* store configuration settings */
896 node->add_property ("name", _name);
898 if (session_dirs.size() > 1) {
902 vector<space_and_path>::iterator i = session_dirs.begin();
903 vector<space_and_path>::iterator next;
905 ++i; /* skip the first one */
909 while (i != session_dirs.end()) {
913 if (next != session_dirs.end()) {
923 child = node->add_child ("Path");
924 child->add_content (p);
928 /* save the ID counter */
930 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
931 node->add_property ("id-counter", buf);
933 /* various options */
935 node->add_child_nocopy (get_options());
937 child = node->add_child ("Sources");
940 Glib::Mutex::Lock sl (audio_source_lock);
942 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
944 /* Don't save information about AudioFileSources that are empty */
946 boost::shared_ptr<AudioFileSource> fs;
948 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
950 /* destructive file sources are OK if they are empty, because
951 we will re-use them every time.
954 if (!fs->destructive()) {
955 if (fs->length() == 0) {
961 child->add_child_nocopy (siter->second->get_state());
965 child = node->add_child ("Regions");
968 Glib::Mutex::Lock rl (region_lock);
970 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
972 /* only store regions not attached to playlists */
974 if (i->second->playlist() == 0) {
975 child->add_child_nocopy (i->second->state (true));
980 child = node->add_child ("DiskStreams");
983 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
984 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
985 if (!(*i)->hidden()) {
986 child->add_child_nocopy ((*i)->get_state());
992 node->add_child_nocopy (_locations.get_state());
994 // for a template, just create a new Locations, populate it
995 // with the default start and end, and get the state for that.
997 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
998 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1001 end->set_end(compute_initial_length());
1003 node->add_child_nocopy (loc.get_state());
1006 child = node->add_child ("Connections");
1008 Glib::Mutex::Lock lm (connection_lock);
1009 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1010 if (!(*i)->system_dependent()) {
1011 child->add_child_nocopy ((*i)->get_state());
1016 child = node->add_child ("Routes");
1018 boost::shared_ptr<RouteList> r = routes.reader ();
1020 RoutePublicOrderSorter cmp;
1021 RouteList public_order (*r);
1022 public_order.sort (cmp);
1024 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1025 if (!(*i)->hidden()) {
1027 child->add_child_nocopy ((*i)->get_state());
1029 child->add_child_nocopy ((*i)->get_template());
1036 child = node->add_child ("EditGroups");
1037 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1038 child->add_child_nocopy ((*i)->get_state());
1041 child = node->add_child ("MixGroups");
1042 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1043 child->add_child_nocopy ((*i)->get_state());
1046 child = node->add_child ("Playlists");
1047 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1048 if (!(*i)->hidden()) {
1049 if (!(*i)->empty()) {
1051 child->add_child_nocopy ((*i)->get_state());
1053 child->add_child_nocopy ((*i)->get_template());
1059 child = node->add_child ("UnusedPlaylists");
1060 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1061 if (!(*i)->hidden()) {
1062 if (!(*i)->empty()) {
1064 child->add_child_nocopy ((*i)->get_state());
1066 child->add_child_nocopy ((*i)->get_template());
1074 child = node->add_child ("Click");
1075 child->add_child_nocopy (_click_io->state (full_state));
1079 child = node->add_child ("NamedSelections");
1080 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1082 child->add_child_nocopy ((*i)->get_state());
1087 node->add_child_nocopy (_tempo_map->get_state());
1089 node->add_child_nocopy (get_control_protocol_state());
1092 node->add_child_copy (*_extra_xml);
1099 Session::get_control_protocol_state ()
1101 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1102 return cpm.get_state();
1106 Session::set_state (const XMLNode& node)
1110 const XMLProperty* prop;
1113 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1115 if (node.name() != X_("Session")){
1116 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1120 if ((prop = node.property ("name")) != 0) {
1121 _name = prop->value ();
1124 setup_raid_path(_path);
1126 if ((prop = node.property (X_("id-counter"))) != 0) {
1128 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1129 ID::init_counter (x);
1131 /* old sessions used a timebased counter, so fake
1132 the startup ID counter based on a standard
1137 ID::init_counter (now);
1141 IO::disable_ports ();
1142 IO::disable_connecting ();
1144 /* Object loading order:
1162 if (use_config_midi_ports ()) {
1165 if ((child = find_named_node (node, "extra")) != 0) {
1166 _extra_xml = new XMLNode (*child);
1169 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1170 load_options (*child);
1171 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1172 load_options (*child);
1174 error << _("Session: XML state has no options section") << endmsg;
1177 if ((child = find_named_node (node, "Locations")) == 0) {
1178 error << _("Session: XML state has no locations section") << endmsg;
1180 } else if (_locations.set_state (*child)) {
1186 if ((location = _locations.auto_loop_location()) != 0) {
1187 set_auto_loop_location (location);
1190 if ((location = _locations.auto_punch_location()) != 0) {
1191 set_auto_punch_location (location);
1194 if ((location = _locations.end_location()) == 0) {
1195 _locations.add (end_location);
1197 delete end_location;
1198 end_location = location;
1201 if ((location = _locations.start_location()) == 0) {
1202 _locations.add (start_location);
1204 delete start_location;
1205 start_location = location;
1208 AudioFileSource::set_header_position_offset (start_location->start());
1210 if ((child = find_named_node (node, "Sources")) == 0) {
1211 error << _("Session: XML state has no sources section") << endmsg;
1213 } else if (load_sources (*child)) {
1217 if ((child = find_named_node (node, "Regions")) == 0) {
1218 error << _("Session: XML state has no Regions section") << endmsg;
1220 } else if (load_regions (*child)) {
1224 if ((child = find_named_node (node, "Playlists")) == 0) {
1225 error << _("Session: XML state has no playlists section") << endmsg;
1227 } else if (load_playlists (*child)) {
1231 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1233 } else if (load_unused_playlists (*child)) {
1237 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1238 if (load_named_selections (*child)) {
1243 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1244 error << _("Session: XML state has no diskstreams section") << endmsg;
1246 } else if (load_diskstreams (*child)) {
1250 if ((child = find_named_node (node, "Connections")) == 0) {
1251 error << _("Session: XML state has no connections section") << endmsg;
1253 } else if (load_connections (*child)) {
1257 if ((child = find_named_node (node, "EditGroups")) == 0) {
1258 error << _("Session: XML state has no edit groups section") << endmsg;
1260 } else if (load_edit_groups (*child)) {
1264 if ((child = find_named_node (node, "MixGroups")) == 0) {
1265 error << _("Session: XML state has no mix groups section") << endmsg;
1267 } else if (load_mix_groups (*child)) {
1271 if ((child = find_named_node (node, "TempoMap")) == 0) {
1272 error << _("Session: XML state has no Tempo Map section") << endmsg;
1274 } else if (_tempo_map->set_state (*child)) {
1278 if ((child = find_named_node (node, "Routes")) == 0) {
1279 error << _("Session: XML state has no routes section") << endmsg;
1281 } else if (load_routes (*child)) {
1285 if ((child = find_named_node (node, "Click")) == 0) {
1286 warning << _("Session: XML state has no click section") << endmsg;
1287 } else if (_click_io) {
1288 _click_io->set_state (*child);
1291 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1292 ControlProtocolManager::instance().set_protocol_states (*child);
1295 /* here beginneth the second phase ... */
1297 StateReady (); /* EMIT SIGNAL */
1299 _state_of_the_state = Clean;
1301 if (state_was_pending) {
1302 save_state (_current_snapshot_name);
1303 remove_pending_capture_state ();
1304 state_was_pending = false;
1314 Session::load_routes (const XMLNode& node)
1317 XMLNodeConstIterator niter;
1318 RouteList new_routes;
1320 nlist = node.children();
1324 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1326 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1329 error << _("Session: cannot create Route from XML description.") << endmsg;
1333 new_routes.push_back (route);
1336 add_routes (new_routes);
1341 boost::shared_ptr<Route>
1342 Session::XMLRouteFactory (const XMLNode& node)
1344 if (node.name() != "Route") {
1345 return boost::shared_ptr<Route> ((Route*) 0);
1348 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1349 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1352 boost::shared_ptr<Route> x (new Route (*this, node));
1358 Session::load_regions (const XMLNode& node)
1361 XMLNodeConstIterator niter;
1362 boost::shared_ptr<AudioRegion> region;
1364 nlist = node.children();
1368 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1369 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1370 error << _("Session: cannot create Region from XML description.") << endmsg;
1377 boost::shared_ptr<AudioRegion>
1378 Session::XMLRegionFactory (const XMLNode& node, bool full)
1380 const XMLProperty* prop;
1381 boost::shared_ptr<Source> source;
1382 boost::shared_ptr<AudioSource> as;
1384 uint32_t nchans = 1;
1387 if (node.name() != X_("Region")) {
1388 return boost::shared_ptr<AudioRegion>();
1391 if ((prop = node.property (X_("channels"))) != 0) {
1392 nchans = atoi (prop->value().c_str());
1396 if ((prop = node.property ("name")) == 0) {
1397 cerr << "no name for this region\n";
1401 if ((prop = node.property (X_("source-0"))) == 0) {
1402 if ((prop = node.property ("source")) == 0) {
1403 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1404 return boost::shared_ptr<AudioRegion>();
1408 PBD::ID s_id (prop->value());
1410 if ((source = source_by_id (s_id)) == 0) {
1411 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1412 return boost::shared_ptr<AudioRegion>();
1415 as = boost::dynamic_pointer_cast<AudioSource>(source);
1417 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1418 return boost::shared_ptr<AudioRegion>();
1421 sources.push_back (as);
1423 /* pickup other channels */
1425 for (uint32_t n=1; n < nchans; ++n) {
1426 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1427 if ((prop = node.property (buf)) != 0) {
1429 PBD::ID id2 (prop->value());
1431 if ((source = source_by_id (id2)) == 0) {
1432 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1433 return boost::shared_ptr<AudioRegion>();
1436 as = boost::dynamic_pointer_cast<AudioSource>(source);
1438 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1439 return boost::shared_ptr<AudioRegion>();
1441 sources.push_back (as);
1446 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1448 /* a final detail: this is the one and only place that we know how long missing files are */
1450 if (region->whole_file()) {
1451 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1452 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1454 sfp->set_length (region->length());
1464 catch (failed_constructor& err) {
1465 return boost::shared_ptr<AudioRegion>();
1470 Session::get_sources_as_xml ()
1473 XMLNode* node = new XMLNode (X_("Sources"));
1474 Glib::Mutex::Lock lm (audio_source_lock);
1476 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1477 node->add_child_nocopy (i->second->get_state());
1480 /* XXX get MIDI and other sources here */
1486 Session::path_from_region_name (string name, string identifier)
1488 char buf[PATH_MAX+1];
1490 string dir = discover_best_sound_dir ();
1492 for (n = 0; n < 999999; ++n) {
1493 if (identifier.length()) {
1494 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1495 identifier.c_str(), n);
1497 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1500 if (!g_file_test (buf, G_FILE_TEST_EXISTS)) {
1505 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1514 Session::load_sources (const XMLNode& node)
1517 XMLNodeConstIterator niter;
1518 boost::shared_ptr<Source> source;
1520 nlist = node.children();
1524 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1527 if ((source = XMLSourceFactory (**niter)) == 0) {
1528 error << _("Session: cannot create Source from XML description.") << endmsg;
1532 catch (non_existent_source& err) {
1533 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1534 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1541 boost::shared_ptr<Source>
1542 Session::XMLSourceFactory (const XMLNode& node)
1544 if (node.name() != "Source") {
1545 return boost::shared_ptr<Source>();
1549 return SourceFactory::create (*this, node);
1552 catch (failed_constructor& err) {
1553 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1554 return boost::shared_ptr<Source>();
1559 Session::save_template (string template_name)
1562 string xml_path, bak_path, template_path;
1564 if (_state_of_the_state & CannotSave) {
1569 string dir = template_dir();
1571 if ((dp = opendir (dir.c_str()))) {
1574 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1575 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1580 tree.set_root (&get_template());
1583 xml_path += template_name;
1584 xml_path += _template_suffix;
1586 ifstream in(xml_path.c_str());
1589 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1595 if (!tree.write (xml_path)) {
1596 error << _("mix template not saved") << endmsg;
1604 Session::rename_template (string old_name, string new_name)
1606 string old_path = template_dir() + old_name + _template_suffix;
1607 string new_path = template_dir() + new_name + _template_suffix;
1609 return rename (old_path.c_str(), new_path.c_str());
1613 Session::delete_template (string name)
1615 string template_path = template_dir();
1616 template_path += name;
1617 template_path += _template_suffix;
1619 return remove (template_path.c_str());
1623 Session::refresh_disk_space ()
1626 struct statfs statfsbuf;
1627 vector<space_and_path>::iterator i;
1628 Glib::Mutex::Lock lm (space_lock);
1631 /* get freespace on every FS that is part of the session path */
1633 _total_free_4k_blocks = 0;
1635 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1636 statfs ((*i).path.c_str(), &statfsbuf);
1638 scale = statfsbuf.f_bsize/4096.0;
1640 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1641 _total_free_4k_blocks += (*i).blocks;
1647 Session::ensure_sound_dir (string path, string& result)
1652 /* Ensure that the parent directory exists */
1654 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1655 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1659 /* Ensure that the sounds directory exists */
1663 result += sound_dir_name;
1665 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1666 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1672 dead += dead_sound_dir_name;
1674 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1675 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1681 peak += peak_dir_name;
1683 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1684 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1688 /* callers expect this to be terminated ... */
1695 Session::discover_best_sound_dir (bool destructive)
1697 vector<space_and_path>::iterator i;
1700 /* handle common case without system calls */
1702 if (session_dirs.size() == 1) {
1706 /* OK, here's the algorithm we're following here:
1708 We want to select which directory to use for
1709 the next file source to be created. Ideally,
1710 we'd like to use a round-robin process so as to
1711 get maximum performance benefits from splitting
1712 the files across multiple disks.
1714 However, in situations without much diskspace, an
1715 RR approach may end up filling up a filesystem
1716 with new files while others still have space.
1717 Its therefore important to pay some attention to
1718 the freespace in the filesystem holding each
1719 directory as well. However, if we did that by
1720 itself, we'd keep creating new files in the file
1721 system with the most space until it was as full
1722 as all others, thus negating any performance
1723 benefits of this RAID-1 like approach.
1725 So, we use a user-configurable space threshold. If
1726 there are at least 2 filesystems with more than this
1727 much space available, we use RR selection between them.
1728 If not, then we pick the filesystem with the most space.
1730 This gets a good balance between the two
1734 refresh_disk_space ();
1736 int free_enough = 0;
1738 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1739 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1744 if (free_enough >= 2) {
1746 bool found_it = false;
1748 /* use RR selection process, ensuring that the one
1752 i = last_rr_session_dir;
1755 if (++i == session_dirs.end()) {
1756 i = session_dirs.begin();
1759 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1760 if (ensure_sound_dir ((*i).path, result) == 0) {
1761 last_rr_session_dir = i;
1767 } while (i != last_rr_session_dir);
1770 result = sound_dir();
1775 /* pick FS with the most freespace (and that
1776 seems to actually work ...)
1779 vector<space_and_path> sorted;
1780 space_and_path_ascending_cmp cmp;
1782 sorted = session_dirs;
1783 sort (sorted.begin(), sorted.end(), cmp);
1785 for (i = sorted.begin(); i != sorted.end(); ++i) {
1786 if (ensure_sound_dir ((*i).path, result) == 0) {
1787 last_rr_session_dir = i;
1792 /* if the above fails, fall back to the most simplistic solution */
1794 if (i == sorted.end()) {
1803 Session::load_playlists (const XMLNode& node)
1806 XMLNodeConstIterator niter;
1807 boost::shared_ptr<Playlist> playlist;
1809 nlist = node.children();
1813 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1815 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1816 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1824 Session::load_unused_playlists (const XMLNode& node)
1827 XMLNodeConstIterator niter;
1828 boost::shared_ptr<Playlist> playlist;
1830 nlist = node.children();
1834 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1836 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1837 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1841 // now manually untrack it
1843 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1850 boost::shared_ptr<Playlist>
1851 Session::XMLPlaylistFactory (const XMLNode& node)
1854 return PlaylistFactory::create (*this, node);
1857 catch (failed_constructor& err) {
1858 return boost::shared_ptr<Playlist>();
1863 Session::load_named_selections (const XMLNode& node)
1866 XMLNodeConstIterator niter;
1869 nlist = node.children();
1873 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1875 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1876 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1884 Session::XMLNamedSelectionFactory (const XMLNode& node)
1887 return new NamedSelection (*this, node);
1890 catch (failed_constructor& err) {
1896 Session::dead_sound_dir () const
1899 res += dead_sound_dir_name;
1905 Session::old_sound_dir (bool with_path) const
1913 res += old_sound_dir_name;
1919 Session::sound_dir (bool with_path) const
1930 res += interchange_dir_name;
1932 res += legalize_for_path (_name);
1934 res += sound_dir_name;
1942 /* if this already exists, don't check for the old session sound directory */
1944 if (Glib::file_test (full, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
1948 /* possibly support old session structure */
1951 string old_withpath;
1953 old_nopath += old_sound_dir_name;
1956 old_withpath = _path;
1957 old_withpath += old_sound_dir_name;
1959 if (Glib::file_test (old_withpath.c_str(), Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
1961 return old_withpath;
1966 /* ok, old "sounds" directory isn't there, return the new path */
1972 Session::peak_dir () const
1975 res += peak_dir_name;
1981 Session::automation_dir () const
1984 res += "automation/";
1989 Session::template_dir ()
1991 string path = get_user_ardour_path();
1992 path += "templates/";
1998 Session::export_dir () const
2001 res += export_dir_name;
2007 Session::suffixed_search_path (string suffix, bool data)
2011 path += get_user_ardour_path();
2012 if (path[path.length()-1] != ':') {
2017 path += get_system_data_path();
2019 path += get_system_module_path();
2022 vector<string> split_path;
2024 split (path, split_path, ':');
2027 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2032 if (distance (i, split_path.end()) != 1) {
2041 Session::template_path ()
2043 return suffixed_search_path (X_("templates"), true);
2047 Session::control_protocol_path ()
2049 return suffixed_search_path (X_("surfaces"), false);
2053 Session::load_connections (const XMLNode& node)
2055 XMLNodeList nlist = node.children();
2056 XMLNodeConstIterator niter;
2060 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2061 if ((*niter)->name() == "InputConnection") {
2062 add_connection (new ARDOUR::InputConnection (**niter));
2063 } else if ((*niter)->name() == "OutputConnection") {
2064 add_connection (new ARDOUR::OutputConnection (**niter));
2066 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2075 Session::load_edit_groups (const XMLNode& node)
2077 return load_route_groups (node, true);
2081 Session::load_mix_groups (const XMLNode& node)
2083 return load_route_groups (node, false);
2087 Session::load_route_groups (const XMLNode& node, bool edit)
2089 XMLNodeList nlist = node.children();
2090 XMLNodeConstIterator niter;
2095 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2096 if ((*niter)->name() == "RouteGroup") {
2098 rg = add_edit_group ("");
2099 rg->set_state (**niter);
2101 rg = add_mix_group ("");
2102 rg->set_state (**niter);
2111 state_file_filter (const string &str, void *arg)
2113 return (str.length() > strlen(Session::statefile_suffix()) &&
2114 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2118 bool operator()(const string* a, const string* b) {
2124 remove_end(string* state)
2126 string statename(*state);
2128 string::size_type start,end;
2129 if ((start = statename.find_last_of ('/')) != string::npos) {
2130 statename = statename.substr (start+1);
2133 if ((end = statename.rfind(".ardour")) == string::npos) {
2134 end = statename.length();
2137 return new string(statename.substr (0, end));
2141 Session::possible_states (string path)
2143 PathScanner scanner;
2144 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2146 transform(states->begin(), states->end(), states->begin(), remove_end);
2149 sort (states->begin(), states->end(), cmp);
2155 Session::possible_states () const
2157 return possible_states(_path);
2161 Session::auto_save()
2163 save_state (_current_snapshot_name);
2167 Session::add_edit_group (string name)
2169 RouteGroup* rg = new RouteGroup (*this, name);
2170 edit_groups.push_back (rg);
2171 edit_group_added (rg); /* EMIT SIGNAL */
2177 Session::add_mix_group (string name)
2179 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2180 mix_groups.push_back (rg);
2181 mix_group_added (rg); /* EMIT SIGNAL */
2187 Session::remove_edit_group (RouteGroup& rg)
2189 list<RouteGroup*>::iterator i;
2191 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2192 (*i)->apply (&Route::drop_edit_group, this);
2193 edit_groups.erase (i);
2194 edit_group_removed (); /* EMIT SIGNAL */
2201 Session::remove_mix_group (RouteGroup& rg)
2203 list<RouteGroup*>::iterator i;
2205 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2206 (*i)->apply (&Route::drop_mix_group, this);
2207 mix_groups.erase (i);
2208 mix_group_removed (); /* EMIT SIGNAL */
2215 Session::mix_group_by_name (string name)
2217 list<RouteGroup *>::iterator i;
2219 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2220 if ((*i)->name() == name) {
2228 Session::edit_group_by_name (string name)
2230 list<RouteGroup *>::iterator i;
2232 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2233 if ((*i)->name() == name) {
2241 Session::begin_reversible_command (string name)
2243 current_trans = new UndoTransaction;
2244 current_trans->set_name (name);
2248 Session::commit_reversible_command (Command *cmd)
2253 current_trans->add_command (cmd);
2256 gettimeofday (&now, 0);
2257 current_trans->set_timestamp (now);
2259 _history.add (current_trans);
2262 Session::GlobalRouteBooleanState
2263 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2265 GlobalRouteBooleanState s;
2266 boost::shared_ptr<RouteList> r = routes.reader ();
2268 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2269 if (!(*i)->hidden()) {
2270 RouteBooleanState v;
2273 Route* r = (*i).get();
2274 v.second = (r->*method)();
2283 Session::GlobalRouteMeterState
2284 Session::get_global_route_metering ()
2286 GlobalRouteMeterState s;
2287 boost::shared_ptr<RouteList> r = routes.reader ();
2289 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2290 if (!(*i)->hidden()) {
2294 v.second = (*i)->meter_point();
2304 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2306 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2308 boost::shared_ptr<Route> r = (i->first.lock());
2311 r->set_meter_point (i->second, arg);
2317 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2319 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2321 boost::shared_ptr<Route> r = (i->first.lock());
2324 Route* rp = r.get();
2325 (rp->*method) (i->second, arg);
2331 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2333 set_global_route_boolean (s, &Route::set_mute, src);
2337 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2339 set_global_route_boolean (s, &Route::set_solo, src);
2343 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2345 set_global_route_boolean (s, &Route::set_record_enable, src);
2350 Session::global_mute_memento (void* src)
2352 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2356 Session::global_metering_memento (void* src)
2358 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2362 Session::global_solo_memento (void* src)
2364 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2368 Session::global_record_enable_memento (void* src)
2370 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2375 template_filter (const string &str, void *arg)
2377 return (str.length() > strlen(Session::template_suffix()) &&
2378 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2382 Session::get_template_list (list<string> &template_names)
2384 vector<string *> *templates;
2385 PathScanner scanner;
2388 path = template_path ();
2390 templates = scanner (path, template_filter, 0, false, true);
2392 vector<string*>::iterator i;
2393 for (i = templates->begin(); i != templates->end(); ++i) {
2394 string fullpath = *(*i);
2397 start = fullpath.find_last_of ('/') + 1;
2398 if ((end = fullpath.find_last_of ('.')) <0) {
2399 end = fullpath.length();
2402 template_names.push_back(fullpath.substr(start, (end-start)));
2407 Session::read_favorite_dirs (FavoriteDirs & favs)
2409 string path = get_user_ardour_path();
2410 path += "/favorite_dirs";
2412 ifstream fav (path.c_str());
2417 if (errno != ENOENT) {
2418 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2429 getline(fav, newfav);
2435 favs.push_back (newfav);
2442 Session::write_favorite_dirs (FavoriteDirs & favs)
2444 string path = get_user_ardour_path();
2445 path += "/favorite_dirs";
2447 ofstream fav (path.c_str());
2453 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2454 fav << (*i) << endl;
2461 accept_all_non_peak_files (const string& path, void *arg)
2463 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2467 accept_all_state_files (const string& path, void *arg)
2469 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2473 Session::find_all_sources (string path, set<string>& result)
2478 if (!tree.read (path)) {
2482 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2487 XMLNodeConstIterator niter;
2489 nlist = node->children();
2493 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2497 if ((prop = (*niter)->property (X_("name"))) == 0) {
2501 if (prop->value()[0] == '/') {
2502 /* external file, ignore */
2506 string path = _path; /* /-terminated */
2507 path += sound_dir_name;
2509 path += prop->value();
2511 result.insert (path);
2518 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2520 PathScanner scanner;
2521 vector<string*>* state_files;
2523 string this_snapshot_path;
2529 if (ripped[ripped.length()-1] == '/') {
2530 ripped = ripped.substr (0, ripped.length() - 1);
2533 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2535 if (state_files == 0) {
2540 this_snapshot_path = _path;
2541 this_snapshot_path += _current_snapshot_name;
2542 this_snapshot_path += _statefile_suffix;
2544 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2546 if (exclude_this_snapshot && **i == this_snapshot_path) {
2550 if (find_all_sources (**i, result) < 0) {
2558 struct RegionCounter {
2559 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2560 AudioSourceList::iterator iter;
2561 boost::shared_ptr<Region> region;
2564 RegionCounter() : count (0) {}
2568 Session::cleanup_sources (Session::cleanup_report& rep)
2570 vector<boost::shared_ptr<Source> > dead_sources;
2571 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2572 PathScanner scanner;
2574 vector<space_and_path>::iterator i;
2575 vector<space_and_path>::iterator nexti;
2576 vector<string*>* soundfiles;
2577 vector<string> unused;
2578 set<string> all_sources;
2583 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2585 /* step 1: consider deleting all unused playlists */
2587 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2590 status = AskAboutPlaylistDeletion (*x);
2599 playlists_tbd.push_back (*x);
2603 /* leave it alone */
2608 /* now delete any that were marked for deletion */
2610 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2611 (*x)->drop_references ();
2614 playlists_tbd.clear ();
2616 /* step 2: find all un-used sources */
2621 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2623 AudioSourceList::iterator tmp;
2628 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2632 if (!i->second->used() && i->second->length() > 0) {
2633 dead_sources.push_back (i->second);
2634 i->second->GoingAway();
2640 /* build a list of all the possible sound directories for the session */
2642 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2647 sound_path += (*i).path;
2648 sound_path += sound_dir (false);
2650 if (nexti != session_dirs.end()) {
2657 /* now do the same thing for the files that ended up in the sounds dir(s)
2658 but are not referenced as sources in any snapshot.
2661 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2663 if (soundfiles == 0) {
2667 /* find all sources, but don't use this snapshot because the
2668 state file on disk still references sources we may have already
2672 find_all_sources_across_snapshots (all_sources, true);
2674 /* add our current source list
2677 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2678 boost::shared_ptr<AudioFileSource> fs;
2680 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2681 all_sources.insert (fs->path());
2685 char tmppath1[PATH_MAX+1];
2686 char tmppath2[PATH_MAX+1];
2688 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2693 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2695 realpath(spath.c_str(), tmppath1);
2696 realpath((*i).c_str(), tmppath2);
2698 if (strcmp(tmppath1, tmppath2) == 0) {
2705 unused.push_back (spath);
2709 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2711 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2712 struct stat statbuf;
2714 rep.paths.push_back (*x);
2715 if (stat ((*x).c_str(), &statbuf) == 0) {
2716 rep.space += statbuf.st_size;
2721 /* don't move the file across filesystems, just
2722 stick it in the `dead_sound_dir_name' directory
2723 on whichever filesystem it was already on.
2726 if ((*x).find ("/sounds/") != string::npos) {
2728 /* old school, go up 1 level */
2730 newpath = Glib::path_get_dirname (*x); // "sounds"
2731 newpath = Glib::path_get_dirname (newpath); // "session-name"
2735 /* new school, go up 4 levels */
2737 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2738 newpath = Glib::path_get_dirname (newpath); // "session-name"
2739 newpath = Glib::path_get_dirname (newpath); // "interchange"
2740 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2744 newpath += dead_sound_dir_name;
2746 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2747 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2752 newpath += Glib::path_get_basename ((*x));
2754 if (access (newpath.c_str(), F_OK) == 0) {
2756 /* the new path already exists, try versioning */
2758 char buf[PATH_MAX+1];
2762 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2765 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2766 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2770 if (version == 999) {
2771 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2775 newpath = newpath_v;
2780 /* it doesn't exist, or we can't read it or something */
2784 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2785 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2786 (*x), newpath, strerror (errno))
2791 /* see if there an easy to find peakfile for this file, and remove it.
2794 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2795 peakpath += ".peak";
2797 if (access (peakpath.c_str(), W_OK) == 0) {
2798 if (::unlink (peakpath.c_str()) != 0) {
2799 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2800 peakpath, _path, strerror (errno))
2802 /* try to back out */
2803 rename (newpath.c_str(), _path.c_str());
2811 /* dump the history list */
2815 /* save state so we don't end up a session file
2816 referring to non-existent sources.
2822 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2827 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2829 vector<space_and_path>::iterator i;
2830 string dead_sound_dir;
2831 struct dirent* dentry;
2832 struct stat statbuf;
2838 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2840 dead_sound_dir = (*i).path;
2841 dead_sound_dir += dead_sound_dir_name;
2843 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2847 while ((dentry = readdir (dead)) != 0) {
2849 /* avoid '.' and '..' */
2851 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2852 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2858 fullpath = dead_sound_dir;
2860 fullpath += dentry->d_name;
2862 if (stat (fullpath.c_str(), &statbuf)) {
2866 if (!S_ISREG (statbuf.st_mode)) {
2870 if (unlink (fullpath.c_str())) {
2871 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2872 fullpath, strerror (errno))
2876 rep.paths.push_back (dentry->d_name);
2877 rep.space += statbuf.st_size;
2888 Session::set_dirty ()
2890 bool was_dirty = dirty();
2892 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2895 DirtyChanged(); /* EMIT SIGNAL */
2901 Session::set_clean ()
2903 bool was_dirty = dirty();
2905 _state_of_the_state = Clean;
2908 DirtyChanged(); /* EMIT SIGNAL */
2913 Session::set_deletion_in_progress ()
2915 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2919 Session::add_controllable (Controllable* c)
2921 /* this adds a controllable to the list managed by the Session.
2922 this is a subset of those managed by the Controllable class
2923 itself, and represents the only ones whose state will be saved
2924 as part of the session.
2927 Glib::Mutex::Lock lm (controllables_lock);
2928 controllables.insert (c);
2932 Session::remove_controllable (Controllable* c)
2934 if (_state_of_the_state | Deletion) {
2938 Glib::Mutex::Lock lm (controllables_lock);
2940 Controllables::iterator x = controllables.find (c);
2942 if (x != controllables.end()) {
2943 controllables.erase (x);
2948 Session::controllable_by_id (const PBD::ID& id)
2950 Glib::Mutex::Lock lm (controllables_lock);
2952 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2953 if ((*i)->id() == id) {
2962 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2964 Stateful::add_instant_xml (node, dir);
2965 Config->add_instant_xml (node, get_user_ardour_path());
2970 Session::save_history (string snapshot_name)
2976 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2978 if (snapshot_name.empty()) {
2979 snapshot_name = _current_snapshot_name;
2982 xml_path = _path + snapshot_name + ".history";
2984 bak_path = xml_path + ".bak";
2986 if ((access (xml_path.c_str(), F_OK) == 0) &&
2987 (rename (xml_path.c_str(), bak_path.c_str())))
2989 error << _("could not backup old history file, current history not saved.") << endmsg;
2993 if (!tree.write (xml_path))
2995 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2997 /* don't leave a corrupt file lying around if it is
3001 if (unlink (xml_path.c_str())) {
3002 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
3004 if (rename (bak_path.c_str(), xml_path.c_str()))
3006 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
3017 Session::restore_history (string snapshot_name)
3022 if (snapshot_name.empty()) {
3023 snapshot_name = _current_snapshot_name;
3027 xmlpath = _path + snapshot_name + ".history";
3028 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
3030 if (access (xmlpath.c_str(), F_OK)) {
3031 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
3035 if (!tree.read (xmlpath)) {
3036 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
3040 /* replace history */
3043 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3046 UndoTransaction* ut = new UndoTransaction ();
3049 ut->set_name(t->property("name")->value());
3050 stringstream ss(t->property("tv_sec")->value());
3052 ss.str(t->property("tv_usec")->value());
3054 ut->set_timestamp(tv);
3056 for (XMLNodeConstIterator child_it = t->children().begin();
3057 child_it != t->children().end();
3060 XMLNode *n = *child_it;
3063 if (n->name() == "MementoCommand" ||
3064 n->name() == "MementoUndoCommand" ||
3065 n->name() == "MementoRedoCommand") {
3067 if ((c = memento_command_factory(n))) {
3071 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3073 if ((c = global_state_command_factory (*n))) {
3074 ut->add_command (c);
3079 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3090 Session::config_changed (const char* parameter_name)
3092 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3094 if (PARAM_IS ("seamless-loop")) {
3096 } else if (PARAM_IS ("rf-speed")) {
3098 } else if (PARAM_IS ("auto-loop")) {
3100 } else if (PARAM_IS ("auto-input")) {
3102 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3103 /* auto-input only makes a difference if we're rolling */
3105 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3107 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3108 if ((*i)->record_enabled ()) {
3109 (*i)->monitor_input (!Config->get_auto_input());
3114 } else if (PARAM_IS ("punch-in")) {
3118 if ((location = _locations.auto_punch_location()) != 0) {
3120 if (Config->get_punch_in ()) {
3121 replace_event (Event::PunchIn, location->start());
3123 remove_event (location->start(), Event::PunchIn);
3127 } else if (PARAM_IS ("punch-out")) {
3131 if ((location = _locations.auto_punch_location()) != 0) {
3133 if (Config->get_punch_out()) {
3134 replace_event (Event::PunchOut, location->end());
3136 clear_events (Event::PunchOut);
3140 } else if (PARAM_IS ("edit-mode")) {
3142 Glib::Mutex::Lock lm (playlist_lock);
3144 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3145 (*i)->set_edit_mode (Config->get_edit_mode ());
3148 } else if (PARAM_IS ("use-video-sync")) {
3150 if (transport_stopped()) {
3151 if (Config->get_use_video_sync()) {
3152 waiting_for_sync_offset = true;
3156 } else if (PARAM_IS ("mmc-control")) {
3158 poke_midi_thread ();
3160 } else if (PARAM_IS ("mmc-device-id")) {
3163 mmc->set_device_id (Config->get_mmc_device_id());
3166 } else if (PARAM_IS ("midi-control")) {
3168 poke_midi_thread ();
3170 } else if (PARAM_IS ("raid-path")) {
3172 setup_raid_path (Config->get_raid_path());
3174 } else if (PARAM_IS ("smpte-format")) {
3178 } else if (PARAM_IS ("video-pullup")) {
3182 } else if (PARAM_IS ("seamless-loop")) {
3184 if (play_loop && transport_rolling()) {
3185 // to reset diskstreams etc
3186 request_play_loop (true);
3189 } else if (PARAM_IS ("rf-speed")) {
3191 cumulative_rf_motion = 0;
3194 } else if (PARAM_IS ("click-sound")) {
3196 setup_click_sounds (1);
3198 } else if (PARAM_IS ("click-emphasis-sound")) {
3200 setup_click_sounds (-1);
3202 } else if (PARAM_IS ("clicking")) {
3204 if (Config->get_clicking()) {
3205 if (_click_io && click_data) { // don't require emphasis data
3212 } else if (PARAM_IS ("send-mtc")) {
3214 /* only set the internal flag if we have
3218 if (_mtc_port != 0) {
3219 session_send_mtc = Config->get_send_mtc();
3220 if (session_send_mtc) {
3221 /* mark us ready to send */
3222 next_quarter_frame_to_send = 0;
3225 session_send_mtc = false;
3228 } else if (PARAM_IS ("send-mmc")) {
3230 /* only set the internal flag if we have
3234 if (_mmc_port != 0) {
3235 session_send_mmc = Config->get_send_mmc();
3238 session_send_mmc = false;
3241 } else if (PARAM_IS ("midi-feedback")) {
3243 /* only set the internal flag if we have
3247 if (_mtc_port != 0) {
3248 session_midi_feedback = Config->get_midi_feedback();
3251 } else if (PARAM_IS ("jack-time-master")) {
3253 engine().reset_timebase ();
3255 } else if (PARAM_IS ("native-file-header-format")) {
3257 if (!first_file_header_format_reset) {
3258 reset_native_file_format ();
3261 first_file_header_format_reset = false;
3263 } else if (PARAM_IS ("native-file-data-format")) {
3265 if (!first_file_data_format_reset) {
3266 reset_native_file_format ();
3269 first_file_data_format_reset = false;
3271 } else if (PARAM_IS ("slave-source")) {
3272 set_slave_source (Config->get_slave_source());
3273 } else if (PARAM_IS ("remote-model")) {
3274 set_remote_control_ids ();