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/mount.h>
44 #include <sys/param.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>
58 #include <ardour/audioengine.h>
59 #include <ardour/configuration.h>
60 #include <ardour/session.h>
61 #include <ardour/buffer.h>
62 #include <ardour/audio_diskstream.h>
63 #include <ardour/midi_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/midi_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>
92 using namespace ARDOUR;
96 Session::first_stage_init (string fullpath, string snapshot_name)
98 if (fullpath.length() == 0) {
99 throw failed_constructor();
102 char buf[PATH_MAX+1];
103 if (!realpath(fullpath.c_str(), buf) && (errno != ENOENT)) {
104 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
105 throw failed_constructor();
109 if (_path[_path.length()-1] != '/') {
113 /* these two are just provisional settings. set_state()
114 will likely override them.
117 _name = _current_snapshot_name = snapshot_name;
118 setup_raid_path (_path);
120 _current_frame_rate = _engine.frame_rate ();
121 _tempo_map = new TempoMap (_current_frame_rate);
122 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
124 g_atomic_int_set (&processing_prohibited, 0);
127 _transport_speed = 0;
128 _last_transport_speed = 0;
129 transport_sub_state = 0;
130 _transport_frame = 0;
132 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
133 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
134 _end_location_is_free = true;
135 g_atomic_int_set (&_record_status, Disabled);
140 seamless_loop = false;
141 loop_changing = false;
143 crossfades_active = false;
146 _last_roll_location = 0;
147 _last_record_location = 0;
148 pending_locate_frame = 0;
149 pending_locate_roll = false;
150 pending_locate_flush = false;
151 dstream_buffer_size = 0;
153 state_was_pending = false;
155 outbound_mtc_smpte_frame = 0;
156 next_quarter_frame_to_send = -1;
157 current_block_size = 0;
158 _solo_latched = true;
159 _solo_model = InverseMute;
160 solo_update_disabled = false;
161 currently_soloing = false;
162 _have_captured = false;
163 _worst_output_latency = 0;
164 _worst_input_latency = 0;
165 _worst_track_latency = 0;
166 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
169 butler_mixdown_buffer = 0;
170 butler_gain_buffer = 0;
174 post_transport_work = PostTransportWork (0);
175 g_atomic_int_set (&butler_should_do_transport_work, 0);
176 g_atomic_int_set (&butler_active, 0);
177 g_atomic_int_set (&_playback_load, 100);
178 g_atomic_int_set (&_capture_load, 100);
179 g_atomic_int_set (&_playback_load_min, 100);
180 g_atomic_int_set (&_capture_load_min, 100);
181 pending_audition_region = 0;
183 pending_edit_mode = _edit_mode;
185 input_auto_connect = AutoConnectOption (0);
186 output_auto_connect = AutoConnectOption (0);
187 waiting_to_start = false;
189 _gain_automation_buffer = 0;
190 _pan_automation_buffer = 0;
192 pending_abort = false;
193 layer_model = MoveAddHigher;
194 xfade_model = ShortCrossfade;
195 destructive_index = 0;
197 /* allocate conversion buffers */
198 _conversion_buffers[ButlerContext] = new char[AudioDiskstream::disk_io_frames() * 4];
199 _conversion_buffers[TransportContext] = new char[AudioDiskstream::disk_io_frames() * 4];
200 AudioDiskstream::allocate_working_buffers();
202 /* default short fade = 15ms */
204 Crossfade::set_short_xfade_length ((jack_nframes_t) floor ((15.0 * frame_rate()) / 1000.0));
205 DestructiveFileSource::setup_standard_crossfades (frame_rate());
207 last_mmc_step.tv_sec = 0;
208 last_mmc_step.tv_usec = 0;
211 preroll.type = AnyTime::Frames;
213 postroll.type = AnyTime::Frames;
216 /* click sounds are unset by default, which causes us to internal
217 waveforms for clicks.
221 click_requested = false;
223 click_emphasis_data = 0;
225 click_emphasis_length = 0;
227 process_function = &Session::process_with_events;
231 _smpte_offset_negative = true;
232 last_smpte_valid = false;
234 last_rr_session_dir = session_dirs.begin();
235 refresh_disk_space ();
237 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
239 /* default configuration */
241 do_not_record_plugins = false;
242 over_length_short = 2;
243 over_length_long = 10;
244 send_midi_timecode = false;
245 send_midi_machine_control = false;
246 shuttle_speed_factor = 1.0;
247 shuttle_speed_threshold = 5;
249 _meter_hold = 100; // XXX unknown units: number of calls to meter::set()
250 _meter_falloff = 1.5f; // XXX unknown units: refresh_rate
256 average_slave_delta = 1800;
257 have_first_delta_accumulator = false;
258 delta_accumulator_cnt = 0;
259 slave_state = Stopped;
261 /* default SMPTE type is 30 FPS, non-drop */
263 set_smpte_type (30.0, false);
265 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
267 /* These are all static "per-class" signals */
269 Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
270 AudioSource::AudioSourceCreated.connect (mem_fun (*this, &Session::add_audio_source));
271 Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
272 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
273 Diskstream::DiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
274 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
276 Controllable::Created.connect (mem_fun (*this, &Session::add_controllable));
277 Controllable::GoingAway.connect (mem_fun (*this, &Session::remove_controllable));
279 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
281 /* stop IO objects from doing stuff until we're ready for them */
283 IO::disable_panners ();
284 IO::disable_ports ();
285 IO::disable_connecting ();
289 Session::second_stage_init (bool new_session)
291 AudioFileSource::set_peak_dir (peak_dir());
294 if (load_state (_current_snapshot_name)) {
297 remove_empty_sounds ();
300 if (start_butler_thread()) {
304 /*if (start_midi_thread ()) {
309 if (set_state (*state_tree->root())) {
314 /* we can't save till after ::when_engine_running() is called,
315 because otherwise we save state with no connections made.
316 therefore, we reset _state_of_the_state because ::set_state()
317 will have cleared it.
319 we also have to include Loading so that any events that get
320 generated between here and the end of ::when_engine_running()
321 will be processed directly rather than queued.
324 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
326 // set_auto_input (true);
327 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
328 _locations.added.connect (mem_fun (this, &Session::locations_added));
329 setup_click_sounds (0);
330 setup_midi_control ();
332 /* Pay attention ... */
334 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
335 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
337 if (_engine.running()) {
338 when_engine_running();
340 first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
343 //send_full_time_code ();
344 _engine.transport_locate (0);
345 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
346 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
348 ControlProtocolManager::instance().set_session (*this);
351 _end_location_is_free = true;
353 _end_location_is_free = false;
360 Session::raid_path () const
364 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
369 return path.substr (0, path.length() - 1); // drop final colon
373 Session::set_raid_path (string path)
375 /* public-access to setup_raid_path() */
377 setup_raid_path (path);
381 Session::setup_raid_path (string path)
383 string::size_type colon;
387 string::size_type len = path.length();
392 if (path.length() == 0) {
396 session_dirs.clear ();
398 for (string::size_type n = 0; n < len; ++n) {
399 if (path[n] == ':') {
406 /* no multiple search path, just one location (common case) */
410 session_dirs.push_back (sp);
417 if (fspath[fspath.length()-1] != '/') {
420 fspath += sound_dir_name;
426 if (fspath[fspath.length()-1] != '/') {
429 fspath += tape_dir_name;
431 AudioFileSource::set_search_path (fspath);
438 while ((colon = remaining.find_first_of (':')) != string::npos) {
441 sp.path = remaining.substr (0, colon);
442 session_dirs.push_back (sp);
444 /* add sounds to file search path */
447 if (fspath[fspath.length()-1] != '/') {
450 fspath += sound_dir_name;
453 /* add tape dir to file search path */
456 if (fspath[fspath.length()-1] != '/') {
459 fspath += tape_dir_name;
462 remaining = remaining.substr (colon+1);
465 if (remaining.length()) {
472 if (fspath[fspath.length()-1] != '/') {
475 fspath += sound_dir_name;
479 if (fspath[fspath.length()-1] != '/') {
482 fspath += tape_dir_name;
484 session_dirs.push_back (sp);
487 /* set the AudioFileSource search path */
489 AudioFileSource::set_search_path (fspath);
491 /* reset the round-robin soundfile path thingie */
493 last_rr_session_dir = session_dirs.begin();
497 Session::create (bool& new_session, string* mix_template, jack_nframes_t initial_length)
501 if (mkdir (_path.c_str(), 0755) < 0) {
502 if (errno == EEXIST) {
505 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
514 if (mkdir (dir.c_str(), 0755) < 0) {
515 if (errno != EEXIST) {
516 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
523 if (mkdir (dir.c_str(), 0755) < 0) {
524 if (errno != EEXIST) {
525 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
532 if (mkdir (dir.c_str(), 0755) < 0) {
533 if (errno != EEXIST) {
534 error << string_compose(_("Session: cannot create session tape dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
539 dir = dead_sound_dir ();
541 if (mkdir (dir.c_str(), 0755) < 0) {
542 if (errno != EEXIST) {
543 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
548 dir = automation_dir ();
550 if (mkdir (dir.c_str(), 0755) < 0) {
551 if (errno != EEXIST) {
552 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
558 /* check new_session so we don't overwrite an existing one */
562 std::string in_path = *mix_template;
564 ifstream in(in_path.c_str());
567 string out_path = _path;
569 out_path += _statefile_suffix;
571 ofstream out(out_path.c_str());
576 // okay, session is set up. Treat like normal saved
577 // session from now on.
583 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
589 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
596 warning << _("Session already exists. Not overwriting") << endmsg;
603 /* set initial start + end point */
605 start_location->set_end (0);
606 _locations.add (start_location);
608 end_location->set_end (initial_length);
609 _locations.add (end_location);
611 _state_of_the_state = Clean;
613 if (save_state (_current_snapshot_name)) {
622 Session::load_diskstreams (const XMLNode& node)
625 XMLNodeConstIterator citer;
627 clist = node.children();
629 for (citer = clist.begin(); citer != clist.end(); ++citer) {
630 Diskstream* dstream = NULL;
633 if ((*citer)->name() == "AudioDiskstream") {
634 dstream = new AudioDiskstream (*this, **citer);
635 /* added automatically by DiskstreamCreated handler */
637 assert((*citer)->name() == "MidiDiskstream");
638 dstream = new MidiDiskstream (*this, **citer);
642 catch (failed_constructor& err) {
643 error << _("Session: could not load diskstream via XML state") << endmsg;
652 Session::remove_pending_capture_state ()
657 xml_path += _current_snapshot_name;
658 xml_path += _pending_suffix;
660 unlink (xml_path.c_str());
664 Session::save_state (string snapshot_name, bool pending)
670 if (_state_of_the_state & CannotSave) {
674 tree.set_root (&get_state());
676 if (snapshot_name.empty()) {
677 snapshot_name = _current_snapshot_name;
683 xml_path += snapshot_name;
684 xml_path += _statefile_suffix;
688 // Make backup of state file
690 if ((access (xml_path.c_str(), F_OK) == 0) &&
691 (rename(xml_path.c_str(), bak_path.c_str()))) {
692 error << _("could not backup old state file, current state not saved.") << endmsg;
699 xml_path += snapshot_name;
700 xml_path += _pending_suffix;
704 if (!tree.write (xml_path)) {
705 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
707 /* don't leave a corrupt file lying around if it is
711 if (unlink (xml_path.c_str())) {
712 error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
715 if (rename (bak_path.c_str(), xml_path.c_str())) {
716 error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
726 bool was_dirty = dirty();
728 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
731 DirtyChanged (); /* EMIT SIGNAL */
734 StateSaved (snapshot_name); /* EMIT SIGNAL */
741 Session::restore_state (string snapshot_name)
743 if (load_state (snapshot_name) == 0) {
744 set_state (*state_tree->root());
751 Session::load_state (string snapshot_name)
760 state_was_pending = false;
762 /* check for leftover pending state from a crashed capture attempt */
765 xmlpath += snapshot_name;
766 xmlpath += _pending_suffix;
768 if (!access (xmlpath.c_str(), F_OK)) {
770 /* there is pending state from a crashed capture attempt */
772 if (AskAboutPendingState()) {
773 state_was_pending = true;
777 if (!state_was_pending) {
780 xmlpath += snapshot_name;
781 xmlpath += _statefile_suffix;
784 if (access (xmlpath.c_str(), F_OK)) {
785 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
789 state_tree = new XMLTree;
793 if (state_tree->read (xmlpath)) {
796 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
805 Session::load_options (const XMLNode& node)
809 bool have_fade_msecs = false;
810 bool have_fade_steepness = false;
811 float fade_msecs = 0;
812 float fade_steepness = 0;
813 SlaveSource slave_src = None;
815 LocaleGuard lg (X_("POSIX"));
817 if ((child = find_named_node (node, "input-auto-connect")) != 0) {
818 if ((prop = child->property ("val")) != 0) {
819 sscanf (prop->value().c_str(), "%x", &x);
820 input_auto_connect = AutoConnectOption (x);
824 if ((child = find_named_node (node, "output-auto-connect")) != 0) {
825 if ((prop = child->property ("val")) != 0) {
826 sscanf (prop->value().c_str(), "%x", &x);
827 output_auto_connect = AutoConnectOption (x);
831 if ((child = find_named_node (node, "slave")) != 0) {
832 if ((prop = child->property ("type")) != 0) {
833 if (prop->value() == "none") {
835 } else if (prop->value() == "mtc") {
837 } else if (prop->value() == "jack") {
840 set_slave_source (slave_src, 0);
844 /* we cannot set edit mode if we are loading a session,
845 because it might destroy the playlist's positioning
848 if ((child = find_named_node (node, "edit-mode")) != 0) {
849 if ((prop = child->property ("val")) != 0) {
850 if (prop->value() == "slide") {
851 pending_edit_mode = Slide;
852 } else if (prop->value() == "splice") {
853 pending_edit_mode = Splice;
858 if ((child = find_named_node (node, "send-midi-timecode")) != 0) {
859 if ((prop = child->property ("val")) != 0) {
860 bool x = (prop->value() == "yes");
861 send_mtc = !x; /* force change in value */
865 if ((child = find_named_node (node, "send-midi-machine-control")) != 0) {
866 if ((prop = child->property ("val")) != 0) {
867 bool x = (prop->value() == "yes");
868 send_mmc = !x; /* force change in value */
869 set_send_mmc (prop->value() == "yes");
872 if ((child = find_named_node (node, "max-level")) != 0) {
873 if ((prop = child->property ("val")) != 0) {
874 max_level = atoi (prop->value().c_str());
877 if ((child = find_named_node (node, "min-level")) != 0) {
878 if ((prop = child->property ("val")) != 0) {
879 min_level = atoi (prop->value().c_str());
882 if ((child = find_named_node (node, "meter-hold")) != 0) {
883 if ((prop = child->property ("val")) != 0) {
884 _meter_hold = atof (prop->value().c_str());
887 if ((child = find_named_node (node, "meter-falloff")) != 0) {
888 if ((prop = child->property ("val")) != 0) {
889 _meter_falloff = atof (prop->value().c_str());
892 if ((child = find_named_node (node, "long-over-length")) != 0) {
893 if ((prop = child->property ("val")) != 0) {
894 over_length_long = atoi (prop->value().c_str());
897 if ((child = find_named_node (node, "short-over-length")) != 0) {
898 if ((prop = child->property ("val")) != 0) {
899 over_length_short = atoi (prop->value().c_str());
902 if ((child = find_named_node (node, "shuttle-speed-factor")) != 0) {
903 if ((prop = child->property ("val")) != 0) {
904 shuttle_speed_factor = atof (prop->value().c_str());
907 if ((child = find_named_node (node, "shuttle-speed-threshold")) != 0) {
908 if ((prop = child->property ("val")) != 0) {
909 shuttle_speed_threshold = atof (prop->value().c_str());
912 if ((child = find_named_node (node, "rf-speed")) != 0) {
913 if ((prop = child->property ("val")) != 0) {
914 rf_speed = atof (prop->value().c_str());
917 if ((child = find_named_node (node, "smpte-frames-per-second")) != 0) {
918 if ((prop = child->property ("val")) != 0) {
919 set_smpte_type( atof (prop->value().c_str()), smpte_drop_frames );
922 if ((child = find_named_node (node, "smpte-drop-frames")) != 0) {
923 if ((prop = child->property ("val")) != 0) {
924 set_smpte_type( smpte_frames_per_second, (prop->value() == "yes") );
927 if ((child = find_named_node (node, "smpte-offset")) != 0) {
928 if ((prop = child->property ("val")) != 0) {
929 set_smpte_offset( atoi (prop->value().c_str()) );
932 if ((child = find_named_node (node, "smpte-offset-negative")) != 0) {
933 if ((prop = child->property ("val")) != 0) {
934 set_smpte_offset_negative( (prop->value() == "yes") );
937 if ((child = find_named_node (node, "click-sound")) != 0) {
938 if ((prop = child->property ("val")) != 0) {
939 click_sound = prop->value();
942 if ((child = find_named_node (node, "click-emphasis-sound")) != 0) {
943 if ((prop = child->property ("val")) != 0) {
944 click_emphasis_sound = prop->value();
948 if ((child = find_named_node (node, "solo-model")) != 0) {
949 if ((prop = child->property ("val")) != 0) {
950 if (prop->value() == "SoloBus")
951 _solo_model = SoloBus;
953 _solo_model = InverseMute;
957 /* BOOLEAN OPTIONS */
959 if ((child = find_named_node (node, "auto-play")) != 0) {
960 if ((prop = child->property ("val")) != 0) {
961 set_auto_play (prop->value() == "yes");
964 if ((child = find_named_node (node, "auto-input")) != 0) {
965 if ((prop = child->property ("val")) != 0) {
966 set_auto_input (prop->value() == "yes");
969 if ((child = find_named_node (node, "seamless-loop")) != 0) {
970 if ((prop = child->property ("val")) != 0) {
971 set_seamless_loop (prop->value() == "yes");
974 if ((child = find_named_node (node, "punch-in")) != 0) {
975 if ((prop = child->property ("val")) != 0) {
976 set_punch_in (prop->value() == "yes");
979 if ((child = find_named_node (node, "punch-out")) != 0) {
980 if ((prop = child->property ("val")) != 0) {
981 set_punch_out (prop->value() == "yes");
984 if ((child = find_named_node (node, "auto-return")) != 0) {
985 if ((prop = child->property ("val")) != 0) {
986 set_auto_return (prop->value() == "yes");
989 if ((child = find_named_node (node, "send-mtc")) != 0) {
990 if ((prop = child->property ("val")) != 0) {
991 set_send_mtc (prop->value() == "yes");
994 if ((child = find_named_node (node, "mmc-control")) != 0) {
995 if ((prop = child->property ("val")) != 0) {
996 set_mmc_control (prop->value() == "yes");
999 if ((child = find_named_node (node, "midi-control")) != 0) {
1000 if ((prop = child->property ("val")) != 0) {
1001 set_midi_control (prop->value() == "yes");
1004 if ((child = find_named_node (node, "midi-feedback")) != 0) {
1005 if ((prop = child->property ("val")) != 0) {
1006 set_midi_feedback (prop->value() == "yes");
1009 // Legacy support for <recording-plugins>
1010 if ((child = find_named_node (node, "recording-plugins")) != 0) {
1011 if ((prop = child->property ("val")) != 0) {
1012 set_do_not_record_plugins (prop->value() == "no");
1015 if ((child = find_named_node (node, "do-not-record-plugins")) != 0) {
1016 if ((prop = child->property ("val")) != 0) {
1017 set_do_not_record_plugins (prop->value() == "yes");
1020 if ((child = find_named_node (node, "crossfades-active")) != 0) {
1021 if ((prop = child->property ("val")) != 0) {
1022 set_crossfades_active (prop->value() == "yes");
1025 if ((child = find_named_node (node, "audible-click")) != 0) {
1026 if ((prop = child->property ("val")) != 0) {
1027 set_clicking (prop->value() == "yes");
1031 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
1032 if ((prop = child->property ("val")) != 0) {
1033 _end_location_is_free = (prop->value() == "yes");
1037 if ((child = find_named_node (node, "layer-model")) != 0) {
1038 if ((prop = child->property ("val")) != 0) {
1039 if (prop->value() == X_("LaterHigher")) {
1040 set_layer_model (LaterHigher);
1041 } else if (prop->value() == X_("AddHigher")) {
1042 set_layer_model (AddHigher);
1044 set_layer_model (MoveAddHigher);
1049 if ((child = find_named_node (node, "xfade-model")) != 0) {
1050 if ((prop = child->property ("val")) != 0) {
1051 if (prop->value() == X_("Short")) {
1052 set_xfade_model (ShortCrossfade);
1054 set_xfade_model (FullCrossfade);
1059 if ((child = find_named_node (node, "short-xfade-length")) != 0) {
1060 if ((prop = child->property ("val")) != 0) {
1061 /* value is stored as a fractional seconds */
1062 float secs = atof (prop->value().c_str());
1063 Crossfade::set_short_xfade_length ((jack_nframes_t) floor (secs * frame_rate()));
1067 if ((child = find_named_node (node, "full-xfades-unmuted")) != 0) {
1068 if ((prop = child->property ("val")) != 0) {
1069 crossfades_active = (prop->value() == "yes");
1075 if ((child = find_named_node (node, "default-fade-steepness")) != 0) {
1076 if ((prop = child->property ("val")) != 0) {
1077 fade_steepness = atof (prop->value().c_str());
1078 have_fade_steepness = true;
1081 if ((child = find_named_node (node, "default-fade-msec")) != 0) {
1082 if ((prop = child->property ("val")) != 0) {
1083 fade_msecs = atof (prop->value().c_str());
1084 have_fade_msecs = true;
1088 if (have_fade_steepness || have_fade_msecs) {
1089 // set_default_fade (fade_steepness, fade_msecs);
1096 Session::get_options () const
1101 LocaleGuard lg (X_("POSIX"));
1103 opthead = new XMLNode ("Options");
1105 SlaveSource src = slave_source ();
1109 src_string = "none";
1115 src_string = "jack";
1118 child = opthead->add_child ("slave");
1119 child->add_property ("type", src_string);
1121 child = opthead->add_child ("send-midi-timecode");
1122 child->add_property ("val", send_midi_timecode?"yes":"no");
1124 child = opthead->add_child ("send-midi-machine-control");
1125 child->add_property ("val", send_midi_machine_control?"yes":"no");
1127 snprintf (buf, sizeof(buf)-1, "%x", (int) input_auto_connect);
1128 child = opthead->add_child ("input-auto-connect");
1129 child->add_property ("val", buf);
1131 snprintf (buf, sizeof(buf)-1, "%x", (int) output_auto_connect);
1132 child = opthead->add_child ("output-auto-connect");
1133 child->add_property ("val", buf);
1135 snprintf (buf, sizeof(buf)-1, "%d", max_level);
1136 child = opthead->add_child ("max-level");
1137 child->add_property ("val", buf);
1139 snprintf (buf, sizeof(buf)-1, "%d", min_level);
1140 child = opthead->add_child ("min-level");
1141 child->add_property ("val", buf);
1143 snprintf (buf, sizeof(buf)-1, "%f", _meter_hold);
1144 child = opthead->add_child ("meter-hold");
1145 child->add_property ("val", buf);
1147 snprintf (buf, sizeof(buf)-1, "%f", _meter_falloff);
1148 child = opthead->add_child ("meter-falloff");
1149 child->add_property ("val", buf);
1151 snprintf (buf, sizeof(buf)-1, "%u", over_length_long);
1152 child = opthead->add_child ("long-over-length");
1153 child->add_property ("val", buf);
1155 snprintf (buf, sizeof(buf)-1, "%u", over_length_short);
1156 child = opthead->add_child ("short-over-length");
1157 child->add_property ("val", buf);
1159 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_factor);
1160 child = opthead->add_child ("shuttle-speed-factor");
1161 child->add_property ("val", buf);
1163 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_threshold);
1164 child = opthead->add_child ("shuttle-speed-threshold");
1165 child->add_property ("val", buf);
1167 snprintf (buf, sizeof(buf)-1, "%f", rf_speed);
1168 child = opthead->add_child ("rf-speed");
1169 child->add_property ("val", buf);
1171 snprintf (buf, sizeof(buf)-1, "%.2f", smpte_frames_per_second);
1172 child = opthead->add_child ("smpte-frames-per-second");
1173 child->add_property ("val", buf);
1175 child = opthead->add_child ("smpte-drop-frames");
1176 child->add_property ("val", smpte_drop_frames ? "yes" : "no");
1178 snprintf (buf, sizeof(buf)-1, "%u", smpte_offset ());
1179 child = opthead->add_child ("smpte-offset");
1180 child->add_property ("val", buf);
1182 child = opthead->add_child ("smpte-offset-negative");
1183 child->add_property ("val", smpte_offset_negative () ? "yes" : "no");
1185 child = opthead->add_child ("edit-mode");
1186 switch (_edit_mode) {
1188 child->add_property ("val", "splice");
1192 child->add_property ("val", "slide");
1196 child = opthead->add_child ("auto-play");
1197 child->add_property ("val", get_auto_play () ? "yes" : "no");
1198 child = opthead->add_child ("auto-input");
1199 child->add_property ("val", get_auto_input () ? "yes" : "no");
1200 child = opthead->add_child ("seamless-loop");
1201 child->add_property ("val", get_seamless_loop () ? "yes" : "no");
1202 child = opthead->add_child ("punch-in");
1203 child->add_property ("val", get_punch_in () ? "yes" : "no");
1204 child = opthead->add_child ("punch-out");
1205 child->add_property ("val", get_punch_out () ? "yes" : "no");
1206 child = opthead->add_child ("all-safe");
1207 child->add_property ("val", get_all_safe () ? "yes" : "no");
1208 child = opthead->add_child ("auto-return");
1209 child->add_property ("val", get_auto_return () ? "yes" : "no");
1210 child = opthead->add_child ("mmc-control");
1211 child->add_property ("val", get_mmc_control () ? "yes" : "no");
1212 child = opthead->add_child ("midi-control");
1213 child->add_property ("val", get_midi_control () ? "yes" : "no");
1214 child = opthead->add_child ("midi-feedback");
1215 child->add_property ("val", get_midi_feedback () ? "yes" : "no");
1216 child = opthead->add_child ("do-not-record-plugins");
1217 child->add_property ("val", get_do_not_record_plugins () ? "yes" : "no");
1218 child = opthead->add_child ("auto-crossfade");
1219 child->add_property ("val", get_crossfades_active () ? "yes" : "no");
1220 child = opthead->add_child ("audible-click");
1221 child->add_property ("val", get_clicking () ? "yes" : "no");
1222 child = opthead->add_child ("end-marker-is-free");
1223 child->add_property ("val", _end_location_is_free ? "yes" : "no");
1225 if (click_sound.length()) {
1226 child = opthead->add_child ("click-sound");
1227 child->add_property ("val", click_sound);
1230 if (click_emphasis_sound.length()) {
1231 child = opthead->add_child ("click-emphasis-sound");
1232 child->add_property ("val", click_emphasis_sound);
1235 child = opthead->add_child ("solo-model");
1236 child->add_property ("val", _solo_model == SoloBus ? "SoloBus" : "InverseMute");
1238 child = opthead->add_child ("layer-model");
1239 switch (layer_model) {
1241 child->add_property ("val", X_("LaterHigher"));
1244 child->add_property ("val", X_("MoveAddHigher"));
1247 child->add_property ("val", X_("AddHigher"));
1251 child = opthead->add_child ("xfade-model");
1252 switch (xfade_model) {
1254 child->add_property ("val", X_("Full"));
1256 case ShortCrossfade:
1257 child->add_property ("val", X_("Short"));
1260 child = opthead->add_child ("short-xfade-length");
1261 /* store as fractions of a second */
1262 snprintf (buf, sizeof(buf)-1, "%f",
1263 (float) Crossfade::short_xfade_length() / frame_rate());
1264 child->add_property ("val", buf);
1266 child = opthead->add_child ("full-xfades-unmuted");
1267 child->add_property ("val", crossfades_active ? "yes" : "no");
1273 Session::get_state()
1279 Session::get_template()
1281 /* if we don't disable rec-enable, diskstreams
1282 will believe they need to store their capture
1283 sources in their state node.
1286 disable_record (false);
1288 return state(false);
1292 Session::state(bool full_state)
1294 XMLNode* node = new XMLNode("Session");
1297 // store libardour version, just in case
1299 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
1300 libardour_major_version, libardour_minor_version, libardour_micro_version);
1301 node->add_property("version", string(buf));
1303 /* store configuration settings */
1307 /* store the name */
1308 node->add_property ("name", _name);
1310 if (session_dirs.size() > 1) {
1314 vector<space_and_path>::iterator i = session_dirs.begin();
1315 vector<space_and_path>::iterator next;
1317 ++i; /* skip the first one */
1321 while (i != session_dirs.end()) {
1325 if (next != session_dirs.end()) {
1335 child = node->add_child ("Path");
1336 child->add_content (p);
1340 /* save the ID counter */
1342 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1343 node->add_property ("id-counter", buf);
1345 /* various options */
1347 node->add_child_nocopy (get_options());
1349 child = node->add_child ("Sources");
1352 Glib::Mutex::Lock sl (audio_source_lock);
1354 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
1356 /* Don't save information about AudioFileSources that are empty */
1358 AudioFileSource* fs;
1360 if ((fs = dynamic_cast<AudioFileSource*> (siter->second)) != 0) {
1361 DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
1363 /* destructive file sources are OK if they are empty, because
1364 we will re-use them every time.
1368 if (fs->length() == 0) {
1374 child->add_child_nocopy (siter->second->get_state());
1378 child = node->add_child ("Regions");
1381 Glib::Mutex::Lock rl (region_lock);
1383 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1385 /* only store regions not attached to playlists */
1387 if (i->second->playlist() == 0) {
1388 child->add_child_nocopy (i->second->state (true));
1393 child = node->add_child ("DiskStreams");
1396 Glib::RWLock::ReaderLock dl (diskstream_lock);
1397 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1398 if (!(*i)->hidden()) {
1399 child->add_child_nocopy ((*i)->get_state());
1404 node->add_child_nocopy (_locations.get_state());
1406 child = node->add_child ("Connections");
1408 Glib::Mutex::Lock lm (connection_lock);
1409 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1410 if (!(*i)->system_dependent()) {
1411 child->add_child_nocopy ((*i)->get_state());
1416 child = node->add_child ("Routes");
1418 boost::shared_ptr<RouteList> r = routes.reader ();
1420 RoutePublicOrderSorter cmp;
1421 RouteList public_order (*r);
1422 public_order.sort (cmp);
1424 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1425 if (!(*i)->hidden()) {
1427 child->add_child_nocopy ((*i)->get_state());
1429 child->add_child_nocopy ((*i)->get_template());
1436 child = node->add_child ("EditGroups");
1437 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1438 child->add_child_nocopy ((*i)->get_state());
1441 child = node->add_child ("MixGroups");
1442 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1443 child->add_child_nocopy ((*i)->get_state());
1446 child = node->add_child ("Playlists");
1447 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1448 if (!(*i)->hidden()) {
1449 if (!(*i)->empty()) {
1451 child->add_child_nocopy ((*i)->get_state());
1453 child->add_child_nocopy ((*i)->get_template());
1459 child = node->add_child ("UnusedPlaylists");
1460 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1461 if (!(*i)->hidden()) {
1462 if (!(*i)->empty()) {
1464 child->add_child_nocopy ((*i)->get_state());
1466 child->add_child_nocopy ((*i)->get_template());
1474 child = node->add_child ("Click");
1475 child->add_child_nocopy (_click_io->state (full_state));
1479 child = node->add_child ("NamedSelections");
1480 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1482 child->add_child_nocopy ((*i)->get_state());
1487 node->add_child_nocopy (_tempo_map->get_state());
1490 node->add_child_copy (*_extra_xml);
1497 Session::set_state (const XMLNode& node)
1501 const XMLProperty* prop;
1504 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1506 if (node.name() != X_("Session")){
1507 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1511 StateManager::prohibit_save ();
1513 if ((prop = node.property ("name")) != 0) {
1514 _name = prop->value ();
1517 if ((prop = node.property (X_("id-counter"))) != 0) {
1519 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1520 ID::init_counter (x);
1522 /* old sessions used a timebased counter, so fake
1523 the startup ID counter based on a standard
1528 ID::init_counter (now);
1532 IO::disable_ports ();
1533 IO::disable_connecting ();
1535 /* Object loading order:
1552 if (use_config_midi_ports ()) {
1555 if ((child = find_named_node (node, "Path")) != 0) {
1556 /* XXX this XML content stuff horrible API design */
1557 string raid_path = _path + ':' + child->children().front()->content();
1558 setup_raid_path (raid_path);
1560 /* the path is already set */
1563 if ((child = find_named_node (node, "extra")) != 0) {
1564 _extra_xml = new XMLNode (*child);
1567 if ((child = find_named_node (node, "Options")) == 0) {
1568 error << _("Session: XML state has no options section") << endmsg;
1569 } else if (load_options (*child)) {
1572 if ((child = find_named_node (node, "Sources")) == 0) {
1573 error << _("Session: XML state has no sources section") << endmsg;
1575 } else if (load_sources (*child)) {
1579 if ((child = find_named_node (node, "Regions")) == 0) {
1580 error << _("Session: XML state has no Regions section") << endmsg;
1582 } else if (load_regions (*child)) {
1586 if ((child = find_named_node (node, "Playlists")) == 0) {
1587 error << _("Session: XML state has no playlists section") << endmsg;
1589 } else if (load_playlists (*child)) {
1593 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1595 } else if (load_unused_playlists (*child)) {
1599 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1600 if (load_named_selections (*child)) {
1605 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1606 error << _("Session: XML state has no diskstreams section") << endmsg;
1608 } else if (load_diskstreams (*child)) {
1612 if ((child = find_named_node (node, "Connections")) == 0) {
1613 error << _("Session: XML state has no connections section") << endmsg;
1615 } else if (load_connections (*child)) {
1619 if ((child = find_named_node (node, "Locations")) == 0) {
1620 error << _("Session: XML state has no locations section") << endmsg;
1622 } else if (_locations.set_state (*child)) {
1628 if ((location = _locations.auto_loop_location()) != 0) {
1629 set_auto_loop_location (location);
1632 if ((location = _locations.auto_punch_location()) != 0) {
1633 set_auto_punch_location (location);
1636 if ((location = _locations.end_location()) == 0) {
1637 _locations.add (end_location);
1639 delete end_location;
1640 end_location = location;
1643 if ((location = _locations.start_location()) == 0) {
1644 _locations.add (start_location);
1646 delete start_location;
1647 start_location = location;
1650 _locations.save_state (_("initial state"));
1652 if ((child = find_named_node (node, "EditGroups")) == 0) {
1653 error << _("Session: XML state has no edit groups section") << endmsg;
1655 } else if (load_edit_groups (*child)) {
1659 if ((child = find_named_node (node, "MixGroups")) == 0) {
1660 error << _("Session: XML state has no mix groups section") << endmsg;
1662 } else if (load_mix_groups (*child)) {
1666 if ((child = find_named_node (node, "TempoMap")) == 0) {
1667 error << _("Session: XML state has no Tempo Map section") << endmsg;
1669 } else if (_tempo_map->set_state (*child)) {
1673 if ((child = find_named_node (node, "Routes")) == 0) {
1674 error << _("Session: XML state has no routes section") << endmsg;
1676 } else if (load_routes (*child)) {
1680 if ((child = find_named_node (node, "Click")) == 0) {
1681 warning << _("Session: XML state has no click section") << endmsg;
1682 } else if (_click_io) {
1683 _click_io->set_state (*child);
1686 /* OK, now we can set edit mode */
1688 set_edit_mode (pending_edit_mode);
1690 /* here beginneth the second phase ... */
1692 StateReady (); /* EMIT SIGNAL */
1694 _state_of_the_state = Clean;
1696 StateManager::allow_save (_("initial state"), true);
1698 if (state_was_pending) {
1699 save_state (_current_snapshot_name);
1700 remove_pending_capture_state ();
1701 state_was_pending = false;
1707 /* we failed, re-enable state saving but don't actually save internal state */
1708 StateManager::allow_save (X_("ignored"), false);
1713 Session::load_routes (const XMLNode& node)
1716 XMLNodeConstIterator niter;
1718 nlist = node.children();
1722 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1724 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1727 error << _("Session: cannot create Route from XML description.") << endmsg;
1737 boost::shared_ptr<Route>
1738 Session::XMLRouteFactory (const XMLNode& node)
1740 if (node.name() != "Route") {
1741 return boost::shared_ptr<Route> ((Route*) 0);
1744 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1746 DataType type = DataType::AUDIO;
1747 const XMLProperty* prop = node.property("default-type");
1749 type = DataType(prop->value());
1751 assert(type != DataType::NIL);
1753 if (has_diskstream) {
1754 if (type == DataType::AUDIO) {
1755 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1758 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1762 boost::shared_ptr<Route> ret (new Route (*this, node));
1768 Session::load_regions (const XMLNode& node)
1771 XMLNodeConstIterator niter;
1772 AudioRegion* region;
1774 nlist = node.children();
1778 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1779 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1780 error << _("Session: cannot create Region from XML description.") << endmsg;
1787 Session::XMLRegionFactory (const XMLNode& node, bool full)
1789 const XMLProperty* prop;
1792 AudioRegion::SourceList sources;
1793 uint32_t nchans = 1;
1796 if (node.name() != X_("Region")) {
1800 if ((prop = node.property (X_("channels"))) != 0) {
1801 nchans = atoi (prop->value().c_str());
1805 if ((prop = node.property (X_("source-0"))) == 0) {
1806 if ((prop = node.property ("source")) == 0) {
1807 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1812 PBD::ID s_id (prop->value());
1814 if ((source = source_by_id (s_id)) == 0) {
1815 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1819 as = dynamic_cast<AudioSource*>(source);
1821 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1825 sources.push_back (as);
1827 /* pickup other channels */
1829 for (uint32_t n=1; n < nchans; ++n) {
1830 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1831 if ((prop = node.property (buf)) != 0) {
1833 PBD::ID id2 (prop->value());
1835 if ((source = source_by_id (id2)) == 0) {
1836 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1840 as = dynamic_cast<AudioSource*>(source);
1842 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1845 sources.push_back (as);
1850 return new AudioRegion (sources, node);
1853 catch (failed_constructor& err) {
1859 Session::get_sources_as_xml ()
1862 XMLNode* node = new XMLNode (X_("Sources"));
1863 Glib::Mutex::Lock lm (audio_source_lock);
1865 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1866 node->add_child_nocopy (i->second->get_state());
1869 /* XXX get MIDI and other sources here */
1875 Session::path_from_region_name (string name, string identifier)
1877 char buf[PATH_MAX+1];
1879 string dir = discover_best_sound_dir ();
1881 for (n = 0; n < 999999; ++n) {
1882 if (identifier.length()) {
1883 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1884 identifier.c_str(), n);
1886 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1888 if (access (buf, F_OK) != 0) {
1898 Session::load_sources (const XMLNode& node)
1901 XMLNodeConstIterator niter;
1904 nlist = node.children();
1908 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1910 if ((source = XMLSourceFactory (**niter)) == 0) {
1911 error << _("Session: cannot create Source from XML description.") << endmsg;
1919 Session::XMLSourceFactory (const XMLNode& node)
1923 if (node.name() != "Source") {
1928 src = AudioFileSource::create (node);
1931 catch (failed_constructor& err) {
1932 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1940 Session::save_template (string template_name)
1943 string xml_path, bak_path, template_path;
1945 if (_state_of_the_state & CannotSave) {
1950 string dir = template_dir();
1952 if ((dp = opendir (dir.c_str()))) {
1955 if (mkdir (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)<0) {
1956 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1961 tree.set_root (&get_template());
1964 xml_path += template_name;
1965 xml_path += _template_suffix;
1967 ifstream in(xml_path.c_str());
1970 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1976 if (!tree.write (xml_path)) {
1977 error << _("mix template not saved") << endmsg;
1985 Session::rename_template (string old_name, string new_name)
1987 string old_path = template_dir() + old_name + _template_suffix;
1988 string new_path = template_dir() + new_name + _template_suffix;
1990 return rename (old_path.c_str(), new_path.c_str());
1994 Session::delete_template (string name)
1996 string template_path = template_dir();
1997 template_path += name;
1998 template_path += _template_suffix;
2000 return remove (template_path.c_str());
2004 Session::refresh_disk_space ()
2007 struct statfs statfsbuf;
2008 vector<space_and_path>::iterator i;
2009 Glib::Mutex::Lock lm (space_lock);
2012 /* get freespace on every FS that is part of the session path */
2014 _total_free_4k_blocks = 0;
2016 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2017 statfs ((*i).path.c_str(), &statfsbuf);
2019 scale = statfsbuf.f_bsize/4096.0;
2021 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2022 _total_free_4k_blocks += (*i).blocks;
2028 Session::ensure_sound_dir (string path, string& result)
2033 /* Ensure that the parent directory exists */
2035 if (mkdir (path.c_str(), 0775)) {
2036 if (errno != EEXIST) {
2037 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
2042 /* Ensure that the sounds directory exists */
2046 result += sound_dir_name;
2048 if (mkdir (result.c_str(), 0775)) {
2049 if (errno != EEXIST) {
2050 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
2057 dead += dead_sound_dir_name;
2059 if (mkdir (dead.c_str(), 0775)) {
2060 if (errno != EEXIST) {
2061 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
2068 peak += peak_dir_name;
2070 if (mkdir (peak.c_str(), 0775)) {
2071 if (errno != EEXIST) {
2072 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
2077 /* callers expect this to be terminated ... */
2084 Session::discover_best_sound_dir (bool destructive)
2086 vector<space_and_path>::iterator i;
2089 /* destructive files all go into the same place */
2095 /* handle common case without system calls */
2097 if (session_dirs.size() == 1) {
2101 /* OK, here's the algorithm we're following here:
2103 We want to select which directory to use for
2104 the next file source to be created. Ideally,
2105 we'd like to use a round-robin process so as to
2106 get maximum performance benefits from splitting
2107 the files across multiple disks.
2109 However, in situations without much diskspace, an
2110 RR approach may end up filling up a filesystem
2111 with new files while others still have space.
2112 Its therefore important to pay some attention to
2113 the freespace in the filesystem holding each
2114 directory as well. However, if we did that by
2115 itself, we'd keep creating new files in the file
2116 system with the most space until it was as full
2117 as all others, thus negating any performance
2118 benefits of this RAID-1 like approach.
2120 So, we use a user-configurable space threshold. If
2121 there are at least 2 filesystems with more than this
2122 much space available, we use RR selection between them.
2123 If not, then we pick the filesystem with the most space.
2125 This gets a good balance between the two
2129 refresh_disk_space ();
2131 int free_enough = 0;
2133 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2134 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2139 if (free_enough >= 2) {
2141 bool found_it = false;
2143 /* use RR selection process, ensuring that the one
2147 i = last_rr_session_dir;
2150 if (++i == session_dirs.end()) {
2151 i = session_dirs.begin();
2154 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2155 if (ensure_sound_dir ((*i).path, result) == 0) {
2156 last_rr_session_dir = i;
2162 } while (i != last_rr_session_dir);
2165 result = sound_dir();
2170 /* pick FS with the most freespace (and that
2171 seems to actually work ...)
2174 vector<space_and_path> sorted;
2175 space_and_path_ascending_cmp cmp;
2177 sorted = session_dirs;
2178 sort (sorted.begin(), sorted.end(), cmp);
2180 for (i = sorted.begin(); i != sorted.end(); ++i) {
2181 if (ensure_sound_dir ((*i).path, result) == 0) {
2182 last_rr_session_dir = i;
2187 /* if the above fails, fall back to the most simplistic solution */
2189 if (i == sorted.end()) {
2198 Session::load_playlists (const XMLNode& node)
2201 XMLNodeConstIterator niter;
2204 nlist = node.children();
2208 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2210 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2211 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2219 Session::load_unused_playlists (const XMLNode& node)
2222 XMLNodeConstIterator niter;
2225 nlist = node.children();
2229 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2231 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2232 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2236 // now manually untrack it
2238 track_playlist (playlist, false);
2246 Session::XMLPlaylistFactory (const XMLNode& node)
2249 return new AudioPlaylist (*this, node);
2252 catch (failed_constructor& err) {
2258 Session::load_named_selections (const XMLNode& node)
2261 XMLNodeConstIterator niter;
2264 nlist = node.children();
2268 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2270 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2271 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2279 Session::XMLNamedSelectionFactory (const XMLNode& node)
2282 return new NamedSelection (*this, node);
2285 catch (failed_constructor& err) {
2291 Session::dead_sound_dir () const
2294 res += dead_sound_dir_name;
2300 Session::sound_dir () const
2303 res += sound_dir_name;
2309 Session::tape_dir () const
2312 res += tape_dir_name;
2318 Session::peak_dir () const
2321 res += peak_dir_name;
2327 Session::automation_dir () const
2330 res += "automation/";
2335 Session::template_dir ()
2337 string path = get_user_ardour_path();
2338 path += "templates/";
2344 Session::suffixed_search_path (string suffix, bool data)
2348 path += get_user_ardour_path();
2349 if (path[path.length()-1] != ':') {
2354 path += get_system_data_path();
2356 path += get_system_module_path();
2359 vector<string> split_path;
2361 split (path, split_path, ':');
2364 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2369 if (distance (i, split_path.end()) != 1) {
2378 Session::template_path ()
2380 return suffixed_search_path (X_("templates"), true);
2384 Session::control_protocol_path ()
2386 return suffixed_search_path (X_("surfaces"), false);
2390 Session::load_connections (const XMLNode& node)
2392 XMLNodeList nlist = node.children();
2393 XMLNodeConstIterator niter;
2397 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2398 if ((*niter)->name() == "InputConnection") {
2399 add_connection (new ARDOUR::InputConnection (**niter));
2400 } else if ((*niter)->name() == "OutputConnection") {
2401 add_connection (new ARDOUR::OutputConnection (**niter));
2403 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2412 Session::load_edit_groups (const XMLNode& node)
2414 return load_route_groups (node, true);
2418 Session::load_mix_groups (const XMLNode& node)
2420 return load_route_groups (node, false);
2424 Session::load_route_groups (const XMLNode& node, bool edit)
2426 XMLNodeList nlist = node.children();
2427 XMLNodeConstIterator niter;
2432 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2433 if ((*niter)->name() == "RouteGroup") {
2435 rg = add_edit_group ("");
2436 rg->set_state (**niter);
2438 rg = add_mix_group ("");
2439 rg->set_state (**niter);
2448 state_file_filter (const string &str, void *arg)
2450 return (str.length() > strlen(Session::statefile_suffix()) &&
2451 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2455 bool operator()(const string* a, const string* b) {
2461 remove_end(string* state)
2463 string statename(*state);
2465 string::size_type start,end;
2466 if ((start = statename.find_last_of ('/')) != string::npos) {
2467 statename = statename.substr (start+1);
2470 if ((end = statename.rfind(".ardour")) == string::npos) {
2471 end = statename.length();
2474 return new string(statename.substr (0, end));
2478 Session::possible_states (string path)
2480 PathScanner scanner;
2481 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2483 transform(states->begin(), states->end(), states->begin(), remove_end);
2486 sort (states->begin(), states->end(), cmp);
2492 Session::possible_states () const
2494 return possible_states(_path);
2498 Session::auto_save()
2500 save_state (_current_snapshot_name);
2504 Session::add_edit_group (string name)
2506 RouteGroup* rg = new RouteGroup (*this, name);
2507 edit_groups.push_back (rg);
2508 edit_group_added (rg); /* EMIT SIGNAL */
2514 Session::add_mix_group (string name)
2516 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2517 mix_groups.push_back (rg);
2518 mix_group_added (rg); /* EMIT SIGNAL */
2524 Session::remove_edit_group (RouteGroup& rg)
2526 list<RouteGroup*>::iterator i;
2528 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2529 (*i)->apply (&Route::drop_edit_group, this);
2530 edit_groups.erase (i);
2531 edit_group_removed (); /* EMIT SIGNAL */
2538 Session::remove_mix_group (RouteGroup& rg)
2540 list<RouteGroup*>::iterator i;
2542 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2543 (*i)->apply (&Route::drop_mix_group, this);
2544 mix_groups.erase (i);
2545 mix_group_removed (); /* EMIT SIGNAL */
2552 Session::mix_group_by_name (string name)
2554 list<RouteGroup *>::iterator i;
2556 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2557 if ((*i)->name() == name) {
2565 Session::edit_group_by_name (string name)
2567 list<RouteGroup *>::iterator i;
2569 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2570 if ((*i)->name() == name) {
2578 Session::set_meter_hold (float val)
2581 MeterHoldChanged(); // emit
2585 Session::set_meter_falloff (float val)
2587 _meter_falloff = val;
2588 MeterFalloffChanged(); // emit
2593 Session::begin_reversible_command (string name, UndoAction* private_undo)
2595 current_cmd.clear ();
2596 current_cmd.set_name (name);
2599 current_cmd.add_undo (*private_undo);
2604 Session::commit_reversible_command (UndoAction* private_redo)
2609 current_cmd.add_redo_no_execute (*private_redo);
2612 gettimeofday (&now, 0);
2613 current_cmd.set_timestamp (now);
2615 history.add (current_cmd);
2618 Session::GlobalRouteBooleanState
2619 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2621 GlobalRouteBooleanState s;
2622 boost::shared_ptr<RouteList> r = routes.reader ();
2624 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2625 if (!(*i)->hidden()) {
2626 RouteBooleanState v;
2629 Route* r = (*i).get();
2630 v.second = (r->*method)();
2639 Session::GlobalRouteMeterState
2640 Session::get_global_route_metering ()
2642 GlobalRouteMeterState s;
2643 boost::shared_ptr<RouteList> r = routes.reader ();
2645 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2646 if (!(*i)->hidden()) {
2650 v.second = (*i)->meter_point();
2660 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2662 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2663 i->first->set_meter_point (i->second, arg);
2668 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2670 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2671 Route* r = i->first.get();
2672 (r->*method) (i->second, arg);
2677 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2679 set_global_route_boolean (s, &Route::set_mute, src);
2683 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2685 set_global_route_boolean (s, &Route::set_solo, src);
2689 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2691 set_global_route_boolean (s, &Route::set_record_enable, src);
2695 Session::global_mute_memento (void* src)
2697 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2701 Session::global_metering_memento (void* src)
2703 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2707 Session::global_solo_memento (void* src)
2709 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2713 Session::global_record_enable_memento (void* src)
2715 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2719 template_filter (const string &str, void *arg)
2721 return (str.length() > strlen(Session::template_suffix()) &&
2722 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2726 Session::get_template_list (list<string> &template_names)
2728 vector<string *> *templates;
2729 PathScanner scanner;
2732 path = template_path ();
2734 templates = scanner (path, template_filter, 0, false, true);
2736 vector<string*>::iterator i;
2737 for (i = templates->begin(); i != templates->end(); ++i) {
2738 string fullpath = *(*i);
2741 start = fullpath.find_last_of ('/') + 1;
2742 if ((end = fullpath.find_last_of ('.')) <0) {
2743 end = fullpath.length();
2746 template_names.push_back(fullpath.substr(start, (end-start)));
2751 Session::read_favorite_dirs (FavoriteDirs & favs)
2753 string path = get_user_ardour_path();
2754 path += "/favorite_dirs";
2756 ifstream fav (path.c_str());
2761 if (errno != ENOENT) {
2762 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2773 getline(fav, newfav);
2779 favs.push_back (newfav);
2786 Session::write_favorite_dirs (FavoriteDirs & favs)
2788 string path = get_user_ardour_path();
2789 path += "/favorite_dirs";
2791 ofstream fav (path.c_str());
2797 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2798 fav << (*i) << endl;
2805 accept_all_non_peak_files (const string& path, void *arg)
2807 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2811 accept_all_state_files (const string& path, void *arg)
2813 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2817 Session::find_all_sources (string path, set<string>& result)
2822 if (!tree.read (path)) {
2826 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2831 XMLNodeConstIterator niter;
2833 nlist = node->children();
2837 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2841 if ((prop = (*niter)->property (X_("name"))) == 0) {
2845 if (prop->value()[0] == '/') {
2846 /* external file, ignore */
2850 string path = _path; /* /-terminated */
2851 path += sound_dir_name;
2853 path += prop->value();
2855 result.insert (path);
2862 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2864 PathScanner scanner;
2865 vector<string*>* state_files;
2867 string this_snapshot_path;
2873 if (ripped[ripped.length()-1] == '/') {
2874 ripped = ripped.substr (0, ripped.length() - 1);
2877 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2879 if (state_files == 0) {
2884 this_snapshot_path = _path;
2885 this_snapshot_path += _current_snapshot_name;
2886 this_snapshot_path += _statefile_suffix;
2888 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2890 if (exclude_this_snapshot && **i == this_snapshot_path) {
2894 if (find_all_sources (**i, result) < 0) {
2903 Session::cleanup_sources (Session::cleanup_report& rep)
2905 vector<Source*> dead_sources;
2906 vector<Playlist*> playlists_tbd;
2907 PathScanner scanner;
2909 vector<space_and_path>::iterator i;
2910 vector<space_and_path>::iterator nexti;
2911 vector<string*>* soundfiles;
2912 vector<string> unused;
2913 set<string> all_sources;
2918 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2920 /* step 1: consider deleting all unused playlists */
2922 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2925 status = AskAboutPlaylistDeletion (*x);
2934 playlists_tbd.push_back (*x);
2938 /* leave it alone */
2943 /* now delete any that were marked for deletion */
2945 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2946 PlaylistList::iterator foo;
2948 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2949 unused_playlists.erase (foo);
2954 /* step 2: clear the undo/redo history for all playlists */
2956 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2957 (*x)->drop_all_states ();
2960 /* step 3: find all un-referenced sources */
2965 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2967 AudioSourceList::iterator tmp;
2972 /* only remove files that are not in use and have some size
2973 to them. otherwise we remove the current "nascent"
2977 if (i->second->use_cnt() == 0 && i->second->length() > 0) {
2978 dead_sources.push_back (i->second);
2980 /* remove this source from our own list to avoid us
2981 adding it to the list of all sources below
2984 audio_sources.erase (i);
2990 /* Step 4: get rid of all regions in the region list that use any dead sources
2991 in case the sources themselves don't go away (they might be referenced in
2995 for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2997 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2998 AudioRegionList::iterator tmp;
3006 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
3007 if (&ar->source (n) == (*i)) {
3008 /* this region is dead */
3017 /* build a list of all the possible sound directories for the session */
3019 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
3024 sound_path += (*i).path;
3025 sound_path += sound_dir_name;
3027 if (nexti != session_dirs.end()) {
3034 /* now do the same thing for the files that ended up in the sounds dir(s)
3035 but are not referenced as sources in any snapshot.
3038 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
3040 if (soundfiles == 0) {
3044 /* find all sources, but don't use this snapshot because the
3045 state file on disk still references sources we may have already
3049 find_all_sources_across_snapshots (all_sources, true);
3051 /* add our current source list
3054 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
3055 AudioFileSource* fs;
3057 if ((fs = dynamic_cast<AudioFileSource*> (i->second)) != 0) {
3058 all_sources.insert (fs->path());
3062 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
3067 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
3077 unused.push_back (spath);
3081 /* now try to move all unused files into the "dead_sounds" directory(ies) */
3083 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
3084 struct stat statbuf;
3086 rep.paths.push_back (*x);
3087 if (stat ((*x).c_str(), &statbuf) == 0) {
3088 rep.space += statbuf.st_size;
3093 /* don't move the file across filesystems, just
3094 stick it in the `dead_sound_dir_name' directory
3095 on whichever filesystem it was already on.
3098 newpath = Glib::path_get_dirname (*x);
3099 newpath = Glib::path_get_dirname (newpath);
3102 newpath += dead_sound_dir_name;
3104 newpath += Glib::path_get_basename ((*x));
3106 if (access (newpath.c_str(), F_OK) == 0) {
3108 /* the new path already exists, try versioning */
3110 char buf[PATH_MAX+1];
3114 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
3117 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
3118 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
3122 if (version == 999) {
3123 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
3127 newpath = newpath_v;
3132 /* it doesn't exist, or we can't read it or something */
3136 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
3137 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
3138 (*x), newpath, strerror (errno))
3144 /* see if there an easy to find peakfile for this file, and remove it.
3147 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
3148 peakpath += ".peak";
3150 if (access (peakpath.c_str(), W_OK) == 0) {
3151 if (::unlink (peakpath.c_str()) != 0) {
3152 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3153 peakpath, _path, strerror (errno))
3155 /* try to back out */
3156 rename (newpath.c_str(), _path.c_str());
3165 /* dump the history list */
3169 /* save state so we don't end up a session file
3170 referring to non-existent sources.
3176 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3181 Session::cleanup_trash_sources (Session::cleanup_report& rep)
3183 vector<space_and_path>::iterator i;
3184 string dead_sound_dir;
3185 struct dirent* dentry;
3186 struct stat statbuf;
3192 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3194 dead_sound_dir = (*i).path;
3195 dead_sound_dir += dead_sound_dir_name;
3197 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
3201 while ((dentry = readdir (dead)) != 0) {
3203 /* avoid '.' and '..' */
3205 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
3206 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3212 fullpath = dead_sound_dir;
3214 fullpath += dentry->d_name;
3216 if (stat (fullpath.c_str(), &statbuf)) {
3220 if (!S_ISREG (statbuf.st_mode)) {
3224 if (unlink (fullpath.c_str())) {
3225 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3226 fullpath, strerror (errno))
3230 rep.paths.push_back (dentry->d_name);
3231 rep.space += statbuf.st_size;
3242 Session::set_dirty ()
3244 bool was_dirty = dirty();
3246 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3249 DirtyChanged(); /* EMIT SIGNAL */
3255 Session::set_clean ()
3257 bool was_dirty = dirty();
3259 _state_of_the_state = Clean;
3262 DirtyChanged(); /* EMIT SIGNAL */
3267 Session::add_controllable (Controllable* c)
3269 Glib::Mutex::Lock lm (controllables_lock);
3270 controllables.push_back (c);
3274 Session::remove_controllable (Controllable* c)
3276 if (_state_of_the_state | Deletion) {
3280 Glib::Mutex::Lock lm (controllables_lock);
3281 controllables.remove (c);
3285 Session::controllable_by_id (const PBD::ID& id)
3287 Glib::Mutex::Lock lm (controllables_lock);
3289 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3290 if ((*i)->id() == id) {
3299 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3301 Stateful::add_instant_xml (node, dir);
3302 Config->add_instant_xml (node, get_user_ardour_path());