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/utils.h>
63 #include <ardour/audioplaylist.h>
64 #include <ardour/audiofilesource.h>
65 #include <ardour/destructive_filesource.h>
66 #include <ardour/sndfile_helpers.h>
67 #include <ardour/auditioner.h>
68 #include <ardour/export.h>
69 #include <ardour/redirect.h>
70 #include <ardour/send.h>
71 #include <ardour/insert.h>
72 #include <ardour/connection.h>
73 #include <ardour/slave.h>
74 #include <ardour/tempo.h>
75 #include <ardour/audio_track.h>
76 #include <ardour/cycle_timer.h>
77 #include <ardour/utils.h>
78 #include <ardour/named_selection.h>
79 #include <ardour/version.h>
80 #include <ardour/location.h>
81 #include <ardour/audioregion.h>
82 #include <ardour/crossfade.h>
83 #include <ardour/control_protocol_manager.h>
89 using namespace ARDOUR;
93 Session::first_stage_init (string fullpath, string snapshot_name)
95 if (fullpath.length() == 0) {
96 throw failed_constructor();
100 if (!realpath(fullpath.c_str(), buf) && (errno != ENOENT)) {
101 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
102 throw failed_constructor();
106 if (_path[_path.length()-1] != '/') {
110 /* these two are just provisional settings. set_state()
111 will likely override them.
114 _name = _current_snapshot_name = snapshot_name;
115 setup_raid_path (_path);
117 _current_frame_rate = _engine.frame_rate ();
118 _tempo_map = new TempoMap (_current_frame_rate);
119 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
121 g_atomic_int_set (&processing_prohibited, 0);
124 _transport_speed = 0;
125 _last_transport_speed = 0;
126 transport_sub_state = 0;
127 _transport_frame = 0;
129 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
130 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
131 _end_location_is_free = true;
132 g_atomic_int_set (&_record_status, Disabled);
137 seamless_loop = false;
138 loop_changing = false;
140 crossfades_active = false;
143 _last_roll_location = 0;
144 _last_record_location = 0;
145 pending_locate_frame = 0;
146 pending_locate_roll = false;
147 pending_locate_flush = false;
148 dstream_buffer_size = 0;
150 state_was_pending = false;
152 outbound_mtc_smpte_frame = 0;
153 next_quarter_frame_to_send = -1;
154 current_block_size = 0;
155 _solo_latched = true;
156 _solo_model = InverseMute;
157 solo_update_disabled = false;
158 currently_soloing = false;
159 _have_captured = false;
160 _worst_output_latency = 0;
161 _worst_input_latency = 0;
162 _worst_track_latency = 0;
163 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
166 butler_mixdown_buffer = 0;
167 butler_gain_buffer = 0;
171 post_transport_work = PostTransportWork (0);
172 g_atomic_int_set (&butler_should_do_transport_work, 0);
173 g_atomic_int_set (&butler_active, 0);
174 g_atomic_int_set (&_playback_load, 100);
175 g_atomic_int_set (&_capture_load, 100);
176 g_atomic_int_set (&_playback_load_min, 100);
177 g_atomic_int_set (&_capture_load_min, 100);
178 pending_audition_region = 0;
180 pending_edit_mode = _edit_mode;
182 input_auto_connect = AutoConnectOption (0);
183 output_auto_connect = AutoConnectOption (0);
184 waiting_to_start = false;
186 _gain_automation_buffer = 0;
187 _pan_automation_buffer = 0;
189 pending_abort = false;
190 layer_model = MoveAddHigher;
191 xfade_model = ShortCrossfade;
192 destructive_index = 0;
194 AudioDiskstream::allocate_working_buffers();
196 /* default short fade = 15ms */
198 Crossfade::set_short_xfade_length ((jack_nframes_t) floor ((15.0 * frame_rate()) / 1000.0));
199 DestructiveFileSource::setup_standard_crossfades (frame_rate());
201 last_mmc_step.tv_sec = 0;
202 last_mmc_step.tv_usec = 0;
205 preroll.type = AnyTime::Frames;
207 postroll.type = AnyTime::Frames;
210 /* click sounds are unset by default, which causes us to internal
211 waveforms for clicks.
215 click_requested = false;
217 click_emphasis_data = 0;
219 click_emphasis_length = 0;
221 process_function = &Session::process_with_events;
225 _smpte_offset_negative = true;
226 last_smpte_valid = false;
228 last_rr_session_dir = session_dirs.begin();
229 refresh_disk_space ();
231 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
233 /* default configuration */
235 do_not_record_plugins = false;
236 over_length_short = 2;
237 over_length_long = 10;
238 send_midi_timecode = false;
239 send_midi_machine_control = false;
240 shuttle_speed_factor = 1.0;
241 shuttle_speed_threshold = 5;
243 _meter_hold = 100; // XXX unknown units: number of calls to meter::set()
244 _meter_falloff = 1.5f; // XXX unknown units: refresh_rate
250 average_slave_delta = 1800;
251 have_first_delta_accumulator = false;
252 delta_accumulator_cnt = 0;
253 slave_state = Stopped;
255 /* default SMPTE type is 30 FPS, non-drop */
257 set_smpte_type (30.0, false);
259 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
261 /* These are all static "per-class" signals */
263 Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
264 AudioSource::AudioSourceCreated.connect (mem_fun (*this, &Session::add_audio_source));
265 Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
266 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
267 AudioDiskstream::DiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
268 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
270 Controllable::Created.connect (mem_fun (*this, &Session::add_controllable));
271 Controllable::GoingAway.connect (mem_fun (*this, &Session::remove_controllable));
273 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
275 /* stop IO objects from doing stuff until we're ready for them */
277 IO::disable_panners ();
278 IO::disable_ports ();
279 IO::disable_connecting ();
283 Session::second_stage_init (bool new_session)
285 AudioFileSource::set_peak_dir (peak_dir());
288 if (load_state (_current_snapshot_name)) {
291 remove_empty_sounds ();
294 if (start_butler_thread()) {
298 if (start_midi_thread ()) {
303 if (set_state (*state_tree->root())) {
308 /* we can't save till after ::when_engine_running() is called,
309 because otherwise we save state with no connections made.
310 therefore, we reset _state_of_the_state because ::set_state()
311 will have cleared it.
313 we also have to include Loading so that any events that get
314 generated between here and the end of ::when_engine_running()
315 will be processed directly rather than queued.
318 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
320 // set_auto_input (true);
321 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
322 _locations.added.connect (mem_fun (this, &Session::locations_added));
323 setup_click_sounds (0);
324 setup_midi_control ();
326 /* Pay attention ... */
328 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
329 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
331 if (_engine.running()) {
332 when_engine_running();
334 first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
337 send_full_time_code ();
338 _engine.transport_locate (0);
339 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
340 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
342 ControlProtocolManager::instance().set_session (*this);
345 _end_location_is_free = true;
347 _end_location_is_free = false;
354 Session::raid_path () const
358 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
363 return path.substr (0, path.length() - 1); // drop final colon
367 Session::set_raid_path (string path)
369 /* public-access to setup_raid_path() */
371 setup_raid_path (path);
375 Session::setup_raid_path (string path)
377 string::size_type colon;
381 string::size_type len = path.length();
386 if (path.length() == 0) {
390 session_dirs.clear ();
392 for (string::size_type n = 0; n < len; ++n) {
393 if (path[n] == ':') {
400 /* no multiple search path, just one location (common case) */
404 session_dirs.push_back (sp);
411 if (fspath[fspath.length()-1] != '/') {
414 fspath += sound_dir_name;
420 if (fspath[fspath.length()-1] != '/') {
423 fspath += tape_dir_name;
425 AudioFileSource::set_search_path (fspath);
432 while ((colon = remaining.find_first_of (':')) != string::npos) {
435 sp.path = remaining.substr (0, colon);
436 session_dirs.push_back (sp);
438 /* add sounds to file search path */
441 if (fspath[fspath.length()-1] != '/') {
444 fspath += sound_dir_name;
447 /* add tape dir to file search path */
450 if (fspath[fspath.length()-1] != '/') {
453 fspath += tape_dir_name;
456 remaining = remaining.substr (colon+1);
459 if (remaining.length()) {
466 if (fspath[fspath.length()-1] != '/') {
469 fspath += sound_dir_name;
473 if (fspath[fspath.length()-1] != '/') {
476 fspath += tape_dir_name;
478 session_dirs.push_back (sp);
481 /* set the AudioFileSource search path */
483 AudioFileSource::set_search_path (fspath);
485 /* reset the round-robin soundfile path thingie */
487 last_rr_session_dir = session_dirs.begin();
491 Session::create (bool& new_session, string* mix_template, jack_nframes_t initial_length)
495 if (mkdir (_path.c_str(), 0755) < 0) {
496 if (errno == EEXIST) {
499 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
508 if (mkdir (dir.c_str(), 0755) < 0) {
509 if (errno != EEXIST) {
510 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
517 if (mkdir (dir.c_str(), 0755) < 0) {
518 if (errno != EEXIST) {
519 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
526 if (mkdir (dir.c_str(), 0755) < 0) {
527 if (errno != EEXIST) {
528 error << string_compose(_("Session: cannot create session tape dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
533 dir = dead_sound_dir ();
535 if (mkdir (dir.c_str(), 0755) < 0) {
536 if (errno != EEXIST) {
537 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
542 dir = automation_dir ();
544 if (mkdir (dir.c_str(), 0755) < 0) {
545 if (errno != EEXIST) {
546 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
552 /* check new_session so we don't overwrite an existing one */
556 std::string in_path = *mix_template;
558 ifstream in(in_path.c_str());
561 string out_path = _path;
563 out_path += _statefile_suffix;
565 ofstream out(out_path.c_str());
570 // okay, session is set up. Treat like normal saved
571 // session from now on.
577 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
583 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
590 warning << _("Session already exists. Not overwriting") << endmsg;
597 /* set initial start + end point */
599 start_location->set_end (0);
600 _locations.add (start_location);
602 end_location->set_end (initial_length);
603 _locations.add (end_location);
605 _state_of_the_state = Clean;
607 if (save_state (_current_snapshot_name)) {
608 save_history (_current_snapshot_name);
617 Session::load_diskstreams (const XMLNode& node)
620 XMLNodeConstIterator citer;
622 clist = node.children();
624 for (citer = clist.begin(); citer != clist.end(); ++citer) {
626 AudioDiskstream* dstream;
629 dstream = new AudioDiskstream (*this, **citer);
630 /* added automatically by AudioDiskstreamCreated handler */
633 catch (failed_constructor& err) {
634 error << _("Session: could not load diskstream via XML state") << endmsg;
643 Session::remove_pending_capture_state ()
648 xml_path += _current_snapshot_name;
649 xml_path += _pending_suffix;
651 unlink (xml_path.c_str());
655 Session::save_state (string snapshot_name, bool pending)
661 if (_state_of_the_state & CannotSave) {
665 tree.set_root (&get_state());
667 if (snapshot_name.empty()) {
668 snapshot_name = _current_snapshot_name;
674 xml_path += snapshot_name;
675 xml_path += _statefile_suffix;
679 // Make backup of state file
681 if ((access (xml_path.c_str(), F_OK) == 0) &&
682 (rename(xml_path.c_str(), bak_path.c_str()))) {
683 error << _("could not backup old state file, current state not saved.") << endmsg;
690 xml_path += snapshot_name;
691 xml_path += _pending_suffix;
695 if (!tree.write (xml_path)) {
696 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
698 /* don't leave a corrupt file lying around if it is
702 if (unlink (xml_path.c_str())) {
703 error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
706 if (rename (bak_path.c_str(), xml_path.c_str())) {
707 error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
717 bool was_dirty = dirty();
719 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
722 DirtyChanged (); /* EMIT SIGNAL */
725 StateSaved (snapshot_name); /* EMIT SIGNAL */
732 Session::restore_state (string snapshot_name)
734 if (load_state (snapshot_name) == 0) {
735 set_state (*state_tree->root());
742 Session::load_state (string snapshot_name)
751 state_was_pending = false;
753 /* check for leftover pending state from a crashed capture attempt */
756 xmlpath += snapshot_name;
757 xmlpath += _pending_suffix;
759 if (!access (xmlpath.c_str(), F_OK)) {
761 /* there is pending state from a crashed capture attempt */
763 if (AskAboutPendingState()) {
764 state_was_pending = true;
768 if (!state_was_pending) {
771 xmlpath += snapshot_name;
772 xmlpath += _statefile_suffix;
775 if (access (xmlpath.c_str(), F_OK)) {
776 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
780 state_tree = new XMLTree;
784 if (state_tree->read (xmlpath)) {
787 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
796 Session::load_options (const XMLNode& node)
800 bool have_fade_msecs = false;
801 bool have_fade_steepness = false;
802 float fade_msecs = 0;
803 float fade_steepness = 0;
804 SlaveSource slave_src = None;
806 LocaleGuard lg (X_("POSIX"));
808 if ((child = find_named_node (node, "input-auto-connect")) != 0) {
809 if ((prop = child->property ("val")) != 0) {
810 sscanf (prop->value().c_str(), "%x", &x);
811 input_auto_connect = AutoConnectOption (x);
815 if ((child = find_named_node (node, "output-auto-connect")) != 0) {
816 if ((prop = child->property ("val")) != 0) {
817 sscanf (prop->value().c_str(), "%x", &x);
818 output_auto_connect = AutoConnectOption (x);
822 if ((child = find_named_node (node, "slave")) != 0) {
823 if ((prop = child->property ("type")) != 0) {
824 if (prop->value() == "none") {
826 } else if (prop->value() == "mtc") {
828 } else if (prop->value() == "jack") {
831 set_slave_source (slave_src, 0);
835 /* we cannot set edit mode if we are loading a session,
836 because it might destroy the playlist's positioning
839 if ((child = find_named_node (node, "edit-mode")) != 0) {
840 if ((prop = child->property ("val")) != 0) {
841 if (prop->value() == "slide") {
842 pending_edit_mode = Slide;
843 } else if (prop->value() == "splice") {
844 pending_edit_mode = Splice;
849 if ((child = find_named_node (node, "send-midi-timecode")) != 0) {
850 if ((prop = child->property ("val")) != 0) {
851 bool x = (prop->value() == "yes");
852 send_mtc = !x; /* force change in value */
856 if ((child = find_named_node (node, "send-midi-machine-control")) != 0) {
857 if ((prop = child->property ("val")) != 0) {
858 bool x = (prop->value() == "yes");
859 send_mmc = !x; /* force change in value */
860 set_send_mmc (prop->value() == "yes");
863 if ((child = find_named_node (node, "max-level")) != 0) {
864 if ((prop = child->property ("val")) != 0) {
865 max_level = atoi (prop->value().c_str());
868 if ((child = find_named_node (node, "min-level")) != 0) {
869 if ((prop = child->property ("val")) != 0) {
870 min_level = atoi (prop->value().c_str());
873 if ((child = find_named_node (node, "meter-hold")) != 0) {
874 if ((prop = child->property ("val")) != 0) {
875 _meter_hold = atof (prop->value().c_str());
878 if ((child = find_named_node (node, "meter-falloff")) != 0) {
879 if ((prop = child->property ("val")) != 0) {
880 _meter_falloff = atof (prop->value().c_str());
883 if ((child = find_named_node (node, "long-over-length")) != 0) {
884 if ((prop = child->property ("val")) != 0) {
885 over_length_long = atoi (prop->value().c_str());
888 if ((child = find_named_node (node, "short-over-length")) != 0) {
889 if ((prop = child->property ("val")) != 0) {
890 over_length_short = atoi (prop->value().c_str());
893 if ((child = find_named_node (node, "shuttle-speed-factor")) != 0) {
894 if ((prop = child->property ("val")) != 0) {
895 shuttle_speed_factor = atof (prop->value().c_str());
898 if ((child = find_named_node (node, "shuttle-speed-threshold")) != 0) {
899 if ((prop = child->property ("val")) != 0) {
900 shuttle_speed_threshold = atof (prop->value().c_str());
903 if ((child = find_named_node (node, "rf-speed")) != 0) {
904 if ((prop = child->property ("val")) != 0) {
905 rf_speed = atof (prop->value().c_str());
908 if ((child = find_named_node (node, "smpte-frames-per-second")) != 0) {
909 if ((prop = child->property ("val")) != 0) {
910 set_smpte_type( atof (prop->value().c_str()), smpte_drop_frames );
913 if ((child = find_named_node (node, "smpte-drop-frames")) != 0) {
914 if ((prop = child->property ("val")) != 0) {
915 set_smpte_type( smpte_frames_per_second, (prop->value() == "yes") );
918 if ((child = find_named_node (node, "smpte-offset")) != 0) {
919 if ((prop = child->property ("val")) != 0) {
920 set_smpte_offset( atoi (prop->value().c_str()) );
923 if ((child = find_named_node (node, "smpte-offset-negative")) != 0) {
924 if ((prop = child->property ("val")) != 0) {
925 set_smpte_offset_negative( (prop->value() == "yes") );
928 if ((child = find_named_node (node, "click-sound")) != 0) {
929 if ((prop = child->property ("val")) != 0) {
930 click_sound = prop->value();
933 if ((child = find_named_node (node, "click-emphasis-sound")) != 0) {
934 if ((prop = child->property ("val")) != 0) {
935 click_emphasis_sound = prop->value();
939 if ((child = find_named_node (node, "solo-model")) != 0) {
940 if ((prop = child->property ("val")) != 0) {
941 if (prop->value() == "SoloBus")
942 _solo_model = SoloBus;
944 _solo_model = InverseMute;
948 /* BOOLEAN OPTIONS */
950 if ((child = find_named_node (node, "auto-play")) != 0) {
951 if ((prop = child->property ("val")) != 0) {
952 set_auto_play (prop->value() == "yes");
955 if ((child = find_named_node (node, "auto-input")) != 0) {
956 if ((prop = child->property ("val")) != 0) {
957 set_auto_input (prop->value() == "yes");
960 if ((child = find_named_node (node, "seamless-loop")) != 0) {
961 if ((prop = child->property ("val")) != 0) {
962 set_seamless_loop (prop->value() == "yes");
965 if ((child = find_named_node (node, "punch-in")) != 0) {
966 if ((prop = child->property ("val")) != 0) {
967 set_punch_in (prop->value() == "yes");
970 if ((child = find_named_node (node, "punch-out")) != 0) {
971 if ((prop = child->property ("val")) != 0) {
972 set_punch_out (prop->value() == "yes");
975 if ((child = find_named_node (node, "auto-return")) != 0) {
976 if ((prop = child->property ("val")) != 0) {
977 set_auto_return (prop->value() == "yes");
980 if ((child = find_named_node (node, "send-mtc")) != 0) {
981 if ((prop = child->property ("val")) != 0) {
982 set_send_mtc (prop->value() == "yes");
985 if ((child = find_named_node (node, "mmc-control")) != 0) {
986 if ((prop = child->property ("val")) != 0) {
987 set_mmc_control (prop->value() == "yes");
990 if ((child = find_named_node (node, "midi-control")) != 0) {
991 if ((prop = child->property ("val")) != 0) {
992 set_midi_control (prop->value() == "yes");
995 if ((child = find_named_node (node, "midi-feedback")) != 0) {
996 if ((prop = child->property ("val")) != 0) {
997 set_midi_feedback (prop->value() == "yes");
1000 // Legacy support for <recording-plugins>
1001 if ((child = find_named_node (node, "recording-plugins")) != 0) {
1002 if ((prop = child->property ("val")) != 0) {
1003 set_do_not_record_plugins (prop->value() == "no");
1006 if ((child = find_named_node (node, "do-not-record-plugins")) != 0) {
1007 if ((prop = child->property ("val")) != 0) {
1008 set_do_not_record_plugins (prop->value() == "yes");
1011 if ((child = find_named_node (node, "crossfades-active")) != 0) {
1012 if ((prop = child->property ("val")) != 0) {
1013 set_crossfades_active (prop->value() == "yes");
1016 if ((child = find_named_node (node, "audible-click")) != 0) {
1017 if ((prop = child->property ("val")) != 0) {
1018 set_clicking (prop->value() == "yes");
1022 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
1023 if ((prop = child->property ("val")) != 0) {
1024 _end_location_is_free = (prop->value() == "yes");
1028 if ((child = find_named_node (node, "layer-model")) != 0) {
1029 if ((prop = child->property ("val")) != 0) {
1030 if (prop->value() == X_("LaterHigher")) {
1031 set_layer_model (LaterHigher);
1032 } else if (prop->value() == X_("AddHigher")) {
1033 set_layer_model (AddHigher);
1035 set_layer_model (MoveAddHigher);
1040 if ((child = find_named_node (node, "xfade-model")) != 0) {
1041 if ((prop = child->property ("val")) != 0) {
1042 if (prop->value() == X_("Short")) {
1043 set_xfade_model (ShortCrossfade);
1045 set_xfade_model (FullCrossfade);
1050 if ((child = find_named_node (node, "short-xfade-length")) != 0) {
1051 if ((prop = child->property ("val")) != 0) {
1052 /* value is stored as a fractional seconds */
1053 float secs = atof (prop->value().c_str());
1054 Crossfade::set_short_xfade_length ((jack_nframes_t) floor (secs * frame_rate()));
1058 if ((child = find_named_node (node, "full-xfades-unmuted")) != 0) {
1059 if ((prop = child->property ("val")) != 0) {
1060 crossfades_active = (prop->value() == "yes");
1066 if ((child = find_named_node (node, "default-fade-steepness")) != 0) {
1067 if ((prop = child->property ("val")) != 0) {
1068 fade_steepness = atof (prop->value().c_str());
1069 have_fade_steepness = true;
1072 if ((child = find_named_node (node, "default-fade-msec")) != 0) {
1073 if ((prop = child->property ("val")) != 0) {
1074 fade_msecs = atof (prop->value().c_str());
1075 have_fade_msecs = true;
1079 if (have_fade_steepness || have_fade_msecs) {
1080 // set_default_fade (fade_steepness, fade_msecs);
1087 Session::get_options () const
1092 LocaleGuard lg (X_("POSIX"));
1094 opthead = new XMLNode ("Options");
1096 SlaveSource src = slave_source ();
1100 src_string = "none";
1106 src_string = "jack";
1109 child = opthead->add_child ("slave");
1110 child->add_property ("type", src_string);
1112 child = opthead->add_child ("send-midi-timecode");
1113 child->add_property ("val", send_midi_timecode?"yes":"no");
1115 child = opthead->add_child ("send-midi-machine-control");
1116 child->add_property ("val", send_midi_machine_control?"yes":"no");
1118 snprintf (buf, sizeof(buf)-1, "%x", (int) input_auto_connect);
1119 child = opthead->add_child ("input-auto-connect");
1120 child->add_property ("val", buf);
1122 snprintf (buf, sizeof(buf)-1, "%x", (int) output_auto_connect);
1123 child = opthead->add_child ("output-auto-connect");
1124 child->add_property ("val", buf);
1126 snprintf (buf, sizeof(buf)-1, "%d", max_level);
1127 child = opthead->add_child ("max-level");
1128 child->add_property ("val", buf);
1130 snprintf (buf, sizeof(buf)-1, "%d", min_level);
1131 child = opthead->add_child ("min-level");
1132 child->add_property ("val", buf);
1134 snprintf (buf, sizeof(buf)-1, "%f", _meter_hold);
1135 child = opthead->add_child ("meter-hold");
1136 child->add_property ("val", buf);
1138 snprintf (buf, sizeof(buf)-1, "%f", _meter_falloff);
1139 child = opthead->add_child ("meter-falloff");
1140 child->add_property ("val", buf);
1142 snprintf (buf, sizeof(buf)-1, "%u", over_length_long);
1143 child = opthead->add_child ("long-over-length");
1144 child->add_property ("val", buf);
1146 snprintf (buf, sizeof(buf)-1, "%u", over_length_short);
1147 child = opthead->add_child ("short-over-length");
1148 child->add_property ("val", buf);
1150 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_factor);
1151 child = opthead->add_child ("shuttle-speed-factor");
1152 child->add_property ("val", buf);
1154 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_threshold);
1155 child = opthead->add_child ("shuttle-speed-threshold");
1156 child->add_property ("val", buf);
1158 snprintf (buf, sizeof(buf)-1, "%f", rf_speed);
1159 child = opthead->add_child ("rf-speed");
1160 child->add_property ("val", buf);
1162 snprintf (buf, sizeof(buf)-1, "%.2f", smpte_frames_per_second);
1163 child = opthead->add_child ("smpte-frames-per-second");
1164 child->add_property ("val", buf);
1166 child = opthead->add_child ("smpte-drop-frames");
1167 child->add_property ("val", smpte_drop_frames ? "yes" : "no");
1169 snprintf (buf, sizeof(buf)-1, "%u", smpte_offset ());
1170 child = opthead->add_child ("smpte-offset");
1171 child->add_property ("val", buf);
1173 child = opthead->add_child ("smpte-offset-negative");
1174 child->add_property ("val", smpte_offset_negative () ? "yes" : "no");
1176 child = opthead->add_child ("edit-mode");
1177 switch (_edit_mode) {
1179 child->add_property ("val", "splice");
1183 child->add_property ("val", "slide");
1187 child = opthead->add_child ("auto-play");
1188 child->add_property ("val", get_auto_play () ? "yes" : "no");
1189 child = opthead->add_child ("auto-input");
1190 child->add_property ("val", get_auto_input () ? "yes" : "no");
1191 child = opthead->add_child ("seamless-loop");
1192 child->add_property ("val", get_seamless_loop () ? "yes" : "no");
1193 child = opthead->add_child ("punch-in");
1194 child->add_property ("val", get_punch_in () ? "yes" : "no");
1195 child = opthead->add_child ("punch-out");
1196 child->add_property ("val", get_punch_out () ? "yes" : "no");
1197 child = opthead->add_child ("all-safe");
1198 child->add_property ("val", get_all_safe () ? "yes" : "no");
1199 child = opthead->add_child ("auto-return");
1200 child->add_property ("val", get_auto_return () ? "yes" : "no");
1201 child = opthead->add_child ("mmc-control");
1202 child->add_property ("val", get_mmc_control () ? "yes" : "no");
1203 child = opthead->add_child ("midi-control");
1204 child->add_property ("val", get_midi_control () ? "yes" : "no");
1205 child = opthead->add_child ("midi-feedback");
1206 child->add_property ("val", get_midi_feedback () ? "yes" : "no");
1207 child = opthead->add_child ("do-not-record-plugins");
1208 child->add_property ("val", get_do_not_record_plugins () ? "yes" : "no");
1209 child = opthead->add_child ("auto-crossfade");
1210 child->add_property ("val", get_crossfades_active () ? "yes" : "no");
1211 child = opthead->add_child ("audible-click");
1212 child->add_property ("val", get_clicking () ? "yes" : "no");
1213 child = opthead->add_child ("end-marker-is-free");
1214 child->add_property ("val", _end_location_is_free ? "yes" : "no");
1216 if (click_sound.length()) {
1217 child = opthead->add_child ("click-sound");
1218 child->add_property ("val", click_sound);
1221 if (click_emphasis_sound.length()) {
1222 child = opthead->add_child ("click-emphasis-sound");
1223 child->add_property ("val", click_emphasis_sound);
1226 child = opthead->add_child ("solo-model");
1227 child->add_property ("val", _solo_model == SoloBus ? "SoloBus" : "InverseMute");
1229 child = opthead->add_child ("layer-model");
1230 switch (layer_model) {
1232 child->add_property ("val", X_("LaterHigher"));
1235 child->add_property ("val", X_("MoveAddHigher"));
1238 child->add_property ("val", X_("AddHigher"));
1242 child = opthead->add_child ("xfade-model");
1243 switch (xfade_model) {
1245 child->add_property ("val", X_("Full"));
1247 case ShortCrossfade:
1248 child->add_property ("val", X_("Short"));
1251 child = opthead->add_child ("short-xfade-length");
1252 /* store as fractions of a second */
1253 snprintf (buf, sizeof(buf)-1, "%f",
1254 (float) Crossfade::short_xfade_length() / frame_rate());
1255 child->add_property ("val", buf);
1257 child = opthead->add_child ("full-xfades-unmuted");
1258 child->add_property ("val", crossfades_active ? "yes" : "no");
1264 Session::get_state()
1270 Session::get_template()
1272 /* if we don't disable rec-enable, diskstreams
1273 will believe they need to store their capture
1274 sources in their state node.
1277 disable_record (false);
1279 return state(false);
1283 Session::state(bool full_state)
1285 XMLNode* node = new XMLNode("Session");
1288 // store libardour version, just in case
1290 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
1291 libardour_major_version, libardour_minor_version, libardour_micro_version);
1292 node->add_property("version", string(buf));
1294 /* store configuration settings */
1298 /* store the name */
1299 node->add_property ("name", _name);
1301 if (session_dirs.size() > 1) {
1305 vector<space_and_path>::iterator i = session_dirs.begin();
1306 vector<space_and_path>::iterator next;
1308 ++i; /* skip the first one */
1312 while (i != session_dirs.end()) {
1316 if (next != session_dirs.end()) {
1326 child = node->add_child ("Path");
1327 child->add_content (p);
1331 /* save the ID counter */
1333 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1334 node->add_property ("id-counter", buf);
1336 /* various options */
1338 node->add_child_nocopy (get_options());
1340 child = node->add_child ("Sources");
1343 Glib::Mutex::Lock sl (audio_source_lock);
1345 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
1347 /* Don't save information about AudioFileSources that are empty */
1349 AudioFileSource* fs;
1351 if ((fs = dynamic_cast<AudioFileSource*> (siter->second)) != 0) {
1352 DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
1354 /* destructive file sources are OK if they are empty, because
1355 we will re-use them every time.
1359 if (fs->length() == 0) {
1365 child->add_child_nocopy (siter->second->get_state());
1369 child = node->add_child ("Regions");
1372 Glib::Mutex::Lock rl (region_lock);
1374 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1376 /* only store regions not attached to playlists */
1378 if (i->second->playlist() == 0) {
1379 child->add_child_nocopy (i->second->state (true));
1384 child = node->add_child ("DiskStreams");
1387 Glib::RWLock::ReaderLock dl (diskstream_lock);
1388 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1389 if (!(*i)->hidden()) {
1390 child->add_child_nocopy ((*i)->get_state());
1395 node->add_child_nocopy (_locations.get_state());
1397 child = node->add_child ("Connections");
1399 Glib::Mutex::Lock lm (connection_lock);
1400 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1401 if (!(*i)->system_dependent()) {
1402 child->add_child_nocopy ((*i)->get_state());
1407 child = node->add_child ("Routes");
1409 boost::shared_ptr<RouteList> r = routes.reader ();
1411 RoutePublicOrderSorter cmp;
1412 RouteList public_order (*r);
1413 public_order.sort (cmp);
1415 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1416 if (!(*i)->hidden()) {
1418 child->add_child_nocopy ((*i)->get_state());
1420 child->add_child_nocopy ((*i)->get_template());
1427 child = node->add_child ("EditGroups");
1428 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1429 child->add_child_nocopy ((*i)->get_state());
1432 child = node->add_child ("MixGroups");
1433 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1434 child->add_child_nocopy ((*i)->get_state());
1437 child = node->add_child ("Playlists");
1438 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1439 if (!(*i)->hidden()) {
1440 if (!(*i)->empty()) {
1442 child->add_child_nocopy ((*i)->get_state());
1444 child->add_child_nocopy ((*i)->get_template());
1450 child = node->add_child ("UnusedPlaylists");
1451 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1452 if (!(*i)->hidden()) {
1453 if (!(*i)->empty()) {
1455 child->add_child_nocopy ((*i)->get_state());
1457 child->add_child_nocopy ((*i)->get_template());
1465 child = node->add_child ("Click");
1466 child->add_child_nocopy (_click_io->state (full_state));
1470 child = node->add_child ("NamedSelections");
1471 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1473 child->add_child_nocopy ((*i)->get_state());
1478 node->add_child_nocopy (_tempo_map->get_state());
1481 node->add_child_copy (*_extra_xml);
1488 Session::set_state (const XMLNode& node)
1492 const XMLProperty* prop;
1495 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1497 if (node.name() != X_("Session")){
1498 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1502 StateManager::prohibit_save ();
1504 if ((prop = node.property ("name")) != 0) {
1505 _name = prop->value ();
1508 if ((prop = node.property (X_("id-counter"))) != 0) {
1510 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1511 ID::init_counter (x);
1513 /* old sessions used a timebased counter, so fake
1514 the startup ID counter based on a standard
1519 ID::init_counter (now);
1523 IO::disable_ports ();
1524 IO::disable_connecting ();
1526 /* Object loading order:
1543 if (use_config_midi_ports ()) {
1546 if ((child = find_named_node (node, "Path")) != 0) {
1547 /* XXX this XML content stuff horrible API design */
1548 string raid_path = _path + ':' + child->children().front()->content();
1549 setup_raid_path (raid_path);
1551 /* the path is already set */
1554 if ((child = find_named_node (node, "extra")) != 0) {
1555 _extra_xml = new XMLNode (*child);
1558 if ((child = find_named_node (node, "Options")) == 0) {
1559 error << _("Session: XML state has no options section") << endmsg;
1560 } else if (load_options (*child)) {
1563 if ((child = find_named_node (node, "Sources")) == 0) {
1564 error << _("Session: XML state has no sources section") << endmsg;
1566 } else if (load_sources (*child)) {
1570 if ((child = find_named_node (node, "Regions")) == 0) {
1571 error << _("Session: XML state has no Regions section") << endmsg;
1573 } else if (load_regions (*child)) {
1577 if ((child = find_named_node (node, "Playlists")) == 0) {
1578 error << _("Session: XML state has no playlists section") << endmsg;
1580 } else if (load_playlists (*child)) {
1584 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1586 } else if (load_unused_playlists (*child)) {
1590 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1591 if (load_named_selections (*child)) {
1596 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1597 error << _("Session: XML state has no diskstreams section") << endmsg;
1599 } else if (load_diskstreams (*child)) {
1603 if ((child = find_named_node (node, "Connections")) == 0) {
1604 error << _("Session: XML state has no connections section") << endmsg;
1606 } else if (load_connections (*child)) {
1610 if ((child = find_named_node (node, "Locations")) == 0) {
1611 error << _("Session: XML state has no locations section") << endmsg;
1613 } else if (_locations.set_state (*child)) {
1619 if ((location = _locations.auto_loop_location()) != 0) {
1620 set_auto_loop_location (location);
1623 if ((location = _locations.auto_punch_location()) != 0) {
1624 set_auto_punch_location (location);
1627 if ((location = _locations.end_location()) == 0) {
1628 _locations.add (end_location);
1630 delete end_location;
1631 end_location = location;
1634 if ((location = _locations.start_location()) == 0) {
1635 _locations.add (start_location);
1637 delete start_location;
1638 start_location = location;
1641 _locations.save_state (_("initial state"));
1643 if ((child = find_named_node (node, "EditGroups")) == 0) {
1644 error << _("Session: XML state has no edit groups section") << endmsg;
1646 } else if (load_edit_groups (*child)) {
1650 if ((child = find_named_node (node, "MixGroups")) == 0) {
1651 error << _("Session: XML state has no mix groups section") << endmsg;
1653 } else if (load_mix_groups (*child)) {
1657 if ((child = find_named_node (node, "TempoMap")) == 0) {
1658 error << _("Session: XML state has no Tempo Map section") << endmsg;
1660 } else if (_tempo_map->set_state (*child)) {
1664 if ((child = find_named_node (node, "Routes")) == 0) {
1665 error << _("Session: XML state has no routes section") << endmsg;
1667 } else if (load_routes (*child)) {
1671 if ((child = find_named_node (node, "Click")) == 0) {
1672 warning << _("Session: XML state has no click section") << endmsg;
1673 } else if (_click_io) {
1674 _click_io->set_state (*child);
1677 /* OK, now we can set edit mode */
1679 set_edit_mode (pending_edit_mode);
1681 /* here beginneth the second phase ... */
1683 StateReady (); /* EMIT SIGNAL */
1685 _state_of_the_state = Clean;
1687 StateManager::allow_save (_("initial state"), true);
1689 if (state_was_pending) {
1690 save_state (_current_snapshot_name);
1691 save_history (_current_snapshot_name);
1692 remove_pending_capture_state ();
1693 state_was_pending = false;
1699 /* we failed, re-enable state saving but don't actually save internal state */
1700 StateManager::allow_save (X_("ignored"), false);
1705 Session::load_routes (const XMLNode& node)
1708 XMLNodeConstIterator niter;
1710 nlist = node.children();
1714 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1716 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1719 error << _("Session: cannot create Route from XML description.") << endmsg;
1729 boost::shared_ptr<Route>
1730 Session::XMLRouteFactory (const XMLNode& node)
1732 if (node.name() != "Route") {
1733 return boost::shared_ptr<Route> ((Route*) 0);
1736 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1737 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1740 boost::shared_ptr<Route> x (new Route (*this, node));
1746 Session::load_regions (const XMLNode& node)
1749 XMLNodeConstIterator niter;
1750 AudioRegion* region;
1752 nlist = node.children();
1756 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1757 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1758 error << _("Session: cannot create Region from XML description.") << endmsg;
1765 Session::XMLRegionFactory (const XMLNode& node, bool full)
1767 const XMLProperty* prop;
1770 AudioRegion::SourceList sources;
1771 uint32_t nchans = 1;
1774 if (node.name() != X_("Region")) {
1778 if ((prop = node.property (X_("channels"))) != 0) {
1779 nchans = atoi (prop->value().c_str());
1783 if ((prop = node.property (X_("source-0"))) == 0) {
1784 if ((prop = node.property ("source")) == 0) {
1785 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1790 PBD::ID s_id (prop->value());
1792 if ((source = source_by_id (s_id)) == 0) {
1793 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1797 as = dynamic_cast<AudioSource*>(source);
1799 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1803 sources.push_back (as);
1805 /* pickup other channels */
1807 for (uint32_t n=1; n < nchans; ++n) {
1808 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1809 if ((prop = node.property (buf)) != 0) {
1811 PBD::ID id2 (prop->value());
1813 if ((source = source_by_id (id2)) == 0) {
1814 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1818 as = dynamic_cast<AudioSource*>(source);
1820 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1823 sources.push_back (as);
1828 return new AudioRegion (sources, node);
1831 catch (failed_constructor& err) {
1837 Session::get_sources_as_xml ()
1840 XMLNode* node = new XMLNode (X_("Sources"));
1841 Glib::Mutex::Lock lm (audio_source_lock);
1843 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1844 node->add_child_nocopy (i->second->get_state());
1847 /* XXX get MIDI and other sources here */
1853 Session::path_from_region_name (string name, string identifier)
1855 char buf[PATH_MAX+1];
1857 string dir = discover_best_sound_dir ();
1859 for (n = 0; n < 999999; ++n) {
1860 if (identifier.length()) {
1861 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1862 identifier.c_str(), n);
1864 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1866 if (access (buf, F_OK) != 0) {
1876 Session::load_sources (const XMLNode& node)
1879 XMLNodeConstIterator niter;
1882 nlist = node.children();
1886 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1888 if ((source = XMLSourceFactory (**niter)) == 0) {
1889 error << _("Session: cannot create Source from XML description.") << endmsg;
1897 Session::XMLSourceFactory (const XMLNode& node)
1901 if (node.name() != "Source") {
1906 src = AudioFileSource::create (node);
1909 catch (failed_constructor& err) {
1910 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1918 Session::save_template (string template_name)
1921 string xml_path, bak_path, template_path;
1923 if (_state_of_the_state & CannotSave) {
1928 string dir = template_dir();
1930 if ((dp = opendir (dir.c_str()))) {
1933 if (mkdir (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)<0) {
1934 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1939 tree.set_root (&get_template());
1942 xml_path += template_name;
1943 xml_path += _template_suffix;
1945 ifstream in(xml_path.c_str());
1948 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1954 if (!tree.write (xml_path)) {
1955 error << _("mix template not saved") << endmsg;
1963 Session::rename_template (string old_name, string new_name)
1965 string old_path = template_dir() + old_name + _template_suffix;
1966 string new_path = template_dir() + new_name + _template_suffix;
1968 return rename (old_path.c_str(), new_path.c_str());
1972 Session::delete_template (string name)
1974 string template_path = template_dir();
1975 template_path += name;
1976 template_path += _template_suffix;
1978 return remove (template_path.c_str());
1982 Session::refresh_disk_space ()
1985 struct statfs statfsbuf;
1986 vector<space_and_path>::iterator i;
1987 Glib::Mutex::Lock lm (space_lock);
1990 /* get freespace on every FS that is part of the session path */
1992 _total_free_4k_blocks = 0;
1994 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1995 statfs ((*i).path.c_str(), &statfsbuf);
1997 scale = statfsbuf.f_bsize/4096.0;
1999 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2000 _total_free_4k_blocks += (*i).blocks;
2006 Session::ensure_sound_dir (string path, string& result)
2011 /* Ensure that the parent directory exists */
2013 if (mkdir (path.c_str(), 0775)) {
2014 if (errno != EEXIST) {
2015 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
2020 /* Ensure that the sounds directory exists */
2024 result += sound_dir_name;
2026 if (mkdir (result.c_str(), 0775)) {
2027 if (errno != EEXIST) {
2028 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
2035 dead += dead_sound_dir_name;
2037 if (mkdir (dead.c_str(), 0775)) {
2038 if (errno != EEXIST) {
2039 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
2046 peak += peak_dir_name;
2048 if (mkdir (peak.c_str(), 0775)) {
2049 if (errno != EEXIST) {
2050 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
2055 /* callers expect this to be terminated ... */
2062 Session::discover_best_sound_dir (bool destructive)
2064 vector<space_and_path>::iterator i;
2067 /* destructive files all go into the same place */
2073 /* handle common case without system calls */
2075 if (session_dirs.size() == 1) {
2079 /* OK, here's the algorithm we're following here:
2081 We want to select which directory to use for
2082 the next file source to be created. Ideally,
2083 we'd like to use a round-robin process so as to
2084 get maximum performance benefits from splitting
2085 the files across multiple disks.
2087 However, in situations without much diskspace, an
2088 RR approach may end up filling up a filesystem
2089 with new files while others still have space.
2090 Its therefore important to pay some attention to
2091 the freespace in the filesystem holding each
2092 directory as well. However, if we did that by
2093 itself, we'd keep creating new files in the file
2094 system with the most space until it was as full
2095 as all others, thus negating any performance
2096 benefits of this RAID-1 like approach.
2098 So, we use a user-configurable space threshold. If
2099 there are at least 2 filesystems with more than this
2100 much space available, we use RR selection between them.
2101 If not, then we pick the filesystem with the most space.
2103 This gets a good balance between the two
2107 refresh_disk_space ();
2109 int free_enough = 0;
2111 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2112 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2117 if (free_enough >= 2) {
2119 bool found_it = false;
2121 /* use RR selection process, ensuring that the one
2125 i = last_rr_session_dir;
2128 if (++i == session_dirs.end()) {
2129 i = session_dirs.begin();
2132 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2133 if (ensure_sound_dir ((*i).path, result) == 0) {
2134 last_rr_session_dir = i;
2140 } while (i != last_rr_session_dir);
2143 result = sound_dir();
2148 /* pick FS with the most freespace (and that
2149 seems to actually work ...)
2152 vector<space_and_path> sorted;
2153 space_and_path_ascending_cmp cmp;
2155 sorted = session_dirs;
2156 sort (sorted.begin(), sorted.end(), cmp);
2158 for (i = sorted.begin(); i != sorted.end(); ++i) {
2159 if (ensure_sound_dir ((*i).path, result) == 0) {
2160 last_rr_session_dir = i;
2165 /* if the above fails, fall back to the most simplistic solution */
2167 if (i == sorted.end()) {
2176 Session::load_playlists (const XMLNode& node)
2179 XMLNodeConstIterator niter;
2182 nlist = node.children();
2186 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2188 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2189 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2197 Session::load_unused_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;
2214 // now manually untrack it
2216 track_playlist (playlist, false);
2224 Session::XMLPlaylistFactory (const XMLNode& node)
2227 return new AudioPlaylist (*this, node);
2230 catch (failed_constructor& err) {
2236 Session::load_named_selections (const XMLNode& node)
2239 XMLNodeConstIterator niter;
2242 nlist = node.children();
2246 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2248 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2249 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2257 Session::XMLNamedSelectionFactory (const XMLNode& node)
2260 return new NamedSelection (*this, node);
2263 catch (failed_constructor& err) {
2269 Session::dead_sound_dir () const
2272 res += dead_sound_dir_name;
2278 Session::sound_dir () const
2281 res += sound_dir_name;
2287 Session::tape_dir () const
2290 res += tape_dir_name;
2296 Session::peak_dir () const
2299 res += peak_dir_name;
2305 Session::automation_dir () const
2308 res += "automation/";
2313 Session::template_dir ()
2315 string path = get_user_ardour_path();
2316 path += "templates/";
2322 Session::suffixed_search_path (string suffix, bool data)
2326 path += get_user_ardour_path();
2327 if (path[path.length()-1] != ':') {
2332 path += get_system_data_path();
2334 path += get_system_module_path();
2337 vector<string> split_path;
2339 split (path, split_path, ':');
2342 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2347 if (distance (i, split_path.end()) != 1) {
2356 Session::template_path ()
2358 return suffixed_search_path (X_("templates"), true);
2362 Session::control_protocol_path ()
2364 return suffixed_search_path (X_("surfaces"), false);
2368 Session::load_connections (const XMLNode& node)
2370 XMLNodeList nlist = node.children();
2371 XMLNodeConstIterator niter;
2375 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2376 if ((*niter)->name() == "InputConnection") {
2377 add_connection (new ARDOUR::InputConnection (**niter));
2378 } else if ((*niter)->name() == "OutputConnection") {
2379 add_connection (new ARDOUR::OutputConnection (**niter));
2381 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2390 Session::load_edit_groups (const XMLNode& node)
2392 return load_route_groups (node, true);
2396 Session::load_mix_groups (const XMLNode& node)
2398 return load_route_groups (node, false);
2402 Session::load_route_groups (const XMLNode& node, bool edit)
2404 XMLNodeList nlist = node.children();
2405 XMLNodeConstIterator niter;
2410 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2411 if ((*niter)->name() == "RouteGroup") {
2413 rg = add_edit_group ("");
2414 rg->set_state (**niter);
2416 rg = add_mix_group ("");
2417 rg->set_state (**niter);
2426 state_file_filter (const string &str, void *arg)
2428 return (str.length() > strlen(Session::statefile_suffix()) &&
2429 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2433 bool operator()(const string* a, const string* b) {
2439 remove_end(string* state)
2441 string statename(*state);
2443 string::size_type start,end;
2444 if ((start = statename.find_last_of ('/')) != string::npos) {
2445 statename = statename.substr (start+1);
2448 if ((end = statename.rfind(".ardour")) == string::npos) {
2449 end = statename.length();
2452 return new string(statename.substr (0, end));
2456 Session::possible_states (string path)
2458 PathScanner scanner;
2459 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2461 transform(states->begin(), states->end(), states->begin(), remove_end);
2464 sort (states->begin(), states->end(), cmp);
2470 Session::possible_states () const
2472 return possible_states(_path);
2476 Session::auto_save()
2478 save_state (_current_snapshot_name);
2479 save_history (_current_snapshot_name);
2483 Session::add_edit_group (string name)
2485 RouteGroup* rg = new RouteGroup (*this, name);
2486 edit_groups.push_back (rg);
2487 edit_group_added (rg); /* EMIT SIGNAL */
2493 Session::add_mix_group (string name)
2495 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2496 mix_groups.push_back (rg);
2497 mix_group_added (rg); /* EMIT SIGNAL */
2503 Session::remove_edit_group (RouteGroup& rg)
2505 list<RouteGroup*>::iterator i;
2507 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2508 (*i)->apply (&Route::drop_edit_group, this);
2509 edit_groups.erase (i);
2510 edit_group_removed (); /* EMIT SIGNAL */
2517 Session::remove_mix_group (RouteGroup& rg)
2519 list<RouteGroup*>::iterator i;
2521 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2522 (*i)->apply (&Route::drop_mix_group, this);
2523 mix_groups.erase (i);
2524 mix_group_removed (); /* EMIT SIGNAL */
2531 Session::mix_group_by_name (string name)
2533 list<RouteGroup *>::iterator i;
2535 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2536 if ((*i)->name() == name) {
2544 Session::edit_group_by_name (string name)
2546 list<RouteGroup *>::iterator i;
2548 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2549 if ((*i)->name() == name) {
2557 Session::set_meter_hold (float val)
2560 MeterHoldChanged(); // emit
2564 Session::set_meter_falloff (float val)
2566 _meter_falloff = val;
2567 MeterFalloffChanged(); // emit
2572 Session::begin_reversible_command (string name)
2574 current_trans.clear ();
2575 current_trans.set_name (name);
2579 Session::commit_reversible_command (Command *cmd)
2584 current_trans.add_command (cmd);
2587 gettimeofday (&now, 0);
2588 current_trans.set_timestamp (now);
2590 history.add (current_trans);
2593 Session::GlobalRouteBooleanState
2594 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2596 GlobalRouteBooleanState s;
2597 boost::shared_ptr<RouteList> r = routes.reader ();
2599 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2600 if (!(*i)->hidden()) {
2601 RouteBooleanState v;
2604 Route* r = (*i).get();
2605 v.second = (r->*method)();
2614 Session::GlobalRouteMeterState
2615 Session::get_global_route_metering ()
2617 GlobalRouteMeterState s;
2618 boost::shared_ptr<RouteList> r = routes.reader ();
2620 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2621 if (!(*i)->hidden()) {
2625 v.second = (*i)->meter_point();
2635 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2637 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2638 i->first->set_meter_point (i->second, arg);
2643 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2645 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2646 Route* r = i->first.get();
2647 (r->*method) (i->second, arg);
2652 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2654 set_global_route_boolean (s, &Route::set_mute, src);
2658 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2660 set_global_route_boolean (s, &Route::set_solo, src);
2664 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2666 set_global_route_boolean (s, &Route::set_record_enable, src);
2671 Session::global_mute_memento (void* src)
2673 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2677 Session::global_metering_memento (void* src)
2679 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2683 Session::global_solo_memento (void* src)
2685 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2689 Session::global_record_enable_memento (void* src)
2691 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2696 template_filter (const string &str, void *arg)
2698 return (str.length() > strlen(Session::template_suffix()) &&
2699 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2703 Session::get_template_list (list<string> &template_names)
2705 vector<string *> *templates;
2706 PathScanner scanner;
2709 path = template_path ();
2711 templates = scanner (path, template_filter, 0, false, true);
2713 vector<string*>::iterator i;
2714 for (i = templates->begin(); i != templates->end(); ++i) {
2715 string fullpath = *(*i);
2718 start = fullpath.find_last_of ('/') + 1;
2719 if ((end = fullpath.find_last_of ('.')) <0) {
2720 end = fullpath.length();
2723 template_names.push_back(fullpath.substr(start, (end-start)));
2728 Session::read_favorite_dirs (FavoriteDirs & favs)
2730 string path = get_user_ardour_path();
2731 path += "/favorite_dirs";
2733 ifstream fav (path.c_str());
2738 if (errno != ENOENT) {
2739 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2750 getline(fav, newfav);
2756 favs.push_back (newfav);
2763 Session::write_favorite_dirs (FavoriteDirs & favs)
2765 string path = get_user_ardour_path();
2766 path += "/favorite_dirs";
2768 ofstream fav (path.c_str());
2774 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2775 fav << (*i) << endl;
2782 accept_all_non_peak_files (const string& path, void *arg)
2784 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2788 accept_all_state_files (const string& path, void *arg)
2790 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2794 Session::find_all_sources (string path, set<string>& result)
2799 if (!tree.read (path)) {
2803 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2808 XMLNodeConstIterator niter;
2810 nlist = node->children();
2814 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2818 if ((prop = (*niter)->property (X_("name"))) == 0) {
2822 if (prop->value()[0] == '/') {
2823 /* external file, ignore */
2827 string path = _path; /* /-terminated */
2828 path += sound_dir_name;
2830 path += prop->value();
2832 result.insert (path);
2839 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2841 PathScanner scanner;
2842 vector<string*>* state_files;
2844 string this_snapshot_path;
2850 if (ripped[ripped.length()-1] == '/') {
2851 ripped = ripped.substr (0, ripped.length() - 1);
2854 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2856 if (state_files == 0) {
2861 this_snapshot_path = _path;
2862 this_snapshot_path += _current_snapshot_name;
2863 this_snapshot_path += _statefile_suffix;
2865 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2867 if (exclude_this_snapshot && **i == this_snapshot_path) {
2871 if (find_all_sources (**i, result) < 0) {
2880 Session::cleanup_sources (Session::cleanup_report& rep)
2882 vector<Source*> dead_sources;
2883 vector<Playlist*> playlists_tbd;
2884 PathScanner scanner;
2886 vector<space_and_path>::iterator i;
2887 vector<space_and_path>::iterator nexti;
2888 vector<string*>* soundfiles;
2889 vector<string> unused;
2890 set<string> all_sources;
2895 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2897 /* step 1: consider deleting all unused playlists */
2899 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2902 status = AskAboutPlaylistDeletion (*x);
2911 playlists_tbd.push_back (*x);
2915 /* leave it alone */
2920 /* now delete any that were marked for deletion */
2922 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2923 PlaylistList::iterator foo;
2925 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2926 unused_playlists.erase (foo);
2931 /* step 2: clear the undo/redo history for all playlists */
2933 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2934 (*x)->drop_all_states ();
2937 /* step 3: find all un-referenced sources */
2942 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2944 AudioSourceList::iterator tmp;
2949 /* only remove files that are not in use and have some size
2950 to them. otherwise we remove the current "nascent"
2954 if (i->second->use_cnt() == 0 && i->second->length() > 0) {
2955 dead_sources.push_back (i->second);
2957 /* remove this source from our own list to avoid us
2958 adding it to the list of all sources below
2961 audio_sources.erase (i);
2967 /* Step 4: get rid of all regions in the region list that use any dead sources
2968 in case the sources themselves don't go away (they might be referenced in
2972 for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2974 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2975 AudioRegionList::iterator tmp;
2983 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2984 if (&ar->source (n) == (*i)) {
2985 /* this region is dead */
2994 /* build a list of all the possible sound directories for the session */
2996 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
3001 sound_path += (*i).path;
3002 sound_path += sound_dir_name;
3004 if (nexti != session_dirs.end()) {
3011 /* now do the same thing for the files that ended up in the sounds dir(s)
3012 but are not referenced as sources in any snapshot.
3015 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
3017 if (soundfiles == 0) {
3021 /* find all sources, but don't use this snapshot because the
3022 state file on disk still references sources we may have already
3026 find_all_sources_across_snapshots (all_sources, true);
3028 /* add our current source list
3031 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
3032 AudioFileSource* fs;
3034 if ((fs = dynamic_cast<AudioFileSource*> (i->second)) != 0) {
3035 all_sources.insert (fs->path());
3039 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
3044 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
3054 unused.push_back (spath);
3058 /* now try to move all unused files into the "dead_sounds" directory(ies) */
3060 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
3061 struct stat statbuf;
3063 rep.paths.push_back (*x);
3064 if (stat ((*x).c_str(), &statbuf) == 0) {
3065 rep.space += statbuf.st_size;
3070 /* don't move the file across filesystems, just
3071 stick it in the `dead_sound_dir_name' directory
3072 on whichever filesystem it was already on.
3075 newpath = Glib::path_get_dirname (*x);
3076 newpath = Glib::path_get_dirname (newpath);
3079 newpath += dead_sound_dir_name;
3081 newpath += Glib::path_get_basename ((*x));
3083 if (access (newpath.c_str(), F_OK) == 0) {
3085 /* the new path already exists, try versioning */
3087 char buf[PATH_MAX+1];
3091 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
3094 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
3095 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
3099 if (version == 999) {
3100 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
3104 newpath = newpath_v;
3109 /* it doesn't exist, or we can't read it or something */
3113 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
3114 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
3115 (*x), newpath, strerror (errno))
3121 /* see if there an easy to find peakfile for this file, and remove it.
3124 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
3125 peakpath += ".peak";
3127 if (access (peakpath.c_str(), W_OK) == 0) {
3128 if (::unlink (peakpath.c_str()) != 0) {
3129 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3130 peakpath, _path, strerror (errno))
3132 /* try to back out */
3133 rename (newpath.c_str(), _path.c_str());
3142 /* dump the history list */
3146 /* save state so we don't end up a session file
3147 referring to non-existent sources.
3154 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3159 Session::cleanup_trash_sources (Session::cleanup_report& rep)
3161 vector<space_and_path>::iterator i;
3162 string dead_sound_dir;
3163 struct dirent* dentry;
3164 struct stat statbuf;
3170 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3172 dead_sound_dir = (*i).path;
3173 dead_sound_dir += dead_sound_dir_name;
3175 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
3179 while ((dentry = readdir (dead)) != 0) {
3181 /* avoid '.' and '..' */
3183 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
3184 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3190 fullpath = dead_sound_dir;
3192 fullpath += dentry->d_name;
3194 if (stat (fullpath.c_str(), &statbuf)) {
3198 if (!S_ISREG (statbuf.st_mode)) {
3202 if (unlink (fullpath.c_str())) {
3203 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3204 fullpath, strerror (errno))
3208 rep.paths.push_back (dentry->d_name);
3209 rep.space += statbuf.st_size;
3220 Session::set_dirty ()
3222 bool was_dirty = dirty();
3224 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3227 DirtyChanged(); /* EMIT SIGNAL */
3233 Session::set_clean ()
3235 bool was_dirty = dirty();
3237 _state_of_the_state = Clean;
3240 DirtyChanged(); /* EMIT SIGNAL */
3245 Session::add_controllable (Controllable* c)
3247 Glib::Mutex::Lock lm (controllables_lock);
3248 controllables.push_back (c);
3252 Session::remove_controllable (Controllable* c)
3254 if (_state_of_the_state | Deletion) {
3258 Glib::Mutex::Lock lm (controllables_lock);
3259 controllables.remove (c);
3263 Session::controllable_by_id (const PBD::ID& id)
3265 Glib::Mutex::Lock lm (controllables_lock);
3267 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3268 if ((*i)->id() == id) {
3277 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3279 Stateful::add_instant_xml (node, dir);
3280 Config->add_instant_xml (node, get_user_ardour_path());
3285 Session::save_history (string snapshot_name)
3291 tree.set_root (&history.get_state());
3293 if (snapshot_name.empty()) {
3294 snapshot_name = _current_snapshot_name;
3297 xml_path = _path + snapshot_name + ".history";
3299 bak_path = xml_path + ".bak";
3301 if ((access (xml_path.c_str(), F_OK) == 0) &&
3302 (rename (xml_path.c_str(), bak_path.c_str())))
3304 error << _("could not backup old history file, current history not saved.") << endmsg;
3308 if (!tree.write (xml_path))
3310 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3312 /* don't leave a corrupt file lying around if it is
3316 if (unlink (xml_path.c_str()))
3318 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
3320 if (rename (bak_path.c_str(), xml_path.c_str()))
3322 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;