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.
26 #include <sigc++/bind.h>
28 #include <cstdio> /* snprintf(3) ... grrr */
43 #include <sys/param.h>
44 #include <sys/mount.h>
49 #include <midi++/mmc.h>
50 #include <midi++/port.h>
51 #include <pbd/error.h>
53 #include <glibmm/thread.h>
54 #include <pbd/pathscanner.h>
55 #include <pbd/pthread_utils.h>
56 #include <pbd/strsplit.h>
57 #include <pbd/stacktrace.h>
58 #include <pbd/copyfile.h>
60 #include <ardour/audioengine.h>
61 #include <ardour/configuration.h>
62 #include <ardour/session.h>
63 #include <ardour/audio_diskstream.h>
64 #include <ardour/utils.h>
65 #include <ardour/audioplaylist.h>
66 #include <ardour/audiofilesource.h>
67 #include <ardour/silentfilesource.h>
68 #include <ardour/sndfilesource.h>
69 #include <ardour/sndfile_helpers.h>
70 #include <ardour/auditioner.h>
71 #include <ardour/export.h>
72 #include <ardour/redirect.h>
73 #include <ardour/send.h>
74 #include <ardour/insert.h>
75 #include <ardour/connection.h>
76 #include <ardour/slave.h>
77 #include <ardour/tempo.h>
78 #include <ardour/audio_track.h>
79 #include <ardour/cycle_timer.h>
80 #include <ardour/utils.h>
81 #include <ardour/named_selection.h>
82 #include <ardour/version.h>
83 #include <ardour/location.h>
84 #include <ardour/audioregion.h>
85 #include <ardour/crossfade.h>
86 #include <ardour/control_protocol_manager.h>
87 #include <ardour/region_factory.h>
88 #include <ardour/source_factory.h>
89 #include <ardour/playlist_factory.h>
91 #include <control_protocol/control_protocol.h>
97 using namespace ARDOUR;
101 Session::first_stage_init (string fullpath, string snapshot_name)
103 if (fullpath.length() == 0) {
105 throw failed_constructor();
108 char buf[PATH_MAX+1];
109 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
110 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
112 throw failed_constructor();
117 if (_path[_path.length()-1] != '/') {
121 /* these two are just provisional settings. set_state()
122 will likely override them.
125 _name = _current_snapshot_name = snapshot_name;
127 _current_frame_rate = _engine.frame_rate ();
128 _tempo_map = new TempoMap (_current_frame_rate);
129 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
131 g_atomic_int_set (&processing_prohibited, 0);
133 _transport_speed = 0;
134 _last_transport_speed = 0;
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;
188 AudioDiskstream::allocate_working_buffers();
190 /* default short fade = 15ms */
192 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
193 SndFileSource::setup_standard_crossfades (frame_rate());
195 last_mmc_step.tv_sec = 0;
196 last_mmc_step.tv_usec = 0;
199 /* click sounds are unset by default, which causes us to internal
200 waveforms for clicks.
204 click_emphasis_data = 0;
206 click_emphasis_length = 0;
209 process_function = &Session::process_with_events;
211 if (Config->get_use_video_sync()) {
212 waiting_for_sync_offset = true;
214 waiting_for_sync_offset = false;
217 _current_frame_rate = 48000;
218 _base_frame_rate = 48000;
222 _smpte_offset_negative = true;
223 last_smpte_valid = false;
227 last_rr_session_dir = session_dirs.begin();
228 refresh_disk_space ();
230 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
234 average_slave_delta = 1800;
235 have_first_delta_accumulator = false;
236 delta_accumulator_cnt = 0;
237 slave_state = Stopped;
239 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
241 /* These are all static "per-class" signals */
243 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
244 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
245 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
246 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
247 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
248 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
250 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
252 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
254 /* stop IO objects from doing stuff until we're ready for them */
256 IO::disable_panners ();
257 IO::disable_ports ();
258 IO::disable_connecting ();
262 Session::second_stage_init (bool new_session)
264 AudioFileSource::set_peak_dir (peak_dir());
267 if (load_state (_current_snapshot_name)) {
270 remove_empty_sounds ();
273 if (start_butler_thread()) {
277 if (start_midi_thread ()) {
281 // set_state() will call setup_raid_path(), but if it's a new session we need
282 // to call setup_raid_path() here.
284 if (set_state (*state_tree->root())) {
288 setup_raid_path(_path);
291 /* we can't save till after ::when_engine_running() is called,
292 because otherwise we save state with no connections made.
293 therefore, we reset _state_of_the_state because ::set_state()
294 will have cleared it.
296 we also have to include Loading so that any events that get
297 generated between here and the end of ::when_engine_running()
298 will be processed directly rather than queued.
301 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
303 // set_auto_input (true);
304 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
305 _locations.added.connect (mem_fun (this, &Session::locations_added));
306 setup_click_sounds (0);
307 setup_midi_control ();
309 /* Pay attention ... */
311 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
312 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
315 when_engine_running();
318 /* handle this one in a different way than all others, so that its clear what happened */
320 catch (AudioEngine::PortRegistrationFailure& err) {
321 error << _("Unable to create all required ports")
330 send_full_time_code ();
331 _engine.transport_locate (0);
332 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
333 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
335 ControlProtocolManager::instance().set_session (*this);
338 _end_location_is_free = true;
340 _end_location_is_free = false;
347 Session::raid_path () const
351 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
356 return path.substr (0, path.length() - 1); // drop final colon
360 Session::setup_raid_path (string path)
362 string::size_type colon;
366 string::size_type len = path.length();
371 if (path.length() == 0) {
375 session_dirs.clear ();
377 for (string::size_type n = 0; n < len; ++n) {
378 if (path[n] == ':') {
385 /* no multiple search path, just one location (common case) */
389 session_dirs.push_back (sp);
396 if (fspath[fspath.length()-1] != '/') {
400 fspath += sound_dir (false);
402 AudioFileSource::set_search_path (fspath);
409 while ((colon = remaining.find_first_of (':')) != string::npos) {
412 sp.path = remaining.substr (0, colon);
413 session_dirs.push_back (sp);
415 /* add sounds to file search path */
418 if (fspath[fspath.length()-1] != '/') {
421 fspath += sound_dir (false);
424 remaining = remaining.substr (colon+1);
427 if (remaining.length()) {
434 if (fspath[fspath.length()-1] != '/') {
437 fspath += sound_dir (false);
440 session_dirs.push_back (sp);
443 /* set the AudioFileSource search path */
445 AudioFileSource::set_search_path (fspath);
447 /* reset the round-robin soundfile path thingie */
449 last_rr_session_dir = session_dirs.begin();
453 Session::create (bool& new_session, string* mix_template, nframes_t initial_length)
457 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
458 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
464 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
465 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
471 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
472 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
476 dir = dead_sound_dir ();
478 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
479 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
483 dir = automation_dir ();
485 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
486 error << string_compose(_("Session: cannot create session automation 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());
590 Session::save_state (string snapshot_name, bool pending)
596 if (_state_of_the_state & CannotSave) {
600 if (!_engine.connected ()) {
601 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
606 tree.set_root (&get_state());
608 if (snapshot_name.empty()) {
609 snapshot_name = _current_snapshot_name;
615 xml_path += snapshot_name;
616 xml_path += _statefile_suffix;
621 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
622 copy_file (xml_path, bak_path);
628 xml_path += snapshot_name;
629 xml_path += _pending_suffix;
636 tmp_path += snapshot_name;
639 cerr << "actually writing state\n";
641 if (!tree.write (tmp_path)) {
642 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
643 unlink (tmp_path.c_str());
648 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
649 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
650 unlink (tmp_path.c_str());
657 save_history (snapshot_name);
659 bool was_dirty = dirty();
661 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
664 DirtyChanged (); /* EMIT SIGNAL */
667 StateSaved (snapshot_name); /* EMIT SIGNAL */
674 Session::restore_state (string snapshot_name)
676 if (load_state (snapshot_name) == 0) {
677 set_state (*state_tree->root());
684 Session::load_state (string snapshot_name)
693 state_was_pending = false;
695 /* check for leftover pending state from a crashed capture attempt */
698 xmlpath += snapshot_name;
699 xmlpath += _pending_suffix;
701 if (!access (xmlpath.c_str(), F_OK)) {
703 /* there is pending state from a crashed capture attempt */
705 if (AskAboutPendingState()) {
706 state_was_pending = true;
710 if (!state_was_pending) {
713 xmlpath += snapshot_name;
714 xmlpath += _statefile_suffix;
717 if (access (xmlpath.c_str(), F_OK)) {
718 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
722 state_tree = new XMLTree;
726 if (!state_tree->read (xmlpath)) {
727 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
733 XMLNode& root (*state_tree->root());
735 if (root.name() != X_("Session")) {
736 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
742 const XMLProperty* prop;
745 if ((prop = root.property ("version")) == 0) {
746 /* no version implies very old version of Ardour */
750 major_version = atoi (prop->value()); // grab just the first number before the period
751 if (major_version < 2) {
759 backup_path = xmlpath;
762 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
763 xmlpath, backup_path)
766 copy_file (xmlpath, backup_path);
768 /* if it fails, don't worry. right? */
775 Session::load_options (const XMLNode& node)
779 LocaleGuard lg (X_("POSIX"));
781 Config->set_variables (node, ConfigVariableBase::Session);
783 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
784 if ((prop = child->property ("val")) != 0) {
785 _end_location_is_free = (prop->value() == "yes");
793 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
795 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
796 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
798 return owner & modified_by_session_or_user;
802 Session::get_options () const
805 LocaleGuard lg (X_("POSIX"));
807 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
809 child = option_root.add_child ("end-marker-is-free");
810 child->add_property ("val", _end_location_is_free ? "yes" : "no");
822 Session::get_template()
824 /* if we don't disable rec-enable, diskstreams
825 will believe they need to store their capture
826 sources in their state node.
829 disable_record (false);
835 Session::state(bool full_state)
837 XMLNode* node = new XMLNode("Session");
840 // store libardour version, just in case
842 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
843 libardour_major_version, libardour_minor_version, libardour_micro_version);
844 node->add_property("version", string(buf));
846 /* store configuration settings */
851 node->add_property ("name", _name);
853 if (session_dirs.size() > 1) {
857 vector<space_and_path>::iterator i = session_dirs.begin();
858 vector<space_and_path>::iterator next;
860 ++i; /* skip the first one */
864 while (i != session_dirs.end()) {
868 if (next != session_dirs.end()) {
878 child = node->add_child ("Path");
879 child->add_content (p);
883 /* save the ID counter */
885 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
886 node->add_property ("id-counter", buf);
888 /* various options */
890 node->add_child_nocopy (get_options());
892 child = node->add_child ("Sources");
895 Glib::Mutex::Lock sl (audio_source_lock);
897 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
899 /* Don't save information about AudioFileSources that are empty */
901 boost::shared_ptr<AudioFileSource> fs;
903 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
905 /* destructive file sources are OK if they are empty, because
906 we will re-use them every time.
909 if (!fs->destructive()) {
910 if (fs->length() == 0) {
916 child->add_child_nocopy (siter->second->get_state());
920 child = node->add_child ("Regions");
923 Glib::Mutex::Lock rl (region_lock);
925 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
927 /* only store regions not attached to playlists */
929 if (i->second->playlist() == 0) {
930 child->add_child_nocopy (i->second->state (true));
935 child = node->add_child ("DiskStreams");
938 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
939 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
940 if (!(*i)->hidden()) {
941 child->add_child_nocopy ((*i)->get_state());
947 node->add_child_nocopy (_locations.get_state());
949 // for a template, just create a new Locations, populate it
950 // with the default start and end, and get the state for that.
952 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
953 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
956 end->set_end(compute_initial_length());
958 node->add_child_nocopy (loc.get_state());
961 child = node->add_child ("Connections");
963 Glib::Mutex::Lock lm (connection_lock);
964 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
965 if (!(*i)->system_dependent()) {
966 child->add_child_nocopy ((*i)->get_state());
971 child = node->add_child ("Routes");
973 boost::shared_ptr<RouteList> r = routes.reader ();
975 RoutePublicOrderSorter cmp;
976 RouteList public_order (*r);
977 public_order.sort (cmp);
979 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
980 if (!(*i)->hidden()) {
982 child->add_child_nocopy ((*i)->get_state());
984 child->add_child_nocopy ((*i)->get_template());
991 child = node->add_child ("EditGroups");
992 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
993 child->add_child_nocopy ((*i)->get_state());
996 child = node->add_child ("MixGroups");
997 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
998 child->add_child_nocopy ((*i)->get_state());
1001 child = node->add_child ("Playlists");
1002 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1003 if (!(*i)->hidden()) {
1004 if (!(*i)->empty()) {
1006 child->add_child_nocopy ((*i)->get_state());
1008 child->add_child_nocopy ((*i)->get_template());
1014 child = node->add_child ("UnusedPlaylists");
1015 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1016 if (!(*i)->hidden()) {
1017 if (!(*i)->empty()) {
1019 child->add_child_nocopy ((*i)->get_state());
1021 child->add_child_nocopy ((*i)->get_template());
1029 child = node->add_child ("Click");
1030 child->add_child_nocopy (_click_io->state (full_state));
1034 child = node->add_child ("NamedSelections");
1035 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1037 child->add_child_nocopy ((*i)->get_state());
1042 node->add_child_nocopy (_tempo_map->get_state());
1044 node->add_child_nocopy (get_control_protocol_state());
1047 node->add_child_copy (*_extra_xml);
1054 Session::get_control_protocol_state ()
1056 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1057 return cpm.get_state();
1061 Session::set_state (const XMLNode& node)
1065 const XMLProperty* prop;
1068 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1070 if (node.name() != X_("Session")){
1071 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1075 if ((prop = node.property ("name")) != 0) {
1076 _name = prop->value ();
1079 setup_raid_path(_path);
1081 if ((prop = node.property (X_("id-counter"))) != 0) {
1083 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1084 ID::init_counter (x);
1086 /* old sessions used a timebased counter, so fake
1087 the startup ID counter based on a standard
1092 ID::init_counter (now);
1096 IO::disable_ports ();
1097 IO::disable_connecting ();
1099 /* Object loading order:
1117 if (use_config_midi_ports ()) {
1120 if ((child = find_named_node (node, "extra")) != 0) {
1121 _extra_xml = new XMLNode (*child);
1124 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1125 load_options (*child);
1126 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1127 load_options (*child);
1129 error << _("Session: XML state has no options section") << endmsg;
1132 if ((child = find_named_node (node, "Locations")) == 0) {
1133 error << _("Session: XML state has no locations section") << endmsg;
1135 } else if (_locations.set_state (*child)) {
1141 if ((location = _locations.auto_loop_location()) != 0) {
1142 set_auto_loop_location (location);
1145 if ((location = _locations.auto_punch_location()) != 0) {
1146 set_auto_punch_location (location);
1149 if ((location = _locations.end_location()) == 0) {
1150 _locations.add (end_location);
1152 delete end_location;
1153 end_location = location;
1156 if ((location = _locations.start_location()) == 0) {
1157 _locations.add (start_location);
1159 delete start_location;
1160 start_location = location;
1163 AudioFileSource::set_header_position_offset (start_location->start());
1165 if ((child = find_named_node (node, "Sources")) == 0) {
1166 error << _("Session: XML state has no sources section") << endmsg;
1168 } else if (load_sources (*child)) {
1172 if ((child = find_named_node (node, "Regions")) == 0) {
1173 error << _("Session: XML state has no Regions section") << endmsg;
1175 } else if (load_regions (*child)) {
1179 if ((child = find_named_node (node, "Playlists")) == 0) {
1180 error << _("Session: XML state has no playlists section") << endmsg;
1182 } else if (load_playlists (*child)) {
1186 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1188 } else if (load_unused_playlists (*child)) {
1192 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1193 if (load_named_selections (*child)) {
1198 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1199 error << _("Session: XML state has no diskstreams section") << endmsg;
1201 } else if (load_diskstreams (*child)) {
1205 if ((child = find_named_node (node, "Connections")) == 0) {
1206 error << _("Session: XML state has no connections section") << endmsg;
1208 } else if (load_connections (*child)) {
1212 if ((child = find_named_node (node, "EditGroups")) == 0) {
1213 error << _("Session: XML state has no edit groups section") << endmsg;
1215 } else if (load_edit_groups (*child)) {
1219 if ((child = find_named_node (node, "MixGroups")) == 0) {
1220 error << _("Session: XML state has no mix groups section") << endmsg;
1222 } else if (load_mix_groups (*child)) {
1226 if ((child = find_named_node (node, "TempoMap")) == 0) {
1227 error << _("Session: XML state has no Tempo Map section") << endmsg;
1229 } else if (_tempo_map->set_state (*child)) {
1233 if ((child = find_named_node (node, "Routes")) == 0) {
1234 error << _("Session: XML state has no routes section") << endmsg;
1236 } else if (load_routes (*child)) {
1240 if ((child = find_named_node (node, "Click")) == 0) {
1241 warning << _("Session: XML state has no click section") << endmsg;
1242 } else if (_click_io) {
1243 _click_io->set_state (*child);
1246 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1247 ControlProtocolManager::instance().set_protocol_states (*child);
1250 /* here beginneth the second phase ... */
1252 StateReady (); /* EMIT SIGNAL */
1254 _state_of_the_state = Clean;
1256 if (state_was_pending) {
1257 save_state (_current_snapshot_name);
1258 remove_pending_capture_state ();
1259 state_was_pending = false;
1269 Session::load_routes (const XMLNode& node)
1272 XMLNodeConstIterator niter;
1273 RouteList new_routes;
1275 nlist = node.children();
1279 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1281 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1284 error << _("Session: cannot create Route from XML description.") << endmsg;
1288 new_routes.push_back (route);
1291 add_routes (new_routes);
1296 boost::shared_ptr<Route>
1297 Session::XMLRouteFactory (const XMLNode& node)
1299 if (node.name() != "Route") {
1300 return boost::shared_ptr<Route> ((Route*) 0);
1303 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1304 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1307 boost::shared_ptr<Route> x (new Route (*this, node));
1313 Session::load_regions (const XMLNode& node)
1316 XMLNodeConstIterator niter;
1317 boost::shared_ptr<AudioRegion> region;
1319 nlist = node.children();
1323 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1324 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1325 error << _("Session: cannot create Region from XML description.") << endmsg;
1332 boost::shared_ptr<AudioRegion>
1333 Session::XMLRegionFactory (const XMLNode& node, bool full)
1335 const XMLProperty* prop;
1336 boost::shared_ptr<Source> source;
1337 boost::shared_ptr<AudioSource> as;
1339 uint32_t nchans = 1;
1342 if (node.name() != X_("Region")) {
1343 return boost::shared_ptr<AudioRegion>();
1346 if ((prop = node.property (X_("channels"))) != 0) {
1347 nchans = atoi (prop->value().c_str());
1351 if ((prop = node.property ("name")) == 0) {
1352 cerr << "no name for this region\n";
1356 if ((prop = node.property (X_("source-0"))) == 0) {
1357 if ((prop = node.property ("source")) == 0) {
1358 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1359 return boost::shared_ptr<AudioRegion>();
1363 PBD::ID s_id (prop->value());
1365 if ((source = source_by_id (s_id)) == 0) {
1366 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1367 return boost::shared_ptr<AudioRegion>();
1370 as = boost::dynamic_pointer_cast<AudioSource>(source);
1372 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1373 return boost::shared_ptr<AudioRegion>();
1376 sources.push_back (as);
1378 /* pickup other channels */
1380 for (uint32_t n=1; n < nchans; ++n) {
1381 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1382 if ((prop = node.property (buf)) != 0) {
1384 PBD::ID id2 (prop->value());
1386 if ((source = source_by_id (id2)) == 0) {
1387 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1388 return boost::shared_ptr<AudioRegion>();
1391 as = boost::dynamic_pointer_cast<AudioSource>(source);
1393 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1394 return boost::shared_ptr<AudioRegion>();
1396 sources.push_back (as);
1401 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1403 /* a final detail: this is the one and only place that we know how long missing files are */
1405 if (region->whole_file()) {
1406 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1407 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1409 sfp->set_length (region->length());
1419 catch (failed_constructor& err) {
1420 return boost::shared_ptr<AudioRegion>();
1425 Session::get_sources_as_xml ()
1428 XMLNode* node = new XMLNode (X_("Sources"));
1429 Glib::Mutex::Lock lm (audio_source_lock);
1431 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1432 node->add_child_nocopy (i->second->get_state());
1435 /* XXX get MIDI and other sources here */
1441 Session::path_from_region_name (string name, string identifier)
1443 char buf[PATH_MAX+1];
1445 string dir = discover_best_sound_dir ();
1447 for (n = 0; n < 999999; ++n) {
1448 if (identifier.length()) {
1449 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1450 identifier.c_str(), n);
1452 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1454 if (access (buf, F_OK) != 0) {
1464 Session::load_sources (const XMLNode& node)
1467 XMLNodeConstIterator niter;
1468 boost::shared_ptr<Source> source;
1470 nlist = node.children();
1474 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1477 if ((source = XMLSourceFactory (**niter)) == 0) {
1478 error << _("Session: cannot create Source from XML description.") << endmsg;
1482 catch (non_existent_source& err) {
1483 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1484 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1491 boost::shared_ptr<Source>
1492 Session::XMLSourceFactory (const XMLNode& node)
1494 if (node.name() != "Source") {
1495 return boost::shared_ptr<Source>();
1499 return SourceFactory::create (*this, node);
1502 catch (failed_constructor& err) {
1503 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1504 return boost::shared_ptr<Source>();
1509 Session::save_template (string template_name)
1512 string xml_path, bak_path, template_path;
1514 if (_state_of_the_state & CannotSave) {
1519 string dir = template_dir();
1521 if ((dp = opendir (dir.c_str()))) {
1524 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1525 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1530 tree.set_root (&get_template());
1533 xml_path += template_name;
1534 xml_path += _template_suffix;
1536 ifstream in(xml_path.c_str());
1539 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1545 if (!tree.write (xml_path)) {
1546 error << _("mix template not saved") << endmsg;
1554 Session::rename_template (string old_name, string new_name)
1556 string old_path = template_dir() + old_name + _template_suffix;
1557 string new_path = template_dir() + new_name + _template_suffix;
1559 return rename (old_path.c_str(), new_path.c_str());
1563 Session::delete_template (string name)
1565 string template_path = template_dir();
1566 template_path += name;
1567 template_path += _template_suffix;
1569 return remove (template_path.c_str());
1573 Session::refresh_disk_space ()
1576 struct statfs statfsbuf;
1577 vector<space_and_path>::iterator i;
1578 Glib::Mutex::Lock lm (space_lock);
1581 /* get freespace on every FS that is part of the session path */
1583 _total_free_4k_blocks = 0;
1585 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1586 statfs ((*i).path.c_str(), &statfsbuf);
1588 scale = statfsbuf.f_bsize/4096.0;
1590 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1591 _total_free_4k_blocks += (*i).blocks;
1597 Session::ensure_sound_dir (string path, string& result)
1602 /* Ensure that the parent directory exists */
1604 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1605 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1609 /* Ensure that the sounds directory exists */
1613 result += sound_dir_name;
1615 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1616 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1622 dead += dead_sound_dir_name;
1624 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1625 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1631 peak += peak_dir_name;
1633 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1634 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1638 /* callers expect this to be terminated ... */
1645 Session::discover_best_sound_dir (bool destructive)
1647 vector<space_and_path>::iterator i;
1650 /* handle common case without system calls */
1652 if (session_dirs.size() == 1) {
1656 /* OK, here's the algorithm we're following here:
1658 We want to select which directory to use for
1659 the next file source to be created. Ideally,
1660 we'd like to use a round-robin process so as to
1661 get maximum performance benefits from splitting
1662 the files across multiple disks.
1664 However, in situations without much diskspace, an
1665 RR approach may end up filling up a filesystem
1666 with new files while others still have space.
1667 Its therefore important to pay some attention to
1668 the freespace in the filesystem holding each
1669 directory as well. However, if we did that by
1670 itself, we'd keep creating new files in the file
1671 system with the most space until it was as full
1672 as all others, thus negating any performance
1673 benefits of this RAID-1 like approach.
1675 So, we use a user-configurable space threshold. If
1676 there are at least 2 filesystems with more than this
1677 much space available, we use RR selection between them.
1678 If not, then we pick the filesystem with the most space.
1680 This gets a good balance between the two
1684 refresh_disk_space ();
1686 int free_enough = 0;
1688 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1689 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1694 if (free_enough >= 2) {
1696 bool found_it = false;
1698 /* use RR selection process, ensuring that the one
1702 i = last_rr_session_dir;
1705 if (++i == session_dirs.end()) {
1706 i = session_dirs.begin();
1709 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1710 if (ensure_sound_dir ((*i).path, result) == 0) {
1711 last_rr_session_dir = i;
1717 } while (i != last_rr_session_dir);
1720 result = sound_dir();
1725 /* pick FS with the most freespace (and that
1726 seems to actually work ...)
1729 vector<space_and_path> sorted;
1730 space_and_path_ascending_cmp cmp;
1732 sorted = session_dirs;
1733 sort (sorted.begin(), sorted.end(), cmp);
1735 for (i = sorted.begin(); i != sorted.end(); ++i) {
1736 if (ensure_sound_dir ((*i).path, result) == 0) {
1737 last_rr_session_dir = i;
1742 /* if the above fails, fall back to the most simplistic solution */
1744 if (i == sorted.end()) {
1753 Session::load_playlists (const XMLNode& node)
1756 XMLNodeConstIterator niter;
1757 boost::shared_ptr<Playlist> playlist;
1759 nlist = node.children();
1763 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1765 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1766 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1774 Session::load_unused_playlists (const XMLNode& node)
1777 XMLNodeConstIterator niter;
1778 boost::shared_ptr<Playlist> playlist;
1780 nlist = node.children();
1784 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1786 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1787 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1791 // now manually untrack it
1793 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1800 boost::shared_ptr<Playlist>
1801 Session::XMLPlaylistFactory (const XMLNode& node)
1804 return PlaylistFactory::create (*this, node);
1807 catch (failed_constructor& err) {
1808 return boost::shared_ptr<Playlist>();
1813 Session::load_named_selections (const XMLNode& node)
1816 XMLNodeConstIterator niter;
1819 nlist = node.children();
1823 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1825 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1826 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1834 Session::XMLNamedSelectionFactory (const XMLNode& node)
1837 return new NamedSelection (*this, node);
1840 catch (failed_constructor& err) {
1846 Session::dead_sound_dir () const
1849 res += dead_sound_dir_name;
1855 Session::sound_dir (bool with_path) const
1857 /* support old session structure */
1859 struct stat statbuf;
1861 string old_withpath;
1863 old_nopath += old_sound_dir_name;
1866 old_withpath = _path;
1867 old_withpath += old_sound_dir_name;
1869 if (stat (old_withpath.c_str(), &statbuf) == 0) {
1871 return old_withpath;
1882 res += interchange_dir_name;
1884 res += legalize_for_path (_name);
1886 res += sound_dir_name;
1892 Session::peak_dir () const
1895 res += peak_dir_name;
1901 Session::automation_dir () const
1904 res += "automation/";
1909 Session::template_dir ()
1911 string path = get_user_ardour_path();
1912 path += "templates/";
1918 Session::export_dir () const
1921 res += export_dir_name;
1927 Session::suffixed_search_path (string suffix, bool data)
1931 path += get_user_ardour_path();
1932 if (path[path.length()-1] != ':') {
1937 path += get_system_data_path();
1939 path += get_system_module_path();
1942 vector<string> split_path;
1944 split (path, split_path, ':');
1947 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
1952 if (distance (i, split_path.end()) != 1) {
1961 Session::template_path ()
1963 return suffixed_search_path (X_("templates"), true);
1967 Session::control_protocol_path ()
1969 return suffixed_search_path (X_("surfaces"), false);
1973 Session::load_connections (const XMLNode& node)
1975 XMLNodeList nlist = node.children();
1976 XMLNodeConstIterator niter;
1980 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1981 if ((*niter)->name() == "InputConnection") {
1982 add_connection (new ARDOUR::InputConnection (**niter));
1983 } else if ((*niter)->name() == "OutputConnection") {
1984 add_connection (new ARDOUR::OutputConnection (**niter));
1986 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1995 Session::load_edit_groups (const XMLNode& node)
1997 return load_route_groups (node, true);
2001 Session::load_mix_groups (const XMLNode& node)
2003 return load_route_groups (node, false);
2007 Session::load_route_groups (const XMLNode& node, bool edit)
2009 XMLNodeList nlist = node.children();
2010 XMLNodeConstIterator niter;
2015 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2016 if ((*niter)->name() == "RouteGroup") {
2018 rg = add_edit_group ("");
2019 rg->set_state (**niter);
2021 rg = add_mix_group ("");
2022 rg->set_state (**niter);
2031 state_file_filter (const string &str, void *arg)
2033 return (str.length() > strlen(Session::statefile_suffix()) &&
2034 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2038 bool operator()(const string* a, const string* b) {
2044 remove_end(string* state)
2046 string statename(*state);
2048 string::size_type start,end;
2049 if ((start = statename.find_last_of ('/')) != string::npos) {
2050 statename = statename.substr (start+1);
2053 if ((end = statename.rfind(".ardour")) == string::npos) {
2054 end = statename.length();
2057 return new string(statename.substr (0, end));
2061 Session::possible_states (string path)
2063 PathScanner scanner;
2064 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2066 transform(states->begin(), states->end(), states->begin(), remove_end);
2069 sort (states->begin(), states->end(), cmp);
2075 Session::possible_states () const
2077 return possible_states(_path);
2081 Session::auto_save()
2083 save_state (_current_snapshot_name);
2087 Session::add_edit_group (string name)
2089 RouteGroup* rg = new RouteGroup (*this, name);
2090 edit_groups.push_back (rg);
2091 edit_group_added (rg); /* EMIT SIGNAL */
2097 Session::add_mix_group (string name)
2099 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2100 mix_groups.push_back (rg);
2101 mix_group_added (rg); /* EMIT SIGNAL */
2107 Session::remove_edit_group (RouteGroup& rg)
2109 list<RouteGroup*>::iterator i;
2111 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2112 (*i)->apply (&Route::drop_edit_group, this);
2113 edit_groups.erase (i);
2114 edit_group_removed (); /* EMIT SIGNAL */
2121 Session::remove_mix_group (RouteGroup& rg)
2123 list<RouteGroup*>::iterator i;
2125 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2126 (*i)->apply (&Route::drop_mix_group, this);
2127 mix_groups.erase (i);
2128 mix_group_removed (); /* EMIT SIGNAL */
2135 Session::mix_group_by_name (string name)
2137 list<RouteGroup *>::iterator i;
2139 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2140 if ((*i)->name() == name) {
2148 Session::edit_group_by_name (string name)
2150 list<RouteGroup *>::iterator i;
2152 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2153 if ((*i)->name() == name) {
2161 Session::begin_reversible_command (string name)
2163 current_trans = new UndoTransaction;
2164 current_trans->set_name (name);
2168 Session::commit_reversible_command (Command *cmd)
2173 current_trans->add_command (cmd);
2176 gettimeofday (&now, 0);
2177 current_trans->set_timestamp (now);
2179 _history.add (current_trans);
2182 Session::GlobalRouteBooleanState
2183 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2185 GlobalRouteBooleanState s;
2186 boost::shared_ptr<RouteList> r = routes.reader ();
2188 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2189 if (!(*i)->hidden()) {
2190 RouteBooleanState v;
2193 Route* r = (*i).get();
2194 v.second = (r->*method)();
2203 Session::GlobalRouteMeterState
2204 Session::get_global_route_metering ()
2206 GlobalRouteMeterState s;
2207 boost::shared_ptr<RouteList> r = routes.reader ();
2209 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2210 if (!(*i)->hidden()) {
2214 v.second = (*i)->meter_point();
2224 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2226 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2228 boost::shared_ptr<Route> r = (i->first.lock());
2231 r->set_meter_point (i->second, arg);
2237 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2239 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2241 boost::shared_ptr<Route> r = (i->first.lock());
2244 Route* rp = r.get();
2245 (rp->*method) (i->second, arg);
2251 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2253 set_global_route_boolean (s, &Route::set_mute, src);
2257 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2259 set_global_route_boolean (s, &Route::set_solo, src);
2263 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2265 set_global_route_boolean (s, &Route::set_record_enable, src);
2270 Session::global_mute_memento (void* src)
2272 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2276 Session::global_metering_memento (void* src)
2278 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2282 Session::global_solo_memento (void* src)
2284 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2288 Session::global_record_enable_memento (void* src)
2290 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2295 template_filter (const string &str, void *arg)
2297 return (str.length() > strlen(Session::template_suffix()) &&
2298 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2302 Session::get_template_list (list<string> &template_names)
2304 vector<string *> *templates;
2305 PathScanner scanner;
2308 path = template_path ();
2310 templates = scanner (path, template_filter, 0, false, true);
2312 vector<string*>::iterator i;
2313 for (i = templates->begin(); i != templates->end(); ++i) {
2314 string fullpath = *(*i);
2317 start = fullpath.find_last_of ('/') + 1;
2318 if ((end = fullpath.find_last_of ('.')) <0) {
2319 end = fullpath.length();
2322 template_names.push_back(fullpath.substr(start, (end-start)));
2327 Session::read_favorite_dirs (FavoriteDirs & favs)
2329 string path = get_user_ardour_path();
2330 path += "/favorite_dirs";
2332 ifstream fav (path.c_str());
2337 if (errno != ENOENT) {
2338 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2349 getline(fav, newfav);
2355 favs.push_back (newfav);
2362 Session::write_favorite_dirs (FavoriteDirs & favs)
2364 string path = get_user_ardour_path();
2365 path += "/favorite_dirs";
2367 ofstream fav (path.c_str());
2373 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2374 fav << (*i) << endl;
2381 accept_all_non_peak_files (const string& path, void *arg)
2383 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2387 accept_all_state_files (const string& path, void *arg)
2389 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2393 Session::find_all_sources (string path, set<string>& result)
2398 if (!tree.read (path)) {
2402 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2407 XMLNodeConstIterator niter;
2409 nlist = node->children();
2413 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2417 if ((prop = (*niter)->property (X_("name"))) == 0) {
2421 if (prop->value()[0] == '/') {
2422 /* external file, ignore */
2426 string path = _path; /* /-terminated */
2427 path += sound_dir_name;
2429 path += prop->value();
2431 result.insert (path);
2438 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2440 PathScanner scanner;
2441 vector<string*>* state_files;
2443 string this_snapshot_path;
2449 if (ripped[ripped.length()-1] == '/') {
2450 ripped = ripped.substr (0, ripped.length() - 1);
2453 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2455 if (state_files == 0) {
2460 this_snapshot_path = _path;
2461 this_snapshot_path += _current_snapshot_name;
2462 this_snapshot_path += _statefile_suffix;
2464 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2466 if (exclude_this_snapshot && **i == this_snapshot_path) {
2470 if (find_all_sources (**i, result) < 0) {
2478 struct RegionCounter {
2479 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2480 AudioSourceList::iterator iter;
2481 boost::shared_ptr<Region> region;
2484 RegionCounter() : count (0) {}
2488 Session::cleanup_sources (Session::cleanup_report& rep)
2490 vector<boost::shared_ptr<Source> > dead_sources;
2491 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2492 PathScanner scanner;
2494 vector<space_and_path>::iterator i;
2495 vector<space_and_path>::iterator nexti;
2496 vector<string*>* soundfiles;
2497 vector<string> unused;
2498 set<string> all_sources;
2503 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2505 /* step 1: consider deleting all unused playlists */
2507 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2510 status = AskAboutPlaylistDeletion (*x);
2519 playlists_tbd.push_back (*x);
2523 /* leave it alone */
2528 /* now delete any that were marked for deletion */
2530 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2531 (*x)->drop_references ();
2534 playlists_tbd.clear ();
2536 /* step 2: find all un-used sources */
2541 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2543 AudioSourceList::iterator tmp;
2548 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2552 if (!i->second->used() && i->second->length() > 0) {
2553 dead_sources.push_back (i->second);
2554 i->second->GoingAway();
2560 /* build a list of all the possible sound directories for the session */
2562 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2567 sound_path += (*i).path;
2568 sound_path += sound_dir (false);
2570 if (nexti != session_dirs.end()) {
2577 /* now do the same thing for the files that ended up in the sounds dir(s)
2578 but are not referenced as sources in any snapshot.
2581 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2583 if (soundfiles == 0) {
2587 /* find all sources, but don't use this snapshot because the
2588 state file on disk still references sources we may have already
2592 find_all_sources_across_snapshots (all_sources, true);
2594 /* add our current source list
2597 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2598 boost::shared_ptr<AudioFileSource> fs;
2600 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2601 all_sources.insert (fs->path());
2605 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2610 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2619 unused.push_back (spath);
2623 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2625 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2626 struct stat statbuf;
2628 rep.paths.push_back (*x);
2629 if (stat ((*x).c_str(), &statbuf) == 0) {
2630 rep.space += statbuf.st_size;
2635 /* don't move the file across filesystems, just
2636 stick it in the `dead_sound_dir_name' directory
2637 on whichever filesystem it was already on.
2640 if (_path.find ("/sounds/")) {
2642 /* old school, go up 1 level */
2644 newpath = Glib::path_get_dirname (*x); // "sounds"
2645 newpath = Glib::path_get_dirname (newpath); // "session-name"
2649 /* new school, go up 4 levels */
2651 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2652 newpath = Glib::path_get_dirname (newpath); // "session-name"
2653 newpath = Glib::path_get_dirname (newpath); // "interchange"
2654 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2658 newpath += dead_sound_dir_name;
2660 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2661 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2666 newpath += Glib::path_get_basename ((*x));
2668 if (access (newpath.c_str(), F_OK) == 0) {
2670 /* the new path already exists, try versioning */
2672 char buf[PATH_MAX+1];
2676 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2679 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2680 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2684 if (version == 999) {
2685 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2689 newpath = newpath_v;
2694 /* it doesn't exist, or we can't read it or something */
2698 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2699 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2700 (*x), newpath, strerror (errno))
2705 /* see if there an easy to find peakfile for this file, and remove it.
2708 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2709 peakpath += ".peak";
2711 if (access (peakpath.c_str(), W_OK) == 0) {
2712 if (::unlink (peakpath.c_str()) != 0) {
2713 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2714 peakpath, _path, strerror (errno))
2716 /* try to back out */
2717 rename (newpath.c_str(), _path.c_str());
2725 /* dump the history list */
2729 /* save state so we don't end up a session file
2730 referring to non-existent sources.
2736 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2741 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2743 vector<space_and_path>::iterator i;
2744 string dead_sound_dir;
2745 struct dirent* dentry;
2746 struct stat statbuf;
2752 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2754 dead_sound_dir = (*i).path;
2755 dead_sound_dir += dead_sound_dir_name;
2757 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2761 while ((dentry = readdir (dead)) != 0) {
2763 /* avoid '.' and '..' */
2765 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2766 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2772 fullpath = dead_sound_dir;
2774 fullpath += dentry->d_name;
2776 if (stat (fullpath.c_str(), &statbuf)) {
2780 if (!S_ISREG (statbuf.st_mode)) {
2784 if (unlink (fullpath.c_str())) {
2785 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2786 fullpath, strerror (errno))
2790 rep.paths.push_back (dentry->d_name);
2791 rep.space += statbuf.st_size;
2802 Session::set_dirty ()
2804 bool was_dirty = dirty();
2806 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2809 DirtyChanged(); /* EMIT SIGNAL */
2815 Session::set_clean ()
2817 bool was_dirty = dirty();
2819 _state_of_the_state = Clean;
2822 DirtyChanged(); /* EMIT SIGNAL */
2827 Session::set_deletion_in_progress ()
2829 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2833 Session::add_controllable (Controllable* c)
2835 /* this adds a controllable to the list managed by the Session.
2836 this is a subset of those managed by the Controllable class
2837 itself, and represents the only ones whose state will be saved
2838 as part of the session.
2841 Glib::Mutex::Lock lm (controllables_lock);
2842 controllables.insert (c);
2846 Session::remove_controllable (Controllable* c)
2848 if (_state_of_the_state | Deletion) {
2852 Glib::Mutex::Lock lm (controllables_lock);
2854 Controllables::iterator x = controllables.find (c);
2856 if (x != controllables.end()) {
2857 controllables.erase (x);
2862 Session::controllable_by_id (const PBD::ID& id)
2864 Glib::Mutex::Lock lm (controllables_lock);
2866 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2867 if ((*i)->id() == id) {
2876 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2878 Stateful::add_instant_xml (node, dir);
2879 Config->add_instant_xml (node, get_user_ardour_path());
2884 Session::save_history (string snapshot_name)
2890 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2892 if (snapshot_name.empty()) {
2893 snapshot_name = _current_snapshot_name;
2896 xml_path = _path + snapshot_name + ".history";
2898 bak_path = xml_path + ".bak";
2900 if ((access (xml_path.c_str(), F_OK) == 0) &&
2901 (rename (xml_path.c_str(), bak_path.c_str())))
2903 error << _("could not backup old history file, current history not saved.") << endmsg;
2907 if (!tree.write (xml_path))
2909 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2911 /* don't leave a corrupt file lying around if it is
2915 if (unlink (xml_path.c_str())) {
2916 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2918 if (rename (bak_path.c_str(), xml_path.c_str()))
2920 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2931 Session::restore_history (string snapshot_name)
2936 if (snapshot_name.empty()) {
2937 snapshot_name = _current_snapshot_name;
2941 xmlpath = _path + snapshot_name + ".history";
2942 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2944 if (access (xmlpath.c_str(), F_OK)) {
2945 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2949 if (!tree.read (xmlpath)) {
2950 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2954 /* replace history */
2957 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2960 UndoTransaction* ut = new UndoTransaction ();
2963 ut->set_name(t->property("name")->value());
2964 stringstream ss(t->property("tv_sec")->value());
2966 ss.str(t->property("tv_usec")->value());
2968 ut->set_timestamp(tv);
2970 for (XMLNodeConstIterator child_it = t->children().begin();
2971 child_it != t->children().end();
2974 XMLNode *n = *child_it;
2977 if (n->name() == "MementoCommand" ||
2978 n->name() == "MementoUndoCommand" ||
2979 n->name() == "MementoRedoCommand") {
2981 if ((c = memento_command_factory(n))) {
2985 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2987 if ((c = global_state_command_factory (*n))) {
2988 ut->add_command (c);
2993 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3004 Session::config_changed (const char* parameter_name)
3006 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3008 if (PARAM_IS ("seamless-loop")) {
3010 } else if (PARAM_IS ("rf-speed")) {
3012 } else if (PARAM_IS ("auto-loop")) {
3014 } else if (PARAM_IS ("auto-input")) {
3016 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3017 /* auto-input only makes a difference if we're rolling */
3019 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3021 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3022 if ((*i)->record_enabled ()) {
3023 (*i)->monitor_input (!Config->get_auto_input());
3028 } else if (PARAM_IS ("punch-in")) {
3032 if ((location = _locations.auto_punch_location()) != 0) {
3034 if (Config->get_punch_in ()) {
3035 replace_event (Event::PunchIn, location->start());
3037 remove_event (location->start(), Event::PunchIn);
3041 } else if (PARAM_IS ("punch-out")) {
3045 if ((location = _locations.auto_punch_location()) != 0) {
3047 if (Config->get_punch_out()) {
3048 replace_event (Event::PunchOut, location->end());
3050 clear_events (Event::PunchOut);
3054 } else if (PARAM_IS ("edit-mode")) {
3056 Glib::Mutex::Lock lm (playlist_lock);
3058 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3059 (*i)->set_edit_mode (Config->get_edit_mode ());
3062 } else if (PARAM_IS ("use-video-sync")) {
3064 if (transport_stopped()) {
3065 if (Config->get_use_video_sync()) {
3066 waiting_for_sync_offset = true;
3070 } else if (PARAM_IS ("mmc-control")) {
3072 poke_midi_thread ();
3074 } else if (PARAM_IS ("mmc-device-id")) {
3077 mmc->set_device_id (Config->get_mmc_device_id());
3080 } else if (PARAM_IS ("midi-control")) {
3082 poke_midi_thread ();
3084 } else if (PARAM_IS ("raid-path")) {
3086 setup_raid_path (Config->get_raid_path());
3088 } else if (PARAM_IS ("smpte-format")) {
3092 } else if (PARAM_IS ("video-pullup")) {
3096 } else if (PARAM_IS ("seamless-loop")) {
3098 if (play_loop && transport_rolling()) {
3099 // to reset diskstreams etc
3100 request_play_loop (true);
3103 } else if (PARAM_IS ("rf-speed")) {
3105 cumulative_rf_motion = 0;
3108 } else if (PARAM_IS ("click-sound")) {
3110 setup_click_sounds (1);
3112 } else if (PARAM_IS ("click-emphasis-sound")) {
3114 setup_click_sounds (-1);
3116 } else if (PARAM_IS ("clicking")) {
3118 if (Config->get_clicking()) {
3119 if (_click_io && click_data) { // don't require emphasis data
3126 } else if (PARAM_IS ("send-mtc")) {
3128 /* only set the internal flag if we have
3132 if (_mtc_port != 0) {
3133 session_send_mtc = Config->get_send_mtc();
3134 if (session_send_mtc) {
3135 /* mark us ready to send */
3136 next_quarter_frame_to_send = 0;
3140 } else if (PARAM_IS ("send-mmc")) {
3142 /* only set the internal flag if we have
3146 if (_mmc_port != 0) {
3147 session_send_mmc = Config->get_send_mmc();
3150 } else if (PARAM_IS ("midi-feedback")) {
3152 /* only set the internal flag if we have
3156 if (_mtc_port != 0) {
3157 session_midi_feedback = Config->get_midi_feedback();
3160 } else if (PARAM_IS ("jack-time-master")) {
3162 engine().reset_timebase ();
3164 } else if (PARAM_IS ("native-file-header-format")) {
3166 if (!first_file_header_format_reset) {
3167 reset_native_file_format ();
3170 first_file_header_format_reset = false;
3172 } else if (PARAM_IS ("native-file-data-format")) {
3174 if (!first_file_data_format_reset) {
3175 reset_native_file_format ();
3178 first_file_data_format_reset = false;
3180 } else if (PARAM_IS ("slave-source")) {
3181 set_slave_source (Config->get_slave_source());
3182 } else if (PARAM_IS ("remote-model")) {
3183 set_remote_control_ids ();