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/destructive_filesource.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 transport_sub_state = 0;
135 _transport_frame = 0;
137 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
138 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
139 _end_location_is_free = true;
140 g_atomic_int_set (&_record_status, Disabled);
141 loop_changing = false;
143 _last_roll_location = 0;
144 _last_record_location = 0;
145 pending_locate_frame = 0;
146 pending_locate_roll = false;
147 pending_locate_flush = false;
148 dstream_buffer_size = 0;
150 state_was_pending = false;
152 outbound_mtc_smpte_frame = 0;
153 next_quarter_frame_to_send = -1;
154 current_block_size = 0;
155 solo_update_disabled = false;
156 currently_soloing = false;
157 _have_captured = false;
158 _worst_output_latency = 0;
159 _worst_input_latency = 0;
160 _worst_track_latency = 0;
161 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
163 butler_mixdown_buffer = 0;
164 butler_gain_buffer = 0;
166 session_send_mmc = false;
167 session_send_mtc = false;
168 post_transport_work = PostTransportWork (0);
169 g_atomic_int_set (&butler_should_do_transport_work, 0);
170 g_atomic_int_set (&butler_active, 0);
171 g_atomic_int_set (&_playback_load, 100);
172 g_atomic_int_set (&_capture_load, 100);
173 g_atomic_int_set (&_playback_load_min, 100);
174 g_atomic_int_set (&_capture_load_min, 100);
176 waiting_to_start = false;
178 _gain_automation_buffer = 0;
179 _pan_automation_buffer = 0;
181 pending_abort = false;
182 destructive_index = 0;
184 first_file_data_format_reset = true;
185 first_file_header_format_reset = true;
187 AudioDiskstream::allocate_working_buffers();
189 /* default short fade = 15ms */
191 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
192 SndFileSource::setup_standard_crossfades (frame_rate());
194 last_mmc_step.tv_sec = 0;
195 last_mmc_step.tv_usec = 0;
198 /* click sounds are unset by default, which causes us to internal
199 waveforms for clicks.
203 click_emphasis_data = 0;
205 click_emphasis_length = 0;
208 process_function = &Session::process_with_events;
210 if (Config->get_use_video_sync()) {
211 waiting_for_sync_offset = true;
213 waiting_for_sync_offset = false;
216 _current_frame_rate = 48000;
217 _base_frame_rate = 48000;
221 _smpte_offset_negative = true;
222 last_smpte_valid = false;
226 last_rr_session_dir = session_dirs.begin();
227 refresh_disk_space ();
229 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
233 average_slave_delta = 1800;
234 have_first_delta_accumulator = false;
235 delta_accumulator_cnt = 0;
236 slave_state = Stopped;
238 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
240 /* These are all static "per-class" signals */
242 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
243 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
244 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
245 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
246 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
247 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
249 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
251 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
253 /* stop IO objects from doing stuff until we're ready for them */
255 IO::disable_panners ();
256 IO::disable_ports ();
257 IO::disable_connecting ();
261 Session::second_stage_init (bool new_session)
263 AudioFileSource::set_peak_dir (peak_dir());
266 if (load_state (_current_snapshot_name)) {
269 remove_empty_sounds ();
272 if (start_butler_thread()) {
276 if (start_midi_thread ()) {
280 // set_state() will call setup_raid_path(), but if it's a new session we need
281 // to call setup_raid_path() here.
283 if (set_state (*state_tree->root())) {
287 setup_raid_path(_path);
290 /* we can't save till after ::when_engine_running() is called,
291 because otherwise we save state with no connections made.
292 therefore, we reset _state_of_the_state because ::set_state()
293 will have cleared it.
295 we also have to include Loading so that any events that get
296 generated between here and the end of ::when_engine_running()
297 will be processed directly rather than queued.
300 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
302 // set_auto_input (true);
303 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
304 _locations.added.connect (mem_fun (this, &Session::locations_added));
305 setup_click_sounds (0);
306 setup_midi_control ();
308 /* Pay attention ... */
310 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
311 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
314 when_engine_running();
317 /* handle this one in a different way than all others, so that its clear what happened */
319 catch (AudioEngine::PortRegistrationFailure& err) {
320 error << _("Unable to create all required ports")
329 send_full_time_code ();
330 _engine.transport_locate (0);
331 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
332 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
334 ControlProtocolManager::instance().set_session (*this);
337 _end_location_is_free = true;
339 _end_location_is_free = false;
346 Session::raid_path () const
350 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
355 return path.substr (0, path.length() - 1); // drop final colon
359 Session::setup_raid_path (string path)
361 string::size_type colon;
365 string::size_type len = path.length();
370 if (path.length() == 0) {
374 session_dirs.clear ();
376 for (string::size_type n = 0; n < len; ++n) {
377 if (path[n] == ':') {
384 /* no multiple search path, just one location (common case) */
388 session_dirs.push_back (sp);
395 if (fspath[fspath.length()-1] != '/') {
399 fspath += sound_dir (false);
401 AudioFileSource::set_search_path (fspath);
408 while ((colon = remaining.find_first_of (':')) != string::npos) {
411 sp.path = remaining.substr (0, colon);
412 session_dirs.push_back (sp);
414 /* add sounds to file search path */
417 if (fspath[fspath.length()-1] != '/') {
420 fspath += sound_dir (false);
423 remaining = remaining.substr (colon+1);
426 if (remaining.length()) {
433 if (fspath[fspath.length()-1] != '/') {
436 fspath += sound_dir (false);
439 session_dirs.push_back (sp);
442 /* set the AudioFileSource search path */
444 AudioFileSource::set_search_path (fspath);
446 /* reset the round-robin soundfile path thingie */
448 last_rr_session_dir = session_dirs.begin();
452 Session::create (bool& new_session, string* mix_template, nframes_t initial_length)
456 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
457 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
463 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
464 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
470 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
471 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
475 dir = dead_sound_dir ();
477 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
478 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
482 dir = automation_dir ();
484 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
485 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
490 /* check new_session so we don't overwrite an existing one */
493 std::string in_path = *mix_template;
495 ifstream in(in_path.c_str());
498 string out_path = _path;
500 out_path += _statefile_suffix;
502 ofstream out(out_path.c_str());
507 // okay, session is set up. Treat like normal saved
508 // session from now on.
514 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
520 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
527 /* set initial start + end point */
529 start_location->set_end (0);
530 _locations.add (start_location);
532 end_location->set_end (initial_length);
533 _locations.add (end_location);
535 _state_of_the_state = Clean;
537 if (save_state (_current_snapshot_name)) {
545 Session::load_diskstreams (const XMLNode& node)
548 XMLNodeConstIterator citer;
550 clist = node.children();
552 for (citer = clist.begin(); citer != clist.end(); ++citer) {
556 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
557 add_diskstream (dstream);
560 catch (failed_constructor& err) {
561 error << _("Session: could not load diskstream via XML state") << endmsg;
570 Session::remove_pending_capture_state ()
575 xml_path += _current_snapshot_name;
576 xml_path += _pending_suffix;
578 unlink (xml_path.c_str());
582 Session::save_state (string snapshot_name, bool pending)
588 if (_state_of_the_state & CannotSave) {
592 tree.set_root (&get_state());
594 if (snapshot_name.empty()) {
595 snapshot_name = _current_snapshot_name;
601 xml_path += snapshot_name;
602 xml_path += _statefile_suffix;
607 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
608 copy_file (xml_path, bak_path);
614 xml_path += snapshot_name;
615 xml_path += _pending_suffix;
622 tmp_path += snapshot_name;
625 cerr << "actually writing state\n";
627 if (!tree.write (tmp_path)) {
628 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
629 unlink (tmp_path.c_str());
634 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
635 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
636 unlink (tmp_path.c_str());
643 save_history (snapshot_name);
645 bool was_dirty = dirty();
647 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
650 DirtyChanged (); /* EMIT SIGNAL */
653 StateSaved (snapshot_name); /* EMIT SIGNAL */
660 Session::restore_state (string snapshot_name)
662 if (load_state (snapshot_name) == 0) {
663 set_state (*state_tree->root());
670 Session::load_state (string snapshot_name)
679 state_was_pending = false;
681 /* check for leftover pending state from a crashed capture attempt */
684 xmlpath += snapshot_name;
685 xmlpath += _pending_suffix;
687 if (!access (xmlpath.c_str(), F_OK)) {
689 /* there is pending state from a crashed capture attempt */
691 if (AskAboutPendingState()) {
692 state_was_pending = true;
696 if (!state_was_pending) {
699 xmlpath += snapshot_name;
700 xmlpath += _statefile_suffix;
703 if (access (xmlpath.c_str(), F_OK)) {
704 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
708 state_tree = new XMLTree;
712 if (!state_tree->read (xmlpath)) {
713 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
719 XMLNode& root (*state_tree->root());
721 if (root.name() != X_("Session")) {
722 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
728 const XMLProperty* prop;
731 if ((prop = root.property ("version")) == 0) {
732 /* no version implies very old version of Ardour */
736 major_version = atoi (prop->value()); // grab just the first number before the period
737 if (major_version < 2) {
745 backup_path = xmlpath;
748 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
749 xmlpath, backup_path)
752 copy_file (xmlpath, backup_path);
754 /* if it fails, don't worry. right? */
761 Session::load_options (const XMLNode& node)
765 LocaleGuard lg (X_("POSIX"));
767 Config->set_variables (node, ConfigVariableBase::Session);
769 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
770 if ((prop = child->property ("val")) != 0) {
771 _end_location_is_free = (prop->value() == "yes");
779 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
781 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
782 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
784 return owner & modified_by_session_or_user;
788 Session::get_options () const
791 LocaleGuard lg (X_("POSIX"));
793 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
795 child = option_root.add_child ("end-marker-is-free");
796 child->add_property ("val", _end_location_is_free ? "yes" : "no");
808 Session::get_template()
810 /* if we don't disable rec-enable, diskstreams
811 will believe they need to store their capture
812 sources in their state node.
815 disable_record (false);
821 Session::state(bool full_state)
823 XMLNode* node = new XMLNode("Session");
826 // store libardour version, just in case
828 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
829 libardour_major_version, libardour_minor_version, libardour_micro_version);
830 node->add_property("version", string(buf));
832 /* store configuration settings */
837 node->add_property ("name", _name);
839 if (session_dirs.size() > 1) {
843 vector<space_and_path>::iterator i = session_dirs.begin();
844 vector<space_and_path>::iterator next;
846 ++i; /* skip the first one */
850 while (i != session_dirs.end()) {
854 if (next != session_dirs.end()) {
864 child = node->add_child ("Path");
865 child->add_content (p);
869 /* save the ID counter */
871 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
872 node->add_property ("id-counter", buf);
874 /* various options */
876 node->add_child_nocopy (get_options());
878 child = node->add_child ("Sources");
881 Glib::Mutex::Lock sl (audio_source_lock);
883 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
885 /* Don't save information about AudioFileSources that are empty */
887 boost::shared_ptr<AudioFileSource> fs;
889 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
891 /* destructive file sources are OK if they are empty, because
892 we will re-use them every time.
895 if (!fs->destructive()) {
896 if (fs->length() == 0) {
902 child->add_child_nocopy (siter->second->get_state());
906 child = node->add_child ("Regions");
909 Glib::Mutex::Lock rl (region_lock);
911 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
913 /* only store regions not attached to playlists */
915 if (i->second->playlist() == 0) {
916 child->add_child_nocopy (i->second->state (true));
921 child = node->add_child ("DiskStreams");
924 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
925 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
926 if (!(*i)->hidden()) {
927 child->add_child_nocopy ((*i)->get_state());
933 node->add_child_nocopy (_locations.get_state());
935 // for a template, just create a new Locations, populate it
936 // with the default start and end, and get the state for that.
938 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
939 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
942 end->set_end(compute_initial_length());
944 node->add_child_nocopy (loc.get_state());
947 child = node->add_child ("Connections");
949 Glib::Mutex::Lock lm (connection_lock);
950 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
951 if (!(*i)->system_dependent()) {
952 child->add_child_nocopy ((*i)->get_state());
957 child = node->add_child ("Routes");
959 boost::shared_ptr<RouteList> r = routes.reader ();
961 RoutePublicOrderSorter cmp;
962 RouteList public_order (*r);
963 public_order.sort (cmp);
965 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
966 if (!(*i)->hidden()) {
968 child->add_child_nocopy ((*i)->get_state());
970 child->add_child_nocopy ((*i)->get_template());
977 child = node->add_child ("EditGroups");
978 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
979 child->add_child_nocopy ((*i)->get_state());
982 child = node->add_child ("MixGroups");
983 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
984 child->add_child_nocopy ((*i)->get_state());
987 child = node->add_child ("Playlists");
988 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
989 if (!(*i)->hidden()) {
990 if (!(*i)->empty()) {
992 child->add_child_nocopy ((*i)->get_state());
994 child->add_child_nocopy ((*i)->get_template());
1000 child = node->add_child ("UnusedPlaylists");
1001 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1002 if (!(*i)->hidden()) {
1003 if (!(*i)->empty()) {
1005 child->add_child_nocopy ((*i)->get_state());
1007 child->add_child_nocopy ((*i)->get_template());
1015 child = node->add_child ("Click");
1016 child->add_child_nocopy (_click_io->state (full_state));
1020 child = node->add_child ("NamedSelections");
1021 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1023 child->add_child_nocopy ((*i)->get_state());
1028 node->add_child_nocopy (_tempo_map->get_state());
1030 node->add_child_nocopy (get_control_protocol_state());
1033 node->add_child_copy (*_extra_xml);
1040 Session::get_control_protocol_state ()
1042 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1043 return cpm.get_state();
1047 Session::set_state (const XMLNode& node)
1051 const XMLProperty* prop;
1054 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1056 if (node.name() != X_("Session")){
1057 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1061 if ((prop = node.property ("name")) != 0) {
1062 _name = prop->value ();
1065 setup_raid_path(_path);
1067 if ((prop = node.property (X_("id-counter"))) != 0) {
1069 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1070 ID::init_counter (x);
1072 /* old sessions used a timebased counter, so fake
1073 the startup ID counter based on a standard
1078 ID::init_counter (now);
1082 IO::disable_ports ();
1083 IO::disable_connecting ();
1085 /* Object loading order:
1103 if (use_config_midi_ports ()) {
1106 if ((child = find_named_node (node, "extra")) != 0) {
1107 _extra_xml = new XMLNode (*child);
1110 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1111 load_options (*child);
1112 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1113 load_options (*child);
1115 error << _("Session: XML state has no options section") << endmsg;
1118 if ((child = find_named_node (node, "Locations")) == 0) {
1119 error << _("Session: XML state has no locations section") << endmsg;
1121 } else if (_locations.set_state (*child)) {
1127 if ((location = _locations.auto_loop_location()) != 0) {
1128 set_auto_loop_location (location);
1131 if ((location = _locations.auto_punch_location()) != 0) {
1132 set_auto_punch_location (location);
1135 if ((location = _locations.end_location()) == 0) {
1136 _locations.add (end_location);
1138 delete end_location;
1139 end_location = location;
1142 if ((location = _locations.start_location()) == 0) {
1143 _locations.add (start_location);
1145 delete start_location;
1146 start_location = location;
1149 AudioFileSource::set_header_position_offset (start_location->start());
1151 if ((child = find_named_node (node, "Sources")) == 0) {
1152 error << _("Session: XML state has no sources section") << endmsg;
1154 } else if (load_sources (*child)) {
1158 if ((child = find_named_node (node, "Regions")) == 0) {
1159 error << _("Session: XML state has no Regions section") << endmsg;
1161 } else if (load_regions (*child)) {
1165 if ((child = find_named_node (node, "Playlists")) == 0) {
1166 error << _("Session: XML state has no playlists section") << endmsg;
1168 } else if (load_playlists (*child)) {
1172 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1174 } else if (load_unused_playlists (*child)) {
1178 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1179 if (load_named_selections (*child)) {
1184 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1185 error << _("Session: XML state has no diskstreams section") << endmsg;
1187 } else if (load_diskstreams (*child)) {
1191 if ((child = find_named_node (node, "Connections")) == 0) {
1192 error << _("Session: XML state has no connections section") << endmsg;
1194 } else if (load_connections (*child)) {
1198 if ((child = find_named_node (node, "EditGroups")) == 0) {
1199 error << _("Session: XML state has no edit groups section") << endmsg;
1201 } else if (load_edit_groups (*child)) {
1205 if ((child = find_named_node (node, "MixGroups")) == 0) {
1206 error << _("Session: XML state has no mix groups section") << endmsg;
1208 } else if (load_mix_groups (*child)) {
1212 if ((child = find_named_node (node, "TempoMap")) == 0) {
1213 error << _("Session: XML state has no Tempo Map section") << endmsg;
1215 } else if (_tempo_map->set_state (*child)) {
1219 if ((child = find_named_node (node, "Routes")) == 0) {
1220 error << _("Session: XML state has no routes section") << endmsg;
1222 } else if (load_routes (*child)) {
1226 if ((child = find_named_node (node, "Click")) == 0) {
1227 warning << _("Session: XML state has no click section") << endmsg;
1228 } else if (_click_io) {
1229 _click_io->set_state (*child);
1232 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1233 ControlProtocolManager::instance().set_protocol_states (*child);
1236 /* here beginneth the second phase ... */
1238 StateReady (); /* EMIT SIGNAL */
1240 _state_of_the_state = Clean;
1242 if (state_was_pending) {
1243 save_state (_current_snapshot_name);
1244 remove_pending_capture_state ();
1245 state_was_pending = false;
1255 Session::load_routes (const XMLNode& node)
1258 XMLNodeConstIterator niter;
1259 RouteList new_routes;
1261 nlist = node.children();
1265 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1267 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1270 error << _("Session: cannot create Route from XML description.") << endmsg;
1274 new_routes.push_back (route);
1277 add_routes (new_routes);
1282 boost::shared_ptr<Route>
1283 Session::XMLRouteFactory (const XMLNode& node)
1285 if (node.name() != "Route") {
1286 return boost::shared_ptr<Route> ((Route*) 0);
1289 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1290 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1293 boost::shared_ptr<Route> x (new Route (*this, node));
1299 Session::load_regions (const XMLNode& node)
1302 XMLNodeConstIterator niter;
1303 boost::shared_ptr<AudioRegion> region;
1305 nlist = node.children();
1309 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1310 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1311 error << _("Session: cannot create Region from XML description.") << endmsg;
1318 boost::shared_ptr<AudioRegion>
1319 Session::XMLRegionFactory (const XMLNode& node, bool full)
1321 const XMLProperty* prop;
1322 boost::shared_ptr<Source> source;
1323 boost::shared_ptr<AudioSource> as;
1325 uint32_t nchans = 1;
1328 if (node.name() != X_("Region")) {
1329 return boost::shared_ptr<AudioRegion>();
1332 if ((prop = node.property (X_("channels"))) != 0) {
1333 nchans = atoi (prop->value().c_str());
1337 if ((prop = node.property ("name")) == 0) {
1338 cerr << "no name for this region\n";
1342 if ((prop = node.property (X_("source-0"))) == 0) {
1343 if ((prop = node.property ("source")) == 0) {
1344 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1345 return boost::shared_ptr<AudioRegion>();
1349 PBD::ID s_id (prop->value());
1351 if ((source = source_by_id (s_id)) == 0) {
1352 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1353 return boost::shared_ptr<AudioRegion>();
1356 as = boost::dynamic_pointer_cast<AudioSource>(source);
1358 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1359 return boost::shared_ptr<AudioRegion>();
1362 sources.push_back (as);
1364 /* pickup other channels */
1366 for (uint32_t n=1; n < nchans; ++n) {
1367 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1368 if ((prop = node.property (buf)) != 0) {
1370 PBD::ID id2 (prop->value());
1372 if ((source = source_by_id (id2)) == 0) {
1373 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1374 return boost::shared_ptr<AudioRegion>();
1377 as = boost::dynamic_pointer_cast<AudioSource>(source);
1379 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1380 return boost::shared_ptr<AudioRegion>();
1382 sources.push_back (as);
1387 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1392 catch (failed_constructor& err) {
1393 return boost::shared_ptr<AudioRegion>();
1398 Session::get_sources_as_xml ()
1401 XMLNode* node = new XMLNode (X_("Sources"));
1402 Glib::Mutex::Lock lm (audio_source_lock);
1404 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1405 node->add_child_nocopy (i->second->get_state());
1408 /* XXX get MIDI and other sources here */
1414 Session::path_from_region_name (string name, string identifier)
1416 char buf[PATH_MAX+1];
1418 string dir = discover_best_sound_dir ();
1420 for (n = 0; n < 999999; ++n) {
1421 if (identifier.length()) {
1422 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1423 identifier.c_str(), n);
1425 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1427 if (access (buf, F_OK) != 0) {
1437 Session::load_sources (const XMLNode& node)
1440 XMLNodeConstIterator niter;
1441 boost::shared_ptr<Source> source;
1443 nlist = node.children();
1447 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1449 if ((source = XMLSourceFactory (**niter)) == 0) {
1450 error << _("Session: cannot create Source from XML description.") << endmsg;
1458 boost::shared_ptr<Source>
1459 Session::XMLSourceFactory (const XMLNode& node)
1461 if (node.name() != "Source") {
1462 return boost::shared_ptr<Source>();
1466 return SourceFactory::create (*this, node);
1469 catch (failed_constructor& err) {
1470 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1471 return boost::shared_ptr<Source>();
1476 Session::save_template (string template_name)
1479 string xml_path, bak_path, template_path;
1481 if (_state_of_the_state & CannotSave) {
1486 string dir = template_dir();
1488 if ((dp = opendir (dir.c_str()))) {
1491 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1492 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1497 tree.set_root (&get_template());
1500 xml_path += template_name;
1501 xml_path += _template_suffix;
1503 ifstream in(xml_path.c_str());
1506 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1512 if (!tree.write (xml_path)) {
1513 error << _("mix template not saved") << endmsg;
1521 Session::rename_template (string old_name, string new_name)
1523 string old_path = template_dir() + old_name + _template_suffix;
1524 string new_path = template_dir() + new_name + _template_suffix;
1526 return rename (old_path.c_str(), new_path.c_str());
1530 Session::delete_template (string name)
1532 string template_path = template_dir();
1533 template_path += name;
1534 template_path += _template_suffix;
1536 return remove (template_path.c_str());
1540 Session::refresh_disk_space ()
1543 struct statfs statfsbuf;
1544 vector<space_and_path>::iterator i;
1545 Glib::Mutex::Lock lm (space_lock);
1548 /* get freespace on every FS that is part of the session path */
1550 _total_free_4k_blocks = 0;
1552 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1553 statfs ((*i).path.c_str(), &statfsbuf);
1555 scale = statfsbuf.f_bsize/4096.0;
1557 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1558 _total_free_4k_blocks += (*i).blocks;
1564 Session::ensure_sound_dir (string path, string& result)
1569 /* Ensure that the parent directory exists */
1571 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1572 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1576 /* Ensure that the sounds directory exists */
1580 result += sound_dir_name;
1582 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1583 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1589 dead += dead_sound_dir_name;
1591 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1592 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1598 peak += peak_dir_name;
1600 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1601 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1605 /* callers expect this to be terminated ... */
1612 Session::discover_best_sound_dir (bool destructive)
1614 vector<space_and_path>::iterator i;
1617 /* handle common case without system calls */
1619 if (session_dirs.size() == 1) {
1623 /* OK, here's the algorithm we're following here:
1625 We want to select which directory to use for
1626 the next file source to be created. Ideally,
1627 we'd like to use a round-robin process so as to
1628 get maximum performance benefits from splitting
1629 the files across multiple disks.
1631 However, in situations without much diskspace, an
1632 RR approach may end up filling up a filesystem
1633 with new files while others still have space.
1634 Its therefore important to pay some attention to
1635 the freespace in the filesystem holding each
1636 directory as well. However, if we did that by
1637 itself, we'd keep creating new files in the file
1638 system with the most space until it was as full
1639 as all others, thus negating any performance
1640 benefits of this RAID-1 like approach.
1642 So, we use a user-configurable space threshold. If
1643 there are at least 2 filesystems with more than this
1644 much space available, we use RR selection between them.
1645 If not, then we pick the filesystem with the most space.
1647 This gets a good balance between the two
1651 refresh_disk_space ();
1653 int free_enough = 0;
1655 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1656 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1661 if (free_enough >= 2) {
1663 bool found_it = false;
1665 /* use RR selection process, ensuring that the one
1669 i = last_rr_session_dir;
1672 if (++i == session_dirs.end()) {
1673 i = session_dirs.begin();
1676 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1677 if (ensure_sound_dir ((*i).path, result) == 0) {
1678 last_rr_session_dir = i;
1684 } while (i != last_rr_session_dir);
1687 result = sound_dir();
1692 /* pick FS with the most freespace (and that
1693 seems to actually work ...)
1696 vector<space_and_path> sorted;
1697 space_and_path_ascending_cmp cmp;
1699 sorted = session_dirs;
1700 sort (sorted.begin(), sorted.end(), cmp);
1702 for (i = sorted.begin(); i != sorted.end(); ++i) {
1703 if (ensure_sound_dir ((*i).path, result) == 0) {
1704 last_rr_session_dir = i;
1709 /* if the above fails, fall back to the most simplistic solution */
1711 if (i == sorted.end()) {
1720 Session::load_playlists (const XMLNode& node)
1723 XMLNodeConstIterator niter;
1724 boost::shared_ptr<Playlist> playlist;
1726 nlist = node.children();
1730 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1732 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1733 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1741 Session::load_unused_playlists (const XMLNode& node)
1744 XMLNodeConstIterator niter;
1745 boost::shared_ptr<Playlist> playlist;
1747 nlist = node.children();
1751 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1753 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1754 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1758 // now manually untrack it
1760 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1767 boost::shared_ptr<Playlist>
1768 Session::XMLPlaylistFactory (const XMLNode& node)
1771 return PlaylistFactory::create (*this, node);
1774 catch (failed_constructor& err) {
1775 return boost::shared_ptr<Playlist>();
1780 Session::load_named_selections (const XMLNode& node)
1783 XMLNodeConstIterator niter;
1786 nlist = node.children();
1790 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1792 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1793 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1801 Session::XMLNamedSelectionFactory (const XMLNode& node)
1804 return new NamedSelection (*this, node);
1807 catch (failed_constructor& err) {
1813 Session::dead_sound_dir () const
1816 res += dead_sound_dir_name;
1822 Session::sound_dir (bool with_path) const
1824 /* support old session structure */
1826 struct stat statbuf;
1828 string old_withpath;
1830 old_nopath += old_sound_dir_name;
1833 old_withpath = _path;
1834 old_withpath += old_sound_dir_name;
1836 if (stat (old_withpath.c_str(), &statbuf) == 0) {
1838 return old_withpath;
1849 res += interchange_dir_name;
1851 res += legalize_for_path (_name);
1853 res += sound_dir_name;
1859 Session::peak_dir () const
1862 res += peak_dir_name;
1868 Session::automation_dir () const
1871 res += "automation/";
1876 Session::template_dir ()
1878 string path = get_user_ardour_path();
1879 path += "templates/";
1885 Session::suffixed_search_path (string suffix, bool data)
1889 path += get_user_ardour_path();
1890 if (path[path.length()-1] != ':') {
1895 path += get_system_data_path();
1897 path += get_system_module_path();
1900 vector<string> split_path;
1902 split (path, split_path, ':');
1905 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
1910 if (distance (i, split_path.end()) != 1) {
1919 Session::template_path ()
1921 return suffixed_search_path (X_("templates"), true);
1925 Session::control_protocol_path ()
1927 return suffixed_search_path (X_("surfaces"), false);
1931 Session::load_connections (const XMLNode& node)
1933 XMLNodeList nlist = node.children();
1934 XMLNodeConstIterator niter;
1938 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1939 if ((*niter)->name() == "InputConnection") {
1940 add_connection (new ARDOUR::InputConnection (**niter));
1941 } else if ((*niter)->name() == "OutputConnection") {
1942 add_connection (new ARDOUR::OutputConnection (**niter));
1944 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1953 Session::load_edit_groups (const XMLNode& node)
1955 return load_route_groups (node, true);
1959 Session::load_mix_groups (const XMLNode& node)
1961 return load_route_groups (node, false);
1965 Session::load_route_groups (const XMLNode& node, bool edit)
1967 XMLNodeList nlist = node.children();
1968 XMLNodeConstIterator niter;
1973 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1974 if ((*niter)->name() == "RouteGroup") {
1976 rg = add_edit_group ("");
1977 rg->set_state (**niter);
1979 rg = add_mix_group ("");
1980 rg->set_state (**niter);
1989 state_file_filter (const string &str, void *arg)
1991 return (str.length() > strlen(Session::statefile_suffix()) &&
1992 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
1996 bool operator()(const string* a, const string* b) {
2002 remove_end(string* state)
2004 string statename(*state);
2006 string::size_type start,end;
2007 if ((start = statename.find_last_of ('/')) != string::npos) {
2008 statename = statename.substr (start+1);
2011 if ((end = statename.rfind(".ardour")) == string::npos) {
2012 end = statename.length();
2015 return new string(statename.substr (0, end));
2019 Session::possible_states (string path)
2021 PathScanner scanner;
2022 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2024 transform(states->begin(), states->end(), states->begin(), remove_end);
2027 sort (states->begin(), states->end(), cmp);
2033 Session::possible_states () const
2035 return possible_states(_path);
2039 Session::auto_save()
2041 save_state (_current_snapshot_name);
2045 Session::add_edit_group (string name)
2047 RouteGroup* rg = new RouteGroup (*this, name);
2048 edit_groups.push_back (rg);
2049 edit_group_added (rg); /* EMIT SIGNAL */
2055 Session::add_mix_group (string name)
2057 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2058 mix_groups.push_back (rg);
2059 mix_group_added (rg); /* EMIT SIGNAL */
2065 Session::remove_edit_group (RouteGroup& rg)
2067 list<RouteGroup*>::iterator i;
2069 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2070 (*i)->apply (&Route::drop_edit_group, this);
2071 edit_groups.erase (i);
2072 edit_group_removed (); /* EMIT SIGNAL */
2079 Session::remove_mix_group (RouteGroup& rg)
2081 list<RouteGroup*>::iterator i;
2083 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2084 (*i)->apply (&Route::drop_mix_group, this);
2085 mix_groups.erase (i);
2086 mix_group_removed (); /* EMIT SIGNAL */
2093 Session::mix_group_by_name (string name)
2095 list<RouteGroup *>::iterator i;
2097 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2098 if ((*i)->name() == name) {
2106 Session::edit_group_by_name (string name)
2108 list<RouteGroup *>::iterator i;
2110 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2111 if ((*i)->name() == name) {
2119 Session::begin_reversible_command (string name)
2121 current_trans = new UndoTransaction;
2122 current_trans->set_name (name);
2126 Session::commit_reversible_command (Command *cmd)
2131 current_trans->add_command (cmd);
2134 gettimeofday (&now, 0);
2135 current_trans->set_timestamp (now);
2137 _history.add (current_trans);
2140 Session::GlobalRouteBooleanState
2141 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2143 GlobalRouteBooleanState s;
2144 boost::shared_ptr<RouteList> r = routes.reader ();
2146 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2147 if (!(*i)->hidden()) {
2148 RouteBooleanState v;
2151 Route* r = (*i).get();
2152 v.second = (r->*method)();
2161 Session::GlobalRouteMeterState
2162 Session::get_global_route_metering ()
2164 GlobalRouteMeterState s;
2165 boost::shared_ptr<RouteList> r = routes.reader ();
2167 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2168 if (!(*i)->hidden()) {
2172 v.second = (*i)->meter_point();
2182 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2184 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2186 boost::shared_ptr<Route> r = (i->first.lock());
2189 r->set_meter_point (i->second, arg);
2195 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2197 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2199 boost::shared_ptr<Route> r = (i->first.lock());
2202 Route* rp = r.get();
2203 (rp->*method) (i->second, arg);
2209 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2211 set_global_route_boolean (s, &Route::set_mute, src);
2215 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2217 set_global_route_boolean (s, &Route::set_solo, src);
2221 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2223 set_global_route_boolean (s, &Route::set_record_enable, src);
2228 Session::global_mute_memento (void* src)
2230 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2234 Session::global_metering_memento (void* src)
2236 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2240 Session::global_solo_memento (void* src)
2242 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2246 Session::global_record_enable_memento (void* src)
2248 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2253 template_filter (const string &str, void *arg)
2255 return (str.length() > strlen(Session::template_suffix()) &&
2256 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2260 Session::get_template_list (list<string> &template_names)
2262 vector<string *> *templates;
2263 PathScanner scanner;
2266 path = template_path ();
2268 templates = scanner (path, template_filter, 0, false, true);
2270 vector<string*>::iterator i;
2271 for (i = templates->begin(); i != templates->end(); ++i) {
2272 string fullpath = *(*i);
2275 start = fullpath.find_last_of ('/') + 1;
2276 if ((end = fullpath.find_last_of ('.')) <0) {
2277 end = fullpath.length();
2280 template_names.push_back(fullpath.substr(start, (end-start)));
2285 Session::read_favorite_dirs (FavoriteDirs & favs)
2287 string path = get_user_ardour_path();
2288 path += "/favorite_dirs";
2290 ifstream fav (path.c_str());
2295 if (errno != ENOENT) {
2296 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2307 getline(fav, newfav);
2313 favs.push_back (newfav);
2320 Session::write_favorite_dirs (FavoriteDirs & favs)
2322 string path = get_user_ardour_path();
2323 path += "/favorite_dirs";
2325 ofstream fav (path.c_str());
2331 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2332 fav << (*i) << endl;
2339 accept_all_non_peak_files (const string& path, void *arg)
2341 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2345 accept_all_state_files (const string& path, void *arg)
2347 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2351 Session::find_all_sources (string path, set<string>& result)
2356 if (!tree.read (path)) {
2360 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2365 XMLNodeConstIterator niter;
2367 nlist = node->children();
2371 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2375 if ((prop = (*niter)->property (X_("name"))) == 0) {
2379 if (prop->value()[0] == '/') {
2380 /* external file, ignore */
2384 string path = _path; /* /-terminated */
2385 path += sound_dir_name;
2387 path += prop->value();
2389 result.insert (path);
2396 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2398 PathScanner scanner;
2399 vector<string*>* state_files;
2401 string this_snapshot_path;
2407 if (ripped[ripped.length()-1] == '/') {
2408 ripped = ripped.substr (0, ripped.length() - 1);
2411 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2413 if (state_files == 0) {
2418 this_snapshot_path = _path;
2419 this_snapshot_path += _current_snapshot_name;
2420 this_snapshot_path += _statefile_suffix;
2422 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2424 if (exclude_this_snapshot && **i == this_snapshot_path) {
2428 if (find_all_sources (**i, result) < 0) {
2436 struct RegionCounter {
2437 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2438 AudioSourceList::iterator iter;
2439 boost::shared_ptr<Region> region;
2442 RegionCounter() : count (0) {}
2446 Session::cleanup_sources (Session::cleanup_report& rep)
2448 vector<boost::shared_ptr<Source> > dead_sources;
2449 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2450 PathScanner scanner;
2452 vector<space_and_path>::iterator i;
2453 vector<space_and_path>::iterator nexti;
2454 vector<string*>* soundfiles;
2455 vector<string> unused;
2456 set<string> all_sources;
2461 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2463 /* step 1: consider deleting all unused playlists */
2465 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2468 status = AskAboutPlaylistDeletion (*x);
2477 playlists_tbd.push_back (*x);
2481 /* leave it alone */
2486 /* now delete any that were marked for deletion */
2488 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2489 (*x)->drop_references ();
2492 playlists_tbd.clear ();
2494 /* step 2: find all un-used sources */
2499 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2501 AudioSourceList::iterator tmp;
2506 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2510 if (!i->second->used() && i->second->length() > 0) {
2511 dead_sources.push_back (i->second);
2512 i->second->GoingAway();
2518 /* build a list of all the possible sound directories for the session */
2520 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2525 sound_path += (*i).path;
2526 sound_path += sound_dir (false);
2528 if (nexti != session_dirs.end()) {
2535 /* now do the same thing for the files that ended up in the sounds dir(s)
2536 but are not referenced as sources in any snapshot.
2539 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2541 if (soundfiles == 0) {
2545 /* find all sources, but don't use this snapshot because the
2546 state file on disk still references sources we may have already
2550 find_all_sources_across_snapshots (all_sources, true);
2552 /* add our current source list
2555 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2556 boost::shared_ptr<AudioFileSource> fs;
2558 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2559 all_sources.insert (fs->path());
2563 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2568 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2577 unused.push_back (spath);
2581 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2583 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2584 struct stat statbuf;
2586 rep.paths.push_back (*x);
2587 if (stat ((*x).c_str(), &statbuf) == 0) {
2588 rep.space += statbuf.st_size;
2593 /* don't move the file across filesystems, just
2594 stick it in the `dead_sound_dir_name' directory
2595 on whichever filesystem it was already on.
2598 if (_path.find ("/sounds/")) {
2600 /* old school, go up 1 level */
2602 newpath = Glib::path_get_dirname (*x); // "sounds"
2603 newpath = Glib::path_get_dirname (newpath); // "session-name"
2607 /* new school, go up 4 levels */
2609 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2610 newpath = Glib::path_get_dirname (newpath); // "session-name"
2611 newpath = Glib::path_get_dirname (newpath); // "interchange"
2612 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2616 newpath += dead_sound_dir_name;
2618 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2619 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2624 newpath += Glib::path_get_basename ((*x));
2626 if (access (newpath.c_str(), F_OK) == 0) {
2628 /* the new path already exists, try versioning */
2630 char buf[PATH_MAX+1];
2634 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2637 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2638 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2642 if (version == 999) {
2643 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2647 newpath = newpath_v;
2652 /* it doesn't exist, or we can't read it or something */
2656 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2657 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2658 (*x), newpath, strerror (errno))
2663 /* see if there an easy to find peakfile for this file, and remove it.
2666 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2667 peakpath += ".peak";
2669 if (access (peakpath.c_str(), W_OK) == 0) {
2670 if (::unlink (peakpath.c_str()) != 0) {
2671 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2672 peakpath, _path, strerror (errno))
2674 /* try to back out */
2675 rename (newpath.c_str(), _path.c_str());
2683 /* dump the history list */
2687 /* save state so we don't end up a session file
2688 referring to non-existent sources.
2694 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2699 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2701 vector<space_and_path>::iterator i;
2702 string dead_sound_dir;
2703 struct dirent* dentry;
2704 struct stat statbuf;
2710 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2712 dead_sound_dir = (*i).path;
2713 dead_sound_dir += dead_sound_dir_name;
2715 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2719 while ((dentry = readdir (dead)) != 0) {
2721 /* avoid '.' and '..' */
2723 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2724 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2730 fullpath = dead_sound_dir;
2732 fullpath += dentry->d_name;
2734 if (stat (fullpath.c_str(), &statbuf)) {
2738 if (!S_ISREG (statbuf.st_mode)) {
2742 if (unlink (fullpath.c_str())) {
2743 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2744 fullpath, strerror (errno))
2748 rep.paths.push_back (dentry->d_name);
2749 rep.space += statbuf.st_size;
2760 Session::set_dirty ()
2762 bool was_dirty = dirty();
2764 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2767 DirtyChanged(); /* EMIT SIGNAL */
2773 Session::set_clean ()
2775 bool was_dirty = dirty();
2777 _state_of_the_state = Clean;
2780 DirtyChanged(); /* EMIT SIGNAL */
2785 Session::set_deletion_in_progress ()
2787 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2791 Session::add_controllable (Controllable* c)
2793 Glib::Mutex::Lock lm (controllables_lock);
2794 controllables.insert (c);
2798 Session::remove_controllable (Controllable* c)
2800 if (_state_of_the_state | Deletion) {
2804 Glib::Mutex::Lock lm (controllables_lock);
2806 Controllables::iterator x = controllables.find (c);
2808 if (x != controllables.end()) {
2809 controllables.erase (x);
2814 Session::controllable_by_id (const PBD::ID& id)
2816 Glib::Mutex::Lock lm (controllables_lock);
2818 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2819 if ((*i)->id() == id) {
2828 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2830 Stateful::add_instant_xml (node, dir);
2831 Config->add_instant_xml (node, get_user_ardour_path());
2836 Session::save_history (string snapshot_name)
2842 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2844 if (snapshot_name.empty()) {
2845 snapshot_name = _current_snapshot_name;
2848 xml_path = _path + snapshot_name + ".history";
2850 bak_path = xml_path + ".bak";
2852 if ((access (xml_path.c_str(), F_OK) == 0) &&
2853 (rename (xml_path.c_str(), bak_path.c_str())))
2855 error << _("could not backup old history file, current history not saved.") << endmsg;
2859 if (!tree.write (xml_path))
2861 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2863 /* don't leave a corrupt file lying around if it is
2867 if (unlink (xml_path.c_str())) {
2868 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2870 if (rename (bak_path.c_str(), xml_path.c_str()))
2872 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2883 Session::restore_history (string snapshot_name)
2888 if (snapshot_name.empty()) {
2889 snapshot_name = _current_snapshot_name;
2893 xmlpath = _path + snapshot_name + ".history";
2894 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2896 if (access (xmlpath.c_str(), F_OK)) {
2897 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2901 if (!tree.read (xmlpath)) {
2902 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2906 /* replace history */
2909 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2912 UndoTransaction* ut = new UndoTransaction ();
2915 ut->set_name(t->property("name")->value());
2916 stringstream ss(t->property("tv_sec")->value());
2918 ss.str(t->property("tv_usec")->value());
2920 ut->set_timestamp(tv);
2922 for (XMLNodeConstIterator child_it = t->children().begin();
2923 child_it != t->children().end();
2926 XMLNode *n = *child_it;
2929 if (n->name() == "MementoCommand" ||
2930 n->name() == "MementoUndoCommand" ||
2931 n->name() == "MementoRedoCommand") {
2933 if ((c = memento_command_factory(n))) {
2937 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2939 if ((c = global_state_command_factory (*n))) {
2940 ut->add_command (c);
2945 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2956 Session::config_changed (const char* parameter_name)
2958 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2960 if (PARAM_IS ("seamless-loop")) {
2962 } else if (PARAM_IS ("rf-speed")) {
2964 } else if (PARAM_IS ("auto-loop")) {
2966 } else if (PARAM_IS ("auto-input")) {
2968 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2969 /* auto-input only makes a difference if we're rolling */
2971 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2973 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2974 if ((*i)->record_enabled ()) {
2975 (*i)->monitor_input (!Config->get_auto_input());
2980 } else if (PARAM_IS ("punch-in")) {
2984 if ((location = _locations.auto_punch_location()) != 0) {
2986 if (Config->get_punch_in ()) {
2987 replace_event (Event::PunchIn, location->start());
2989 remove_event (location->start(), Event::PunchIn);
2993 } else if (PARAM_IS ("punch-out")) {
2997 if ((location = _locations.auto_punch_location()) != 0) {
2999 if (Config->get_punch_out()) {
3000 replace_event (Event::PunchOut, location->end());
3002 clear_events (Event::PunchOut);
3006 } else if (PARAM_IS ("edit-mode")) {
3008 Glib::Mutex::Lock lm (playlist_lock);
3010 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3011 (*i)->set_edit_mode (Config->get_edit_mode ());
3014 } else if (PARAM_IS ("use-video-sync")) {
3016 if (transport_stopped()) {
3017 if (Config->get_use_video_sync()) {
3018 waiting_for_sync_offset = true;
3022 } else if (PARAM_IS ("mmc-control")) {
3024 poke_midi_thread ();
3026 } else if (PARAM_IS ("midi-control")) {
3028 poke_midi_thread ();
3030 } else if (PARAM_IS ("raid-path")) {
3032 setup_raid_path (Config->get_raid_path());
3034 } else if (PARAM_IS ("smpte-format")) {
3038 } else if (PARAM_IS ("video-pullup")) {
3042 } else if (PARAM_IS ("seamless-loop")) {
3044 if (play_loop && transport_rolling()) {
3045 // to reset diskstreams etc
3046 request_play_loop (true);
3049 } else if (PARAM_IS ("rf-speed")) {
3051 cumulative_rf_motion = 0;
3054 } else if (PARAM_IS ("click-sound")) {
3056 setup_click_sounds (1);
3058 } else if (PARAM_IS ("click-emphasis-sound")) {
3060 setup_click_sounds (-1);
3062 } else if (PARAM_IS ("clicking")) {
3064 if (Config->get_clicking()) {
3065 if (_click_io && click_data) { // don't require emphasis data
3072 } else if (PARAM_IS ("send-mtc")) {
3074 /* only set the internal flag if we have
3078 if (_mtc_port != 0) {
3079 session_send_mtc = Config->get_send_mtc();
3080 if (session_send_mtc) {
3081 /* mark us ready to send */
3082 next_quarter_frame_to_send = 0;
3086 } else if (PARAM_IS ("send-mmc")) {
3088 /* only set the internal flag if we have
3092 if (_mmc_port != 0) {
3093 session_send_mmc = Config->get_send_mmc();
3096 } else if (PARAM_IS ("midi-feedback")) {
3098 /* only set the internal flag if we have
3102 if (_mtc_port != 0) {
3103 session_midi_feedback = Config->get_midi_feedback();
3106 } else if (PARAM_IS ("jack-time-master")) {
3108 engine().reset_timebase ();
3110 } else if (PARAM_IS ("native-file-header-format")) {
3112 if (!first_file_header_format_reset) {
3113 reset_native_file_format ();
3116 first_file_header_format_reset = false;
3118 } else if (PARAM_IS ("native-file-data-format")) {
3120 if (!first_file_data_format_reset) {
3121 reset_native_file_format ();
3124 first_file_data_format_reset = false;
3126 } else if (PARAM_IS ("slave-source")) {
3127 set_slave_source (Config->get_slave_source());