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/audio_diskstream.h>
62 #include <ardour/midi_diskstream.h>
63 #include <ardour/utils.h>
64 #include <ardour/audioplaylist.h>
65 #include <ardour/audiofilesource.h>
66 #include <ardour/destructive_filesource.h>
67 #include <ardour/sndfile_helpers.h>
68 #include <ardour/auditioner.h>
69 #include <ardour/export.h>
70 #include <ardour/redirect.h>
71 #include <ardour/send.h>
72 #include <ardour/insert.h>
73 #include <ardour/connection.h>
74 #include <ardour/slave.h>
75 #include <ardour/tempo.h>
76 #include <ardour/audio_track.h>
77 #include <ardour/midi_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>
91 using namespace ARDOUR;
95 Session::first_stage_init (string fullpath, string snapshot_name)
97 if (fullpath.length() == 0) {
98 throw failed_constructor();
101 char buf[PATH_MAX+1];
102 if (!realpath(fullpath.c_str(), buf) && (errno != ENOENT)) {
103 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
104 throw failed_constructor();
108 if (_path[_path.length()-1] != '/') {
112 /* these two are just provisional settings. set_state()
113 will likely override them.
116 _name = _current_snapshot_name = snapshot_name;
117 setup_raid_path (_path);
119 _current_frame_rate = _engine.frame_rate ();
120 _tempo_map = new TempoMap (_current_frame_rate);
121 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
123 g_atomic_int_set (&processing_prohibited, 0);
126 _transport_speed = 0;
127 _last_transport_speed = 0;
128 transport_sub_state = 0;
129 _transport_frame = 0;
131 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
132 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
133 _end_location_is_free = true;
134 g_atomic_int_set (&_record_status, Disabled);
139 seamless_loop = false;
140 loop_changing = false;
142 crossfades_active = false;
145 _last_roll_location = 0;
146 _last_record_location = 0;
147 pending_locate_frame = 0;
148 pending_locate_roll = false;
149 pending_locate_flush = false;
150 dstream_buffer_size = 0;
152 state_was_pending = false;
154 outbound_mtc_smpte_frame = 0;
155 next_quarter_frame_to_send = -1;
156 current_block_size = 0;
157 _solo_latched = true;
158 _solo_model = InverseMute;
159 solo_update_disabled = false;
160 currently_soloing = false;
161 _have_captured = false;
162 _worst_output_latency = 0;
163 _worst_input_latency = 0;
164 _worst_track_latency = 0;
165 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
168 butler_mixdown_buffer = 0;
169 butler_gain_buffer = 0;
173 post_transport_work = PostTransportWork (0);
174 g_atomic_int_set (&butler_should_do_transport_work, 0);
175 g_atomic_int_set (&butler_active, 0);
176 g_atomic_int_set (&_playback_load, 100);
177 g_atomic_int_set (&_capture_load, 100);
178 g_atomic_int_set (&_playback_load_min, 100);
179 g_atomic_int_set (&_capture_load_min, 100);
180 pending_audition_region = 0;
182 pending_edit_mode = _edit_mode;
184 input_auto_connect = AutoConnectOption (0);
185 output_auto_connect = AutoConnectOption (0);
186 waiting_to_start = false;
188 _gain_automation_buffer = 0;
189 _pan_automation_buffer = 0;
191 pending_abort = false;
192 layer_model = MoveAddHigher;
193 xfade_model = ShortCrossfade;
194 destructive_index = 0;
196 /* allocate conversion buffers */
197 _conversion_buffers[ButlerContext] = new char[AudioDiskstream::disk_io_frames() * 4];
198 _conversion_buffers[TransportContext] = new char[AudioDiskstream::disk_io_frames() * 4];
199 AudioDiskstream::allocate_working_buffers();
201 /* default short fade = 15ms */
203 Crossfade::set_short_xfade_length ((jack_nframes_t) floor ((15.0 * frame_rate()) / 1000.0));
204 DestructiveFileSource::setup_standard_crossfades (frame_rate());
206 last_mmc_step.tv_sec = 0;
207 last_mmc_step.tv_usec = 0;
210 preroll.type = AnyTime::Frames;
212 postroll.type = AnyTime::Frames;
215 /* click sounds are unset by default, which causes us to internal
216 waveforms for clicks.
220 click_requested = false;
222 click_emphasis_data = 0;
224 click_emphasis_length = 0;
226 process_function = &Session::process_with_events;
230 _smpte_offset_negative = true;
231 last_smpte_valid = false;
233 last_rr_session_dir = session_dirs.begin();
234 refresh_disk_space ();
236 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
238 /* default configuration */
240 do_not_record_plugins = false;
241 over_length_short = 2;
242 over_length_long = 10;
243 send_midi_timecode = false;
244 send_midi_machine_control = false;
245 shuttle_speed_factor = 1.0;
246 shuttle_speed_threshold = 5;
248 _meter_hold = 100; // XXX unknown units: number of calls to meter::set()
249 _meter_falloff = 1.5f; // XXX unknown units: refresh_rate
255 average_slave_delta = 1800;
256 have_first_delta_accumulator = false;
257 delta_accumulator_cnt = 0;
258 slave_state = Stopped;
260 /* default SMPTE type is 30 FPS, non-drop */
262 set_smpte_type (30.0, false);
264 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
266 /* These are all static "per-class" signals */
268 Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
269 AudioSource::AudioSourceCreated.connect (mem_fun (*this, &Session::add_audio_source));
270 Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
271 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
272 Diskstream::DiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
273 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
275 Controllable::Created.connect (mem_fun (*this, &Session::add_controllable));
276 Controllable::GoingAway.connect (mem_fun (*this, &Session::remove_controllable));
278 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
280 /* stop IO objects from doing stuff until we're ready for them */
282 IO::disable_panners ();
283 IO::disable_ports ();
284 IO::disable_connecting ();
288 Session::second_stage_init (bool new_session)
290 AudioFileSource::set_peak_dir (peak_dir());
293 if (load_state (_current_snapshot_name)) {
296 remove_empty_sounds ();
299 if (start_butler_thread()) {
303 /*if (start_midi_thread ()) {
308 if (set_state (*state_tree->root())) {
313 /* we can't save till after ::when_engine_running() is called,
314 because otherwise we save state with no connections made.
315 therefore, we reset _state_of_the_state because ::set_state()
316 will have cleared it.
318 we also have to include Loading so that any events that get
319 generated between here and the end of ::when_engine_running()
320 will be processed directly rather than queued.
323 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
325 // set_auto_input (true);
326 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
327 _locations.added.connect (mem_fun (this, &Session::locations_added));
328 setup_click_sounds (0);
329 setup_midi_control ();
331 /* Pay attention ... */
333 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
334 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
336 if (_engine.running()) {
337 when_engine_running();
339 first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
342 //send_full_time_code ();
343 _engine.transport_locate (0);
344 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
345 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
347 ControlProtocolManager::instance().set_session (*this);
350 _end_location_is_free = true;
352 _end_location_is_free = false;
359 Session::raid_path () const
363 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
368 return path.substr (0, path.length() - 1); // drop final colon
372 Session::set_raid_path (string path)
374 /* public-access to setup_raid_path() */
376 setup_raid_path (path);
380 Session::setup_raid_path (string path)
382 string::size_type colon;
386 string::size_type len = path.length();
391 if (path.length() == 0) {
395 session_dirs.clear ();
397 for (string::size_type n = 0; n < len; ++n) {
398 if (path[n] == ':') {
405 /* no multiple search path, just one location (common case) */
409 session_dirs.push_back (sp);
416 if (fspath[fspath.length()-1] != '/') {
419 fspath += sound_dir_name;
425 if (fspath[fspath.length()-1] != '/') {
428 fspath += tape_dir_name;
430 AudioFileSource::set_search_path (fspath);
437 while ((colon = remaining.find_first_of (':')) != string::npos) {
440 sp.path = remaining.substr (0, colon);
441 session_dirs.push_back (sp);
443 /* add sounds to file search path */
446 if (fspath[fspath.length()-1] != '/') {
449 fspath += sound_dir_name;
452 /* add tape dir to file search path */
455 if (fspath[fspath.length()-1] != '/') {
458 fspath += tape_dir_name;
461 remaining = remaining.substr (colon+1);
464 if (remaining.length()) {
471 if (fspath[fspath.length()-1] != '/') {
474 fspath += sound_dir_name;
478 if (fspath[fspath.length()-1] != '/') {
481 fspath += tape_dir_name;
483 session_dirs.push_back (sp);
486 /* set the AudioFileSource search path */
488 AudioFileSource::set_search_path (fspath);
490 /* reset the round-robin soundfile path thingie */
492 last_rr_session_dir = session_dirs.begin();
496 Session::create (bool& new_session, string* mix_template, jack_nframes_t initial_length)
500 if (mkdir (_path.c_str(), 0755) < 0) {
501 if (errno == EEXIST) {
504 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
513 if (mkdir (dir.c_str(), 0755) < 0) {
514 if (errno != EEXIST) {
515 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
522 if (mkdir (dir.c_str(), 0755) < 0) {
523 if (errno != EEXIST) {
524 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
531 if (mkdir (dir.c_str(), 0755) < 0) {
532 if (errno != EEXIST) {
533 error << string_compose(_("Session: cannot create session tape dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
538 dir = dead_sound_dir ();
540 if (mkdir (dir.c_str(), 0755) < 0) {
541 if (errno != EEXIST) {
542 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
547 dir = automation_dir ();
549 if (mkdir (dir.c_str(), 0755) < 0) {
550 if (errno != EEXIST) {
551 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
557 /* check new_session so we don't overwrite an existing one */
561 std::string in_path = *mix_template;
563 ifstream in(in_path.c_str());
566 string out_path = _path;
568 out_path += _statefile_suffix;
570 ofstream out(out_path.c_str());
575 // okay, session is set up. Treat like normal saved
576 // session from now on.
582 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
588 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
595 warning << _("Session already exists. Not overwriting") << endmsg;
602 /* set initial start + end point */
604 start_location->set_end (0);
605 _locations.add (start_location);
607 end_location->set_end (initial_length);
608 _locations.add (end_location);
610 _state_of_the_state = Clean;
612 if (save_state (_current_snapshot_name)) {
621 Session::load_diskstreams (const XMLNode& node)
624 XMLNodeConstIterator citer;
626 clist = node.children();
628 for (citer = clist.begin(); citer != clist.end(); ++citer) {
629 Diskstream* dstream = NULL;
632 if ((*citer)->name() == "AudioDiskstream") {
633 dstream = new AudioDiskstream (*this, **citer);
634 /* added automatically by DiskstreamCreated handler */
636 assert((*citer)->name() == "MidiDiskstream");
637 dstream = new MidiDiskstream (*this, **citer);
641 catch (failed_constructor& err) {
642 error << _("Session: could not load diskstream via XML state") << endmsg;
651 Session::remove_pending_capture_state ()
656 xml_path += _current_snapshot_name;
657 xml_path += _pending_suffix;
659 unlink (xml_path.c_str());
663 Session::save_state (string snapshot_name, bool pending)
669 if (_state_of_the_state & CannotSave) {
673 tree.set_root (&get_state());
675 if (snapshot_name.empty()) {
676 snapshot_name = _current_snapshot_name;
682 xml_path += snapshot_name;
683 xml_path += _statefile_suffix;
687 // Make backup of state file
689 if ((access (xml_path.c_str(), F_OK) == 0) &&
690 (rename(xml_path.c_str(), bak_path.c_str()))) {
691 error << _("could not backup old state file, current state not saved.") << endmsg;
698 xml_path += snapshot_name;
699 xml_path += _pending_suffix;
703 if (!tree.write (xml_path)) {
704 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
706 /* don't leave a corrupt file lying around if it is
710 if (unlink (xml_path.c_str())) {
711 error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
714 if (rename (bak_path.c_str(), xml_path.c_str())) {
715 error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
725 bool was_dirty = dirty();
727 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
730 DirtyChanged (); /* EMIT SIGNAL */
733 StateSaved (snapshot_name); /* EMIT SIGNAL */
740 Session::restore_state (string snapshot_name)
742 if (load_state (snapshot_name) == 0) {
743 set_state (*state_tree->root());
750 Session::load_state (string snapshot_name)
759 state_was_pending = false;
761 /* check for leftover pending state from a crashed capture attempt */
764 xmlpath += snapshot_name;
765 xmlpath += _pending_suffix;
767 if (!access (xmlpath.c_str(), F_OK)) {
769 /* there is pending state from a crashed capture attempt */
771 if (AskAboutPendingState()) {
772 state_was_pending = true;
776 if (!state_was_pending) {
779 xmlpath += snapshot_name;
780 xmlpath += _statefile_suffix;
783 if (access (xmlpath.c_str(), F_OK)) {
784 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
788 state_tree = new XMLTree;
792 if (state_tree->read (xmlpath)) {
795 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
804 Session::load_options (const XMLNode& node)
808 bool have_fade_msecs = false;
809 bool have_fade_steepness = false;
810 float fade_msecs = 0;
811 float fade_steepness = 0;
812 SlaveSource slave_src = None;
814 LocaleGuard lg (X_("POSIX"));
816 if ((child = find_named_node (node, "input-auto-connect")) != 0) {
817 if ((prop = child->property ("val")) != 0) {
818 sscanf (prop->value().c_str(), "%x", &x);
819 input_auto_connect = AutoConnectOption (x);
823 if ((child = find_named_node (node, "output-auto-connect")) != 0) {
824 if ((prop = child->property ("val")) != 0) {
825 sscanf (prop->value().c_str(), "%x", &x);
826 output_auto_connect = AutoConnectOption (x);
830 if ((child = find_named_node (node, "slave")) != 0) {
831 if ((prop = child->property ("type")) != 0) {
832 if (prop->value() == "none") {
834 } else if (prop->value() == "mtc") {
836 } else if (prop->value() == "jack") {
839 set_slave_source (slave_src, 0);
843 /* we cannot set edit mode if we are loading a session,
844 because it might destroy the playlist's positioning
847 if ((child = find_named_node (node, "edit-mode")) != 0) {
848 if ((prop = child->property ("val")) != 0) {
849 if (prop->value() == "slide") {
850 pending_edit_mode = Slide;
851 } else if (prop->value() == "splice") {
852 pending_edit_mode = Splice;
857 if ((child = find_named_node (node, "send-midi-timecode")) != 0) {
858 if ((prop = child->property ("val")) != 0) {
859 bool x = (prop->value() == "yes");
860 send_mtc = !x; /* force change in value */
864 if ((child = find_named_node (node, "send-midi-machine-control")) != 0) {
865 if ((prop = child->property ("val")) != 0) {
866 bool x = (prop->value() == "yes");
867 send_mmc = !x; /* force change in value */
868 set_send_mmc (prop->value() == "yes");
871 if ((child = find_named_node (node, "max-level")) != 0) {
872 if ((prop = child->property ("val")) != 0) {
873 max_level = atoi (prop->value().c_str());
876 if ((child = find_named_node (node, "min-level")) != 0) {
877 if ((prop = child->property ("val")) != 0) {
878 min_level = atoi (prop->value().c_str());
881 if ((child = find_named_node (node, "meter-hold")) != 0) {
882 if ((prop = child->property ("val")) != 0) {
883 _meter_hold = atof (prop->value().c_str());
886 if ((child = find_named_node (node, "meter-falloff")) != 0) {
887 if ((prop = child->property ("val")) != 0) {
888 _meter_falloff = atof (prop->value().c_str());
891 if ((child = find_named_node (node, "long-over-length")) != 0) {
892 if ((prop = child->property ("val")) != 0) {
893 over_length_long = atoi (prop->value().c_str());
896 if ((child = find_named_node (node, "short-over-length")) != 0) {
897 if ((prop = child->property ("val")) != 0) {
898 over_length_short = atoi (prop->value().c_str());
901 if ((child = find_named_node (node, "shuttle-speed-factor")) != 0) {
902 if ((prop = child->property ("val")) != 0) {
903 shuttle_speed_factor = atof (prop->value().c_str());
906 if ((child = find_named_node (node, "shuttle-speed-threshold")) != 0) {
907 if ((prop = child->property ("val")) != 0) {
908 shuttle_speed_threshold = atof (prop->value().c_str());
911 if ((child = find_named_node (node, "rf-speed")) != 0) {
912 if ((prop = child->property ("val")) != 0) {
913 rf_speed = atof (prop->value().c_str());
916 if ((child = find_named_node (node, "smpte-frames-per-second")) != 0) {
917 if ((prop = child->property ("val")) != 0) {
918 set_smpte_type( atof (prop->value().c_str()), smpte_drop_frames );
921 if ((child = find_named_node (node, "smpte-drop-frames")) != 0) {
922 if ((prop = child->property ("val")) != 0) {
923 set_smpte_type( smpte_frames_per_second, (prop->value() == "yes") );
926 if ((child = find_named_node (node, "smpte-offset")) != 0) {
927 if ((prop = child->property ("val")) != 0) {
928 set_smpte_offset( atoi (prop->value().c_str()) );
931 if ((child = find_named_node (node, "smpte-offset-negative")) != 0) {
932 if ((prop = child->property ("val")) != 0) {
933 set_smpte_offset_negative( (prop->value() == "yes") );
936 if ((child = find_named_node (node, "click-sound")) != 0) {
937 if ((prop = child->property ("val")) != 0) {
938 click_sound = prop->value();
941 if ((child = find_named_node (node, "click-emphasis-sound")) != 0) {
942 if ((prop = child->property ("val")) != 0) {
943 click_emphasis_sound = prop->value();
947 if ((child = find_named_node (node, "solo-model")) != 0) {
948 if ((prop = child->property ("val")) != 0) {
949 if (prop->value() == "SoloBus")
950 _solo_model = SoloBus;
952 _solo_model = InverseMute;
956 /* BOOLEAN OPTIONS */
958 if ((child = find_named_node (node, "auto-play")) != 0) {
959 if ((prop = child->property ("val")) != 0) {
960 set_auto_play (prop->value() == "yes");
963 if ((child = find_named_node (node, "auto-input")) != 0) {
964 if ((prop = child->property ("val")) != 0) {
965 set_auto_input (prop->value() == "yes");
968 if ((child = find_named_node (node, "seamless-loop")) != 0) {
969 if ((prop = child->property ("val")) != 0) {
970 set_seamless_loop (prop->value() == "yes");
973 if ((child = find_named_node (node, "punch-in")) != 0) {
974 if ((prop = child->property ("val")) != 0) {
975 set_punch_in (prop->value() == "yes");
978 if ((child = find_named_node (node, "punch-out")) != 0) {
979 if ((prop = child->property ("val")) != 0) {
980 set_punch_out (prop->value() == "yes");
983 if ((child = find_named_node (node, "auto-return")) != 0) {
984 if ((prop = child->property ("val")) != 0) {
985 set_auto_return (prop->value() == "yes");
988 if ((child = find_named_node (node, "send-mtc")) != 0) {
989 if ((prop = child->property ("val")) != 0) {
990 set_send_mtc (prop->value() == "yes");
993 if ((child = find_named_node (node, "mmc-control")) != 0) {
994 if ((prop = child->property ("val")) != 0) {
995 set_mmc_control (prop->value() == "yes");
998 if ((child = find_named_node (node, "midi-control")) != 0) {
999 if ((prop = child->property ("val")) != 0) {
1000 set_midi_control (prop->value() == "yes");
1003 if ((child = find_named_node (node, "midi-feedback")) != 0) {
1004 if ((prop = child->property ("val")) != 0) {
1005 set_midi_feedback (prop->value() == "yes");
1008 // Legacy support for <recording-plugins>
1009 if ((child = find_named_node (node, "recording-plugins")) != 0) {
1010 if ((prop = child->property ("val")) != 0) {
1011 set_do_not_record_plugins (prop->value() == "no");
1014 if ((child = find_named_node (node, "do-not-record-plugins")) != 0) {
1015 if ((prop = child->property ("val")) != 0) {
1016 set_do_not_record_plugins (prop->value() == "yes");
1019 if ((child = find_named_node (node, "crossfades-active")) != 0) {
1020 if ((prop = child->property ("val")) != 0) {
1021 set_crossfades_active (prop->value() == "yes");
1024 if ((child = find_named_node (node, "audible-click")) != 0) {
1025 if ((prop = child->property ("val")) != 0) {
1026 set_clicking (prop->value() == "yes");
1030 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
1031 if ((prop = child->property ("val")) != 0) {
1032 _end_location_is_free = (prop->value() == "yes");
1036 if ((child = find_named_node (node, "layer-model")) != 0) {
1037 if ((prop = child->property ("val")) != 0) {
1038 if (prop->value() == X_("LaterHigher")) {
1039 set_layer_model (LaterHigher);
1040 } else if (prop->value() == X_("AddHigher")) {
1041 set_layer_model (AddHigher);
1043 set_layer_model (MoveAddHigher);
1048 if ((child = find_named_node (node, "xfade-model")) != 0) {
1049 if ((prop = child->property ("val")) != 0) {
1050 if (prop->value() == X_("Short")) {
1051 set_xfade_model (ShortCrossfade);
1053 set_xfade_model (FullCrossfade);
1058 if ((child = find_named_node (node, "short-xfade-length")) != 0) {
1059 if ((prop = child->property ("val")) != 0) {
1060 /* value is stored as a fractional seconds */
1061 float secs = atof (prop->value().c_str());
1062 Crossfade::set_short_xfade_length ((jack_nframes_t) floor (secs * frame_rate()));
1066 if ((child = find_named_node (node, "full-xfades-unmuted")) != 0) {
1067 if ((prop = child->property ("val")) != 0) {
1068 crossfades_active = (prop->value() == "yes");
1074 if ((child = find_named_node (node, "default-fade-steepness")) != 0) {
1075 if ((prop = child->property ("val")) != 0) {
1076 fade_steepness = atof (prop->value().c_str());
1077 have_fade_steepness = true;
1080 if ((child = find_named_node (node, "default-fade-msec")) != 0) {
1081 if ((prop = child->property ("val")) != 0) {
1082 fade_msecs = atof (prop->value().c_str());
1083 have_fade_msecs = true;
1087 if (have_fade_steepness || have_fade_msecs) {
1088 // set_default_fade (fade_steepness, fade_msecs);
1095 Session::get_options () const
1100 LocaleGuard lg (X_("POSIX"));
1102 opthead = new XMLNode ("Options");
1104 SlaveSource src = slave_source ();
1108 src_string = "none";
1114 src_string = "jack";
1117 child = opthead->add_child ("slave");
1118 child->add_property ("type", src_string);
1120 child = opthead->add_child ("send-midi-timecode");
1121 child->add_property ("val", send_midi_timecode?"yes":"no");
1123 child = opthead->add_child ("send-midi-machine-control");
1124 child->add_property ("val", send_midi_machine_control?"yes":"no");
1126 snprintf (buf, sizeof(buf)-1, "%x", (int) input_auto_connect);
1127 child = opthead->add_child ("input-auto-connect");
1128 child->add_property ("val", buf);
1130 snprintf (buf, sizeof(buf)-1, "%x", (int) output_auto_connect);
1131 child = opthead->add_child ("output-auto-connect");
1132 child->add_property ("val", buf);
1134 snprintf (buf, sizeof(buf)-1, "%d", max_level);
1135 child = opthead->add_child ("max-level");
1136 child->add_property ("val", buf);
1138 snprintf (buf, sizeof(buf)-1, "%d", min_level);
1139 child = opthead->add_child ("min-level");
1140 child->add_property ("val", buf);
1142 snprintf (buf, sizeof(buf)-1, "%f", _meter_hold);
1143 child = opthead->add_child ("meter-hold");
1144 child->add_property ("val", buf);
1146 snprintf (buf, sizeof(buf)-1, "%f", _meter_falloff);
1147 child = opthead->add_child ("meter-falloff");
1148 child->add_property ("val", buf);
1150 snprintf (buf, sizeof(buf)-1, "%u", over_length_long);
1151 child = opthead->add_child ("long-over-length");
1152 child->add_property ("val", buf);
1154 snprintf (buf, sizeof(buf)-1, "%u", over_length_short);
1155 child = opthead->add_child ("short-over-length");
1156 child->add_property ("val", buf);
1158 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_factor);
1159 child = opthead->add_child ("shuttle-speed-factor");
1160 child->add_property ("val", buf);
1162 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_threshold);
1163 child = opthead->add_child ("shuttle-speed-threshold");
1164 child->add_property ("val", buf);
1166 snprintf (buf, sizeof(buf)-1, "%f", rf_speed);
1167 child = opthead->add_child ("rf-speed");
1168 child->add_property ("val", buf);
1170 snprintf (buf, sizeof(buf)-1, "%.2f", smpte_frames_per_second);
1171 child = opthead->add_child ("smpte-frames-per-second");
1172 child->add_property ("val", buf);
1174 child = opthead->add_child ("smpte-drop-frames");
1175 child->add_property ("val", smpte_drop_frames ? "yes" : "no");
1177 snprintf (buf, sizeof(buf)-1, "%u", smpte_offset ());
1178 child = opthead->add_child ("smpte-offset");
1179 child->add_property ("val", buf);
1181 child = opthead->add_child ("smpte-offset-negative");
1182 child->add_property ("val", smpte_offset_negative () ? "yes" : "no");
1184 child = opthead->add_child ("edit-mode");
1185 switch (_edit_mode) {
1187 child->add_property ("val", "splice");
1191 child->add_property ("val", "slide");
1195 child = opthead->add_child ("auto-play");
1196 child->add_property ("val", get_auto_play () ? "yes" : "no");
1197 child = opthead->add_child ("auto-input");
1198 child->add_property ("val", get_auto_input () ? "yes" : "no");
1199 child = opthead->add_child ("seamless-loop");
1200 child->add_property ("val", get_seamless_loop () ? "yes" : "no");
1201 child = opthead->add_child ("punch-in");
1202 child->add_property ("val", get_punch_in () ? "yes" : "no");
1203 child = opthead->add_child ("punch-out");
1204 child->add_property ("val", get_punch_out () ? "yes" : "no");
1205 child = opthead->add_child ("all-safe");
1206 child->add_property ("val", get_all_safe () ? "yes" : "no");
1207 child = opthead->add_child ("auto-return");
1208 child->add_property ("val", get_auto_return () ? "yes" : "no");
1209 child = opthead->add_child ("mmc-control");
1210 child->add_property ("val", get_mmc_control () ? "yes" : "no");
1211 child = opthead->add_child ("midi-control");
1212 child->add_property ("val", get_midi_control () ? "yes" : "no");
1213 child = opthead->add_child ("midi-feedback");
1214 child->add_property ("val", get_midi_feedback () ? "yes" : "no");
1215 child = opthead->add_child ("do-not-record-plugins");
1216 child->add_property ("val", get_do_not_record_plugins () ? "yes" : "no");
1217 child = opthead->add_child ("auto-crossfade");
1218 child->add_property ("val", get_crossfades_active () ? "yes" : "no");
1219 child = opthead->add_child ("audible-click");
1220 child->add_property ("val", get_clicking () ? "yes" : "no");
1221 child = opthead->add_child ("end-marker-is-free");
1222 child->add_property ("val", _end_location_is_free ? "yes" : "no");
1224 if (click_sound.length()) {
1225 child = opthead->add_child ("click-sound");
1226 child->add_property ("val", click_sound);
1229 if (click_emphasis_sound.length()) {
1230 child = opthead->add_child ("click-emphasis-sound");
1231 child->add_property ("val", click_emphasis_sound);
1234 child = opthead->add_child ("solo-model");
1235 child->add_property ("val", _solo_model == SoloBus ? "SoloBus" : "InverseMute");
1237 child = opthead->add_child ("layer-model");
1238 switch (layer_model) {
1240 child->add_property ("val", X_("LaterHigher"));
1243 child->add_property ("val", X_("MoveAddHigher"));
1246 child->add_property ("val", X_("AddHigher"));
1250 child = opthead->add_child ("xfade-model");
1251 switch (xfade_model) {
1253 child->add_property ("val", X_("Full"));
1255 case ShortCrossfade:
1256 child->add_property ("val", X_("Short"));
1259 child = opthead->add_child ("short-xfade-length");
1260 /* store as fractions of a second */
1261 snprintf (buf, sizeof(buf)-1, "%f",
1262 (float) Crossfade::short_xfade_length() / frame_rate());
1263 child->add_property ("val", buf);
1265 child = opthead->add_child ("full-xfades-unmuted");
1266 child->add_property ("val", crossfades_active ? "yes" : "no");
1272 Session::get_state()
1278 Session::get_template()
1280 /* if we don't disable rec-enable, diskstreams
1281 will believe they need to store their capture
1282 sources in their state node.
1285 disable_record (false);
1287 return state(false);
1291 Session::state(bool full_state)
1293 XMLNode* node = new XMLNode("Session");
1296 // store libardour version, just in case
1298 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
1299 libardour_major_version, libardour_minor_version, libardour_micro_version);
1300 node->add_property("version", string(buf));
1302 /* store configuration settings */
1306 /* store the name */
1307 node->add_property ("name", _name);
1309 if (session_dirs.size() > 1) {
1313 vector<space_and_path>::iterator i = session_dirs.begin();
1314 vector<space_and_path>::iterator next;
1316 ++i; /* skip the first one */
1320 while (i != session_dirs.end()) {
1324 if (next != session_dirs.end()) {
1334 child = node->add_child ("Path");
1335 child->add_content (p);
1339 /* save the ID counter */
1341 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1342 node->add_property ("id-counter", buf);
1344 /* various options */
1346 node->add_child_nocopy (get_options());
1348 child = node->add_child ("Sources");
1351 Glib::Mutex::Lock sl (audio_source_lock);
1353 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
1355 /* Don't save information about AudioFileSources that are empty */
1357 AudioFileSource* fs;
1359 if ((fs = dynamic_cast<AudioFileSource*> (siter->second)) != 0) {
1360 DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
1362 /* destructive file sources are OK if they are empty, because
1363 we will re-use them every time.
1367 if (fs->length() == 0) {
1373 child->add_child_nocopy (siter->second->get_state());
1377 child = node->add_child ("Regions");
1380 Glib::Mutex::Lock rl (region_lock);
1382 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1384 /* only store regions not attached to playlists */
1386 if (i->second->playlist() == 0) {
1387 child->add_child_nocopy (i->second->state (true));
1392 child = node->add_child ("DiskStreams");
1395 Glib::RWLock::ReaderLock dl (diskstream_lock);
1396 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1397 if (!(*i)->hidden()) {
1398 child->add_child_nocopy ((*i)->get_state());
1403 node->add_child_nocopy (_locations.get_state());
1405 child = node->add_child ("Connections");
1407 Glib::Mutex::Lock lm (connection_lock);
1408 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1409 if (!(*i)->system_dependent()) {
1410 child->add_child_nocopy ((*i)->get_state());
1415 child = node->add_child ("Routes");
1417 boost::shared_ptr<RouteList> r = routes.reader ();
1419 RoutePublicOrderSorter cmp;
1420 RouteList public_order (*r);
1421 public_order.sort (cmp);
1423 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1424 if (!(*i)->hidden()) {
1426 child->add_child_nocopy ((*i)->get_state());
1428 child->add_child_nocopy ((*i)->get_template());
1435 child = node->add_child ("EditGroups");
1436 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1437 child->add_child_nocopy ((*i)->get_state());
1440 child = node->add_child ("MixGroups");
1441 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1442 child->add_child_nocopy ((*i)->get_state());
1445 child = node->add_child ("Playlists");
1446 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1447 if (!(*i)->hidden()) {
1448 if (!(*i)->empty()) {
1450 child->add_child_nocopy ((*i)->get_state());
1452 child->add_child_nocopy ((*i)->get_template());
1458 child = node->add_child ("UnusedPlaylists");
1459 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1460 if (!(*i)->hidden()) {
1461 if (!(*i)->empty()) {
1463 child->add_child_nocopy ((*i)->get_state());
1465 child->add_child_nocopy ((*i)->get_template());
1473 child = node->add_child ("Click");
1474 child->add_child_nocopy (_click_io->state (full_state));
1478 child = node->add_child ("NamedSelections");
1479 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1481 child->add_child_nocopy ((*i)->get_state());
1486 node->add_child_nocopy (_tempo_map->get_state());
1489 node->add_child_copy (*_extra_xml);
1496 Session::set_state (const XMLNode& node)
1500 const XMLProperty* prop;
1503 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1505 if (node.name() != X_("Session")){
1506 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1510 StateManager::prohibit_save ();
1512 if ((prop = node.property ("name")) != 0) {
1513 _name = prop->value ();
1516 if ((prop = node.property (X_("id-counter"))) != 0) {
1518 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1519 ID::init_counter (x);
1521 /* old sessions used a timebased counter, so fake
1522 the startup ID counter based on a standard
1527 ID::init_counter (now);
1531 IO::disable_ports ();
1532 IO::disable_connecting ();
1534 /* Object loading order:
1551 if (use_config_midi_ports ()) {
1554 if ((child = find_named_node (node, "Path")) != 0) {
1555 /* XXX this XML content stuff horrible API design */
1556 string raid_path = _path + ':' + child->children().front()->content();
1557 setup_raid_path (raid_path);
1559 /* the path is already set */
1562 if ((child = find_named_node (node, "extra")) != 0) {
1563 _extra_xml = new XMLNode (*child);
1566 if ((child = find_named_node (node, "Options")) == 0) {
1567 error << _("Session: XML state has no options section") << endmsg;
1568 } else if (load_options (*child)) {
1571 if ((child = find_named_node (node, "Sources")) == 0) {
1572 error << _("Session: XML state has no sources section") << endmsg;
1574 } else if (load_sources (*child)) {
1578 if ((child = find_named_node (node, "Regions")) == 0) {
1579 error << _("Session: XML state has no Regions section") << endmsg;
1581 } else if (load_regions (*child)) {
1585 if ((child = find_named_node (node, "Playlists")) == 0) {
1586 error << _("Session: XML state has no playlists section") << endmsg;
1588 } else if (load_playlists (*child)) {
1592 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1594 } else if (load_unused_playlists (*child)) {
1598 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1599 if (load_named_selections (*child)) {
1604 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1605 error << _("Session: XML state has no diskstreams section") << endmsg;
1607 } else if (load_diskstreams (*child)) {
1611 if ((child = find_named_node (node, "Connections")) == 0) {
1612 error << _("Session: XML state has no connections section") << endmsg;
1614 } else if (load_connections (*child)) {
1618 if ((child = find_named_node (node, "Locations")) == 0) {
1619 error << _("Session: XML state has no locations section") << endmsg;
1621 } else if (_locations.set_state (*child)) {
1627 if ((location = _locations.auto_loop_location()) != 0) {
1628 set_auto_loop_location (location);
1631 if ((location = _locations.auto_punch_location()) != 0) {
1632 set_auto_punch_location (location);
1635 if ((location = _locations.end_location()) == 0) {
1636 _locations.add (end_location);
1638 delete end_location;
1639 end_location = location;
1642 if ((location = _locations.start_location()) == 0) {
1643 _locations.add (start_location);
1645 delete start_location;
1646 start_location = location;
1649 _locations.save_state (_("initial state"));
1651 if ((child = find_named_node (node, "EditGroups")) == 0) {
1652 error << _("Session: XML state has no edit groups section") << endmsg;
1654 } else if (load_edit_groups (*child)) {
1658 if ((child = find_named_node (node, "MixGroups")) == 0) {
1659 error << _("Session: XML state has no mix groups section") << endmsg;
1661 } else if (load_mix_groups (*child)) {
1665 if ((child = find_named_node (node, "TempoMap")) == 0) {
1666 error << _("Session: XML state has no Tempo Map section") << endmsg;
1668 } else if (_tempo_map->set_state (*child)) {
1672 if ((child = find_named_node (node, "Routes")) == 0) {
1673 error << _("Session: XML state has no routes section") << endmsg;
1675 } else if (load_routes (*child)) {
1679 if ((child = find_named_node (node, "Click")) == 0) {
1680 warning << _("Session: XML state has no click section") << endmsg;
1681 } else if (_click_io) {
1682 _click_io->set_state (*child);
1685 /* OK, now we can set edit mode */
1687 set_edit_mode (pending_edit_mode);
1689 /* here beginneth the second phase ... */
1691 StateReady (); /* EMIT SIGNAL */
1693 _state_of_the_state = Clean;
1695 StateManager::allow_save (_("initial state"), true);
1697 if (state_was_pending) {
1698 save_state (_current_snapshot_name);
1699 remove_pending_capture_state ();
1700 state_was_pending = false;
1706 /* we failed, re-enable state saving but don't actually save internal state */
1707 StateManager::allow_save (X_("ignored"), false);
1712 Session::load_routes (const XMLNode& node)
1715 XMLNodeConstIterator niter;
1717 nlist = node.children();
1721 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1723 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1726 error << _("Session: cannot create Route from XML description.") << endmsg;
1736 boost::shared_ptr<Route>
1737 Session::XMLRouteFactory (const XMLNode& node)
1739 if (node.name() != "Route") {
1740 return boost::shared_ptr<Route> ((Route*) 0);
1743 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1745 Buffer::Type type = Buffer::AUDIO;
1746 const XMLProperty* prop = node.property("default-type");
1748 type = Buffer::type_from_string(prop->value());
1750 assert(type != Buffer::NIL);
1752 if (has_diskstream) {
1753 if (type == Buffer::AUDIO) {
1754 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1757 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1761 boost::shared_ptr<Route> ret (new Route (*this, node));
1767 Session::load_regions (const XMLNode& node)
1770 XMLNodeConstIterator niter;
1771 AudioRegion* region;
1773 nlist = node.children();
1777 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1778 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1779 error << _("Session: cannot create Region from XML description.") << endmsg;
1786 Session::XMLRegionFactory (const XMLNode& node, bool full)
1788 const XMLProperty* prop;
1791 AudioRegion::SourceList sources;
1792 uint32_t nchans = 1;
1795 if (node.name() != X_("Region")) {
1799 if ((prop = node.property (X_("channels"))) != 0) {
1800 nchans = atoi (prop->value().c_str());
1804 if ((prop = node.property (X_("source-0"))) == 0) {
1805 if ((prop = node.property ("source")) == 0) {
1806 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1811 PBD::ID s_id (prop->value());
1813 if ((source = source_by_id (s_id)) == 0) {
1814 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1818 as = dynamic_cast<AudioSource*>(source);
1820 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1824 sources.push_back (as);
1826 /* pickup other channels */
1828 for (uint32_t n=1; n < nchans; ++n) {
1829 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1830 if ((prop = node.property (buf)) != 0) {
1832 PBD::ID id2 (prop->value());
1834 if ((source = source_by_id (id2)) == 0) {
1835 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1839 as = dynamic_cast<AudioSource*>(source);
1841 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1844 sources.push_back (as);
1849 return new AudioRegion (sources, node);
1852 catch (failed_constructor& err) {
1858 Session::get_sources_as_xml ()
1861 XMLNode* node = new XMLNode (X_("Sources"));
1862 Glib::Mutex::Lock lm (audio_source_lock);
1864 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1865 node->add_child_nocopy (i->second->get_state());
1868 /* XXX get MIDI and other sources here */
1874 Session::path_from_region_name (string name, string identifier)
1876 char buf[PATH_MAX+1];
1878 string dir = discover_best_sound_dir ();
1880 for (n = 0; n < 999999; ++n) {
1881 if (identifier.length()) {
1882 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1883 identifier.c_str(), n);
1885 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1887 if (access (buf, F_OK) != 0) {
1897 Session::load_sources (const XMLNode& node)
1900 XMLNodeConstIterator niter;
1903 nlist = node.children();
1907 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1909 if ((source = XMLSourceFactory (**niter)) == 0) {
1910 error << _("Session: cannot create Source from XML description.") << endmsg;
1918 Session::XMLSourceFactory (const XMLNode& node)
1922 if (node.name() != "Source") {
1927 src = AudioFileSource::create (node);
1930 catch (failed_constructor& err) {
1931 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1939 Session::save_template (string template_name)
1942 string xml_path, bak_path, template_path;
1944 if (_state_of_the_state & CannotSave) {
1949 string dir = template_dir();
1951 if ((dp = opendir (dir.c_str()))) {
1954 if (mkdir (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)<0) {
1955 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1960 tree.set_root (&get_template());
1963 xml_path += template_name;
1964 xml_path += _template_suffix;
1966 ifstream in(xml_path.c_str());
1969 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1975 if (!tree.write (xml_path)) {
1976 error << _("mix template not saved") << endmsg;
1984 Session::rename_template (string old_name, string new_name)
1986 string old_path = template_dir() + old_name + _template_suffix;
1987 string new_path = template_dir() + new_name + _template_suffix;
1989 return rename (old_path.c_str(), new_path.c_str());
1993 Session::delete_template (string name)
1995 string template_path = template_dir();
1996 template_path += name;
1997 template_path += _template_suffix;
1999 return remove (template_path.c_str());
2003 Session::refresh_disk_space ()
2006 struct statfs statfsbuf;
2007 vector<space_and_path>::iterator i;
2008 Glib::Mutex::Lock lm (space_lock);
2011 /* get freespace on every FS that is part of the session path */
2013 _total_free_4k_blocks = 0;
2015 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2016 statfs ((*i).path.c_str(), &statfsbuf);
2018 scale = statfsbuf.f_bsize/4096.0;
2020 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2021 _total_free_4k_blocks += (*i).blocks;
2027 Session::ensure_sound_dir (string path, string& result)
2032 /* Ensure that the parent directory exists */
2034 if (mkdir (path.c_str(), 0775)) {
2035 if (errno != EEXIST) {
2036 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
2041 /* Ensure that the sounds directory exists */
2045 result += sound_dir_name;
2047 if (mkdir (result.c_str(), 0775)) {
2048 if (errno != EEXIST) {
2049 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
2056 dead += dead_sound_dir_name;
2058 if (mkdir (dead.c_str(), 0775)) {
2059 if (errno != EEXIST) {
2060 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
2067 peak += peak_dir_name;
2069 if (mkdir (peak.c_str(), 0775)) {
2070 if (errno != EEXIST) {
2071 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
2076 /* callers expect this to be terminated ... */
2083 Session::discover_best_sound_dir (bool destructive)
2085 vector<space_and_path>::iterator i;
2088 /* destructive files all go into the same place */
2094 /* handle common case without system calls */
2096 if (session_dirs.size() == 1) {
2100 /* OK, here's the algorithm we're following here:
2102 We want to select which directory to use for
2103 the next file source to be created. Ideally,
2104 we'd like to use a round-robin process so as to
2105 get maximum performance benefits from splitting
2106 the files across multiple disks.
2108 However, in situations without much diskspace, an
2109 RR approach may end up filling up a filesystem
2110 with new files while others still have space.
2111 Its therefore important to pay some attention to
2112 the freespace in the filesystem holding each
2113 directory as well. However, if we did that by
2114 itself, we'd keep creating new files in the file
2115 system with the most space until it was as full
2116 as all others, thus negating any performance
2117 benefits of this RAID-1 like approach.
2119 So, we use a user-configurable space threshold. If
2120 there are at least 2 filesystems with more than this
2121 much space available, we use RR selection between them.
2122 If not, then we pick the filesystem with the most space.
2124 This gets a good balance between the two
2128 refresh_disk_space ();
2130 int free_enough = 0;
2132 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2133 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2138 if (free_enough >= 2) {
2140 bool found_it = false;
2142 /* use RR selection process, ensuring that the one
2146 i = last_rr_session_dir;
2149 if (++i == session_dirs.end()) {
2150 i = session_dirs.begin();
2153 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2154 if (ensure_sound_dir ((*i).path, result) == 0) {
2155 last_rr_session_dir = i;
2161 } while (i != last_rr_session_dir);
2164 result = sound_dir();
2169 /* pick FS with the most freespace (and that
2170 seems to actually work ...)
2173 vector<space_and_path> sorted;
2174 space_and_path_ascending_cmp cmp;
2176 sorted = session_dirs;
2177 sort (sorted.begin(), sorted.end(), cmp);
2179 for (i = sorted.begin(); i != sorted.end(); ++i) {
2180 if (ensure_sound_dir ((*i).path, result) == 0) {
2181 last_rr_session_dir = i;
2186 /* if the above fails, fall back to the most simplistic solution */
2188 if (i == sorted.end()) {
2197 Session::load_playlists (const XMLNode& node)
2200 XMLNodeConstIterator niter;
2203 nlist = node.children();
2207 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2209 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2210 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2218 Session::load_unused_playlists (const XMLNode& node)
2221 XMLNodeConstIterator niter;
2224 nlist = node.children();
2228 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2230 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2231 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2235 // now manually untrack it
2237 track_playlist (playlist, false);
2245 Session::XMLPlaylistFactory (const XMLNode& node)
2248 return new AudioPlaylist (*this, node);
2251 catch (failed_constructor& err) {
2257 Session::load_named_selections (const XMLNode& node)
2260 XMLNodeConstIterator niter;
2263 nlist = node.children();
2267 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2269 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2270 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2278 Session::XMLNamedSelectionFactory (const XMLNode& node)
2281 return new NamedSelection (*this, node);
2284 catch (failed_constructor& err) {
2290 Session::dead_sound_dir () const
2293 res += dead_sound_dir_name;
2299 Session::sound_dir () const
2302 res += sound_dir_name;
2308 Session::tape_dir () const
2311 res += tape_dir_name;
2317 Session::peak_dir () const
2320 res += peak_dir_name;
2326 Session::automation_dir () const
2329 res += "automation/";
2334 Session::template_dir ()
2336 string path = get_user_ardour_path();
2337 path += "templates/";
2343 Session::suffixed_search_path (string suffix, bool data)
2347 path += get_user_ardour_path();
2348 if (path[path.length()-1] != ':') {
2353 path += get_system_data_path();
2355 path += get_system_module_path();
2358 vector<string> split_path;
2360 split (path, split_path, ':');
2363 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2368 if (distance (i, split_path.end()) != 1) {
2377 Session::template_path ()
2379 return suffixed_search_path (X_("templates"), true);
2383 Session::control_protocol_path ()
2385 return suffixed_search_path (X_("surfaces"), false);
2389 Session::load_connections (const XMLNode& node)
2391 XMLNodeList nlist = node.children();
2392 XMLNodeConstIterator niter;
2396 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2397 if ((*niter)->name() == "InputConnection") {
2398 add_connection (new ARDOUR::InputConnection (**niter));
2399 } else if ((*niter)->name() == "OutputConnection") {
2400 add_connection (new ARDOUR::OutputConnection (**niter));
2402 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2411 Session::load_edit_groups (const XMLNode& node)
2413 return load_route_groups (node, true);
2417 Session::load_mix_groups (const XMLNode& node)
2419 return load_route_groups (node, false);
2423 Session::load_route_groups (const XMLNode& node, bool edit)
2425 XMLNodeList nlist = node.children();
2426 XMLNodeConstIterator niter;
2431 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2432 if ((*niter)->name() == "RouteGroup") {
2434 rg = add_edit_group ("");
2435 rg->set_state (**niter);
2437 rg = add_mix_group ("");
2438 rg->set_state (**niter);
2447 state_file_filter (const string &str, void *arg)
2449 return (str.length() > strlen(Session::statefile_suffix()) &&
2450 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2454 bool operator()(const string* a, const string* b) {
2460 remove_end(string* state)
2462 string statename(*state);
2464 string::size_type start,end;
2465 if ((start = statename.find_last_of ('/')) != string::npos) {
2466 statename = statename.substr (start+1);
2469 if ((end = statename.rfind(".ardour")) == string::npos) {
2470 end = statename.length();
2473 return new string(statename.substr (0, end));
2477 Session::possible_states (string path)
2479 PathScanner scanner;
2480 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2482 transform(states->begin(), states->end(), states->begin(), remove_end);
2485 sort (states->begin(), states->end(), cmp);
2491 Session::possible_states () const
2493 return possible_states(_path);
2497 Session::auto_save()
2499 save_state (_current_snapshot_name);
2503 Session::add_edit_group (string name)
2505 RouteGroup* rg = new RouteGroup (*this, name);
2506 edit_groups.push_back (rg);
2507 edit_group_added (rg); /* EMIT SIGNAL */
2513 Session::add_mix_group (string name)
2515 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2516 mix_groups.push_back (rg);
2517 mix_group_added (rg); /* EMIT SIGNAL */
2523 Session::remove_edit_group (RouteGroup& rg)
2525 list<RouteGroup*>::iterator i;
2527 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2528 (*i)->apply (&Route::drop_edit_group, this);
2529 edit_groups.erase (i);
2530 edit_group_removed (); /* EMIT SIGNAL */
2537 Session::remove_mix_group (RouteGroup& rg)
2539 list<RouteGroup*>::iterator i;
2541 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2542 (*i)->apply (&Route::drop_mix_group, this);
2543 mix_groups.erase (i);
2544 mix_group_removed (); /* EMIT SIGNAL */
2551 Session::mix_group_by_name (string name)
2553 list<RouteGroup *>::iterator i;
2555 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2556 if ((*i)->name() == name) {
2564 Session::edit_group_by_name (string name)
2566 list<RouteGroup *>::iterator i;
2568 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2569 if ((*i)->name() == name) {
2577 Session::set_meter_hold (float val)
2580 MeterHoldChanged(); // emit
2584 Session::set_meter_falloff (float val)
2586 _meter_falloff = val;
2587 MeterFalloffChanged(); // emit
2592 Session::begin_reversible_command (string name, UndoAction* private_undo)
2594 current_cmd.clear ();
2595 current_cmd.set_name (name);
2598 current_cmd.add_undo (*private_undo);
2603 Session::commit_reversible_command (UndoAction* private_redo)
2608 current_cmd.add_redo_no_execute (*private_redo);
2611 gettimeofday (&now, 0);
2612 current_cmd.set_timestamp (now);
2614 history.add (current_cmd);
2617 Session::GlobalRouteBooleanState
2618 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2620 GlobalRouteBooleanState s;
2621 boost::shared_ptr<RouteList> r = routes.reader ();
2623 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2624 if (!(*i)->hidden()) {
2625 RouteBooleanState v;
2628 Route* r = (*i).get();
2629 v.second = (r->*method)();
2638 Session::GlobalRouteMeterState
2639 Session::get_global_route_metering ()
2641 GlobalRouteMeterState s;
2642 boost::shared_ptr<RouteList> r = routes.reader ();
2644 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2645 if (!(*i)->hidden()) {
2649 v.second = (*i)->meter_point();
2659 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2661 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2662 i->first->set_meter_point (i->second, arg);
2667 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2669 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2670 Route* r = i->first.get();
2671 (r->*method) (i->second, arg);
2676 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2678 set_global_route_boolean (s, &Route::set_mute, src);
2682 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2684 set_global_route_boolean (s, &Route::set_solo, src);
2688 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2690 set_global_route_boolean (s, &Route::set_record_enable, src);
2694 Session::global_mute_memento (void* src)
2696 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2700 Session::global_metering_memento (void* src)
2702 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2706 Session::global_solo_memento (void* src)
2708 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2712 Session::global_record_enable_memento (void* src)
2714 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2718 template_filter (const string &str, void *arg)
2720 return (str.length() > strlen(Session::template_suffix()) &&
2721 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2725 Session::get_template_list (list<string> &template_names)
2727 vector<string *> *templates;
2728 PathScanner scanner;
2731 path = template_path ();
2733 templates = scanner (path, template_filter, 0, false, true);
2735 vector<string*>::iterator i;
2736 for (i = templates->begin(); i != templates->end(); ++i) {
2737 string fullpath = *(*i);
2740 start = fullpath.find_last_of ('/') + 1;
2741 if ((end = fullpath.find_last_of ('.')) <0) {
2742 end = fullpath.length();
2745 template_names.push_back(fullpath.substr(start, (end-start)));
2750 Session::read_favorite_dirs (FavoriteDirs & favs)
2752 string path = get_user_ardour_path();
2753 path += "/favorite_dirs";
2755 ifstream fav (path.c_str());
2760 if (errno != ENOENT) {
2761 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2772 getline(fav, newfav);
2778 favs.push_back (newfav);
2785 Session::write_favorite_dirs (FavoriteDirs & favs)
2787 string path = get_user_ardour_path();
2788 path += "/favorite_dirs";
2790 ofstream fav (path.c_str());
2796 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2797 fav << (*i) << endl;
2804 accept_all_non_peak_files (const string& path, void *arg)
2806 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2810 accept_all_state_files (const string& path, void *arg)
2812 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2816 Session::find_all_sources (string path, set<string>& result)
2821 if (!tree.read (path)) {
2825 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2830 XMLNodeConstIterator niter;
2832 nlist = node->children();
2836 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2840 if ((prop = (*niter)->property (X_("name"))) == 0) {
2844 if (prop->value()[0] == '/') {
2845 /* external file, ignore */
2849 string path = _path; /* /-terminated */
2850 path += sound_dir_name;
2852 path += prop->value();
2854 result.insert (path);
2861 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2863 PathScanner scanner;
2864 vector<string*>* state_files;
2866 string this_snapshot_path;
2872 if (ripped[ripped.length()-1] == '/') {
2873 ripped = ripped.substr (0, ripped.length() - 1);
2876 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2878 if (state_files == 0) {
2883 this_snapshot_path = _path;
2884 this_snapshot_path += _current_snapshot_name;
2885 this_snapshot_path += _statefile_suffix;
2887 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2889 if (exclude_this_snapshot && **i == this_snapshot_path) {
2893 if (find_all_sources (**i, result) < 0) {
2902 Session::cleanup_sources (Session::cleanup_report& rep)
2904 vector<Source*> dead_sources;
2905 vector<Playlist*> playlists_tbd;
2906 PathScanner scanner;
2908 vector<space_and_path>::iterator i;
2909 vector<space_and_path>::iterator nexti;
2910 vector<string*>* soundfiles;
2911 vector<string> unused;
2912 set<string> all_sources;
2917 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2919 /* step 1: consider deleting all unused playlists */
2921 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2924 status = AskAboutPlaylistDeletion (*x);
2933 playlists_tbd.push_back (*x);
2937 /* leave it alone */
2942 /* now delete any that were marked for deletion */
2944 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2945 PlaylistList::iterator foo;
2947 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2948 unused_playlists.erase (foo);
2953 /* step 2: clear the undo/redo history for all playlists */
2955 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2956 (*x)->drop_all_states ();
2959 /* step 3: find all un-referenced sources */
2964 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2966 AudioSourceList::iterator tmp;
2971 /* only remove files that are not in use and have some size
2972 to them. otherwise we remove the current "nascent"
2976 if (i->second->use_cnt() == 0 && i->second->length() > 0) {
2977 dead_sources.push_back (i->second);
2979 /* remove this source from our own list to avoid us
2980 adding it to the list of all sources below
2983 audio_sources.erase (i);
2989 /* Step 4: get rid of all regions in the region list that use any dead sources
2990 in case the sources themselves don't go away (they might be referenced in
2994 for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2996 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2997 AudioRegionList::iterator tmp;
3005 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
3006 if (&ar->source (n) == (*i)) {
3007 /* this region is dead */
3016 /* build a list of all the possible sound directories for the session */
3018 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
3023 sound_path += (*i).path;
3024 sound_path += sound_dir_name;
3026 if (nexti != session_dirs.end()) {
3033 /* now do the same thing for the files that ended up in the sounds dir(s)
3034 but are not referenced as sources in any snapshot.
3037 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
3039 if (soundfiles == 0) {
3043 /* find all sources, but don't use this snapshot because the
3044 state file on disk still references sources we may have already
3048 find_all_sources_across_snapshots (all_sources, true);
3050 /* add our current source list
3053 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
3054 AudioFileSource* fs;
3056 if ((fs = dynamic_cast<AudioFileSource*> (i->second)) != 0) {
3057 all_sources.insert (fs->path());
3061 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
3066 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
3076 unused.push_back (spath);
3080 /* now try to move all unused files into the "dead_sounds" directory(ies) */
3082 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
3083 struct stat statbuf;
3085 rep.paths.push_back (*x);
3086 if (stat ((*x).c_str(), &statbuf) == 0) {
3087 rep.space += statbuf.st_size;
3092 /* don't move the file across filesystems, just
3093 stick it in the `dead_sound_dir_name' directory
3094 on whichever filesystem it was already on.
3097 newpath = Glib::path_get_dirname (*x);
3098 newpath = Glib::path_get_dirname (newpath);
3101 newpath += dead_sound_dir_name;
3103 newpath += Glib::path_get_basename ((*x));
3105 if (access (newpath.c_str(), F_OK) == 0) {
3107 /* the new path already exists, try versioning */
3109 char buf[PATH_MAX+1];
3113 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
3116 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
3117 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
3121 if (version == 999) {
3122 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
3126 newpath = newpath_v;
3131 /* it doesn't exist, or we can't read it or something */
3135 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
3136 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
3137 (*x), newpath, strerror (errno))
3143 /* see if there an easy to find peakfile for this file, and remove it.
3146 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
3147 peakpath += ".peak";
3149 if (access (peakpath.c_str(), W_OK) == 0) {
3150 if (::unlink (peakpath.c_str()) != 0) {
3151 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3152 peakpath, _path, strerror (errno))
3154 /* try to back out */
3155 rename (newpath.c_str(), _path.c_str());
3164 /* dump the history list */
3168 /* save state so we don't end up a session file
3169 referring to non-existent sources.
3175 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3180 Session::cleanup_trash_sources (Session::cleanup_report& rep)
3182 vector<space_and_path>::iterator i;
3183 string dead_sound_dir;
3184 struct dirent* dentry;
3185 struct stat statbuf;
3191 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3193 dead_sound_dir = (*i).path;
3194 dead_sound_dir += dead_sound_dir_name;
3196 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
3200 while ((dentry = readdir (dead)) != 0) {
3202 /* avoid '.' and '..' */
3204 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
3205 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3211 fullpath = dead_sound_dir;
3213 fullpath += dentry->d_name;
3215 if (stat (fullpath.c_str(), &statbuf)) {
3219 if (!S_ISREG (statbuf.st_mode)) {
3223 if (unlink (fullpath.c_str())) {
3224 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3225 fullpath, strerror (errno))
3229 rep.paths.push_back (dentry->d_name);
3230 rep.space += statbuf.st_size;
3241 Session::set_dirty ()
3243 bool was_dirty = dirty();
3245 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3248 DirtyChanged(); /* EMIT SIGNAL */
3254 Session::set_clean ()
3256 bool was_dirty = dirty();
3258 _state_of_the_state = Clean;
3261 DirtyChanged(); /* EMIT SIGNAL */
3266 Session::add_controllable (Controllable* c)
3268 Glib::Mutex::Lock lm (controllables_lock);
3269 controllables.push_back (c);
3273 Session::remove_controllable (Controllable* c)
3275 if (_state_of_the_state | Deletion) {
3279 Glib::Mutex::Lock lm (controllables_lock);
3280 controllables.remove (c);
3284 Session::controllable_by_id (const PBD::ID& id)
3286 Glib::Mutex::Lock lm (controllables_lock);
3288 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3289 if ((*i)->id() == id) {
3298 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3300 Stateful::add_instant_xml (node, dir);
3301 Config->add_instant_xml (node, get_user_ardour_path());