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>
47 #include <midi++/mmc.h>
48 #include <midi++/port.h>
49 #include <pbd/error.h>
50 #include <pbd/dirname.h>
51 #include <pbd/lockmonitor.h>
52 #include <pbd/pathscanner.h>
53 #include <pbd/pthread_utils.h>
54 #include <pbd/basename.h>
55 #include <pbd/strsplit.h>
57 #include <ardour/audioengine.h>
58 #include <ardour/configuration.h>
59 #include <ardour/session.h>
60 #include <ardour/diskstream.h>
61 #include <ardour/utils.h>
62 #include <ardour/audioplaylist.h>
63 #include <ardour/source.h>
64 #include <ardour/filesource.h>
65 #include <ardour/destructive_filesource.h>
66 #include <ardour/sndfilesource.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/cycle_timer.h>
78 #include <ardour/utils.h>
79 #include <ardour/named_selection.h>
80 #include <ardour/version.h>
81 #include <ardour/location.h>
82 #include <ardour/audioregion.h>
83 #include <ardour/crossfade.h>
89 using namespace ARDOUR;
92 Session::first_stage_init (string fullpath, string snapshot_name)
94 if (fullpath.length() == 0) {
95 throw failed_constructor();
99 if (!realpath(fullpath.c_str(), buf) && (errno != ENOENT)) {
100 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
101 throw failed_constructor();
105 if (_path[_path.length()-1] != '/') {
109 /* these two are just provisional settings. set_state()
110 will likely override them.
113 _name = _current_snapshot_name = snapshot_name;
114 setup_raid_path (_path);
116 _current_frame_rate = _engine.frame_rate ();
117 _tempo_map = new TempoMap (_current_frame_rate);
118 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
120 atomic_set (&processing_prohibited, 0);
123 _transport_speed = 0;
124 _last_transport_speed = 0;
125 transport_sub_state = 0;
126 _transport_frame = 0;
128 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
129 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
130 _end_location_is_free = true;
131 atomic_set (&_record_status, Disabled);
136 seamless_loop = false;
137 loop_changing = false;
139 crossfades_active = false;
142 _last_roll_location = 0;
143 _last_record_location = 0;
144 pending_locate_frame = 0;
145 pending_locate_roll = false;
146 pending_locate_flush = false;
147 dstream_buffer_size = 0;
149 state_was_pending = false;
151 outbound_mtc_smpte_frame = 0;
152 next_quarter_frame_to_send = -1;
153 current_block_size = 0;
154 _solo_latched = true;
155 _solo_model = InverseMute;
156 solo_update_disabled = false;
157 currently_soloing = false;
158 _have_captured = false;
159 _worst_output_latency = 0;
160 _worst_input_latency = 0;
161 _worst_track_latency = 0;
162 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
165 butler_mixdown_buffer = 0;
166 butler_gain_buffer = 0;
169 midi_feedback = false;
172 post_transport_work = PostTransportWork (0);
173 atomic_set (&butler_should_do_transport_work, 0);
174 atomic_set (&butler_active, 0);
175 atomic_set (&_playback_load, 100);
176 atomic_set (&_capture_load, 100);
177 atomic_set (&_playback_load_min, 100);
178 atomic_set (&_capture_load_min, 100);
179 pending_audition_region = 0;
181 pending_edit_mode = _edit_mode;
185 input_auto_connect = AutoConnectOption (0);
186 output_auto_connect = AutoConnectOption (0);
187 waiting_to_start = false;
189 _gain_automation_buffer = 0;
190 _pan_automation_buffer = 0;
192 pending_abort = false;
193 layer_model = MoveAddHigher;
194 xfade_model = ShortCrossfade;
195 destructive_index = 0;
197 /* allocate conversion buffers */
198 _conversion_buffers[ButlerContext] = new char[DiskStream::disk_io_frames() * 4];
199 _conversion_buffers[TransportContext] = new char[DiskStream::disk_io_frames() * 4];
201 /* default short fade = 15ms */
203 Crossfade::set_short_xfade_length ((jack_nframes_t) floor ((15.0 * frame_rate()) / 1000.0));
205 last_mmc_step.tv_sec = 0;
206 last_mmc_step.tv_usec = 0;
209 preroll.type = AnyTime::Frames;
211 postroll.type = AnyTime::Frames;
214 /* click sounds are unset by default, which causes us to internal
215 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 Source::SourceCreated.connect (mem_fun (*this, &Session::add_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 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
277 /* stop IO objects from doing stuff until we're ready for them */
279 IO::disable_panners ();
280 IO::disable_ports ();
281 IO::disable_connecting ();
285 Session::second_stage_init (bool new_session)
287 ExternalSource::set_peak_dir (peak_dir());
290 if (load_state (_current_snapshot_name)) {
293 remove_empty_sounds ();
296 if (start_butler_thread()) {
300 if (start_midi_thread ()) {
304 if (init_feedback ()) {
309 if (set_state (*state_tree->root())) {
314 /* we can't save till after ::when_engine_running() is called,
315 because otherwise we save state with no connections made.
316 therefore, we reset _state_of_the_state because ::set_state()
317 will have cleared it.
319 we also have to include Loading so that any events that get
320 generated between here and the end of ::when_engine_running()
321 will be processed directly rather than queued.
324 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
326 // set_auto_input (true);
327 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
328 _locations.added.connect (mem_fun (this, &Session::locations_added));
329 setup_click_sounds (0);
330 setup_midi_control ();
332 /* Pay attention ... */
334 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
335 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
337 if (_engine.running()) {
338 when_engine_running();
340 first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
343 send_full_time_code ();
344 _engine.transport_locate (0);
345 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
346 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
347 send_all_midi_feedback();
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 FileSource::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 FileSource search path */
488 FileSource::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) {
633 dstream = new DiskStream (*this, **citer);
634 /* added automatically by DiskStreamCreated handler */
637 catch (failed_constructor& err) {
638 error << _("Session: could not load diskstream via XML state") << endmsg;
647 Session::remove_pending_capture_state ()
652 xml_path += _current_snapshot_name;
653 xml_path += _pending_suffix;
655 unlink (xml_path.c_str());
659 Session::save_state (string snapshot_name, bool pending)
665 if (_state_of_the_state & CannotSave) {
669 tree.set_root (&get_state());
671 if (snapshot_name.empty()) {
672 snapshot_name = _current_snapshot_name;
678 xml_path += snapshot_name;
679 xml_path += _statefile_suffix;
683 // Make backup of state file
685 if ((access (xml_path.c_str(), F_OK) == 0) &&
686 (rename(xml_path.c_str(), bak_path.c_str()))) {
687 error << _("could not backup old state file, current state not saved.") << endmsg;
694 xml_path += snapshot_name;
695 xml_path += _pending_suffix;
699 if (!tree.write (xml_path)) {
700 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
702 /* don't leave a corrupt file lying around if it is
706 if (unlink (xml_path.c_str())) {
707 error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
710 if (rename (bak_path.c_str(), xml_path.c_str())) {
711 error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
721 bool was_dirty = dirty();
723 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
726 DirtyChanged (); /* EMIT SIGNAL */
729 StateSaved (snapshot_name); /* EMIT SIGNAL */
736 Session::restore_state (string snapshot_name)
738 if (load_state (snapshot_name) == 0) {
739 set_state (*state_tree->root());
746 Session::load_state (string snapshot_name)
755 state_was_pending = false;
757 /* check for leftover pending state from a crashed capture attempt */
760 xmlpath += snapshot_name;
761 xmlpath += _pending_suffix;
763 if (!access (xmlpath.c_str(), F_OK)) {
765 /* there is pending state from a crashed capture attempt */
767 if (AskAboutPendingState()) {
768 state_was_pending = true;
772 if (!state_was_pending) {
775 xmlpath += snapshot_name;
776 xmlpath += _statefile_suffix;
779 if (access (xmlpath.c_str(), F_OK)) {
780 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
784 state_tree = new XMLTree;
788 if (state_tree->read (xmlpath)) {
791 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
800 Session::load_options (const XMLNode& node)
804 bool have_fade_msecs = false;
805 bool have_fade_steepness = false;
806 float fade_msecs = 0;
807 float fade_steepness = 0;
808 SlaveSource slave_src = None;
810 LocaleGuard lg (X_("POSIX"));
812 if ((child = find_named_node (node, "input-auto-connect")) != 0) {
813 if ((prop = child->property ("val")) != 0) {
814 sscanf (prop->value().c_str(), "%x", &x);
815 input_auto_connect = AutoConnectOption (x);
819 if ((child = find_named_node (node, "output-auto-connect")) != 0) {
820 if ((prop = child->property ("val")) != 0) {
821 sscanf (prop->value().c_str(), "%x", &x);
822 output_auto_connect = AutoConnectOption (x);
826 if ((child = find_named_node (node, "slave")) != 0) {
827 if ((prop = child->property ("type")) != 0) {
828 if (prop->value() == "none") {
830 } else if (prop->value() == "mtc") {
832 } else if (prop->value() == "jack") {
835 set_slave_source (slave_src, 0);
839 /* we cannot set edit mode if we are loading a session,
840 because it might destroy the playlist's positioning
843 if ((child = find_named_node (node, "edit-mode")) != 0) {
844 if ((prop = child->property ("val")) != 0) {
845 if (prop->value() == "slide") {
846 pending_edit_mode = Slide;
847 } else if (prop->value() == "splice") {
848 pending_edit_mode = Splice;
853 if ((child = find_named_node (node, "send-midi-timecode")) != 0) {
854 if ((prop = child->property ("val")) != 0) {
855 bool x = (prop->value() == "yes");
856 send_mtc = !x; /* force change in value */
860 if ((child = find_named_node (node, "send-midi-machine-control")) != 0) {
861 if ((prop = child->property ("val")) != 0) {
862 bool x = (prop->value() == "yes");
863 send_mmc = !x; /* force change in value */
864 set_send_mmc (prop->value() == "yes");
867 if ((child = find_named_node (node, "max-level")) != 0) {
868 if ((prop = child->property ("val")) != 0) {
869 max_level = atoi (prop->value().c_str());
872 if ((child = find_named_node (node, "min-level")) != 0) {
873 if ((prop = child->property ("val")) != 0) {
874 min_level = atoi (prop->value().c_str());
877 if ((child = find_named_node (node, "meter-hold")) != 0) {
878 if ((prop = child->property ("val")) != 0) {
879 _meter_hold = atof (prop->value().c_str());
882 if ((child = find_named_node (node, "meter-falloff")) != 0) {
883 if ((prop = child->property ("val")) != 0) {
884 _meter_falloff = atof (prop->value().c_str());
887 if ((child = find_named_node (node, "long-over-length")) != 0) {
888 if ((prop = child->property ("val")) != 0) {
889 over_length_long = atoi (prop->value().c_str());
892 if ((child = find_named_node (node, "short-over-length")) != 0) {
893 if ((prop = child->property ("val")) != 0) {
894 over_length_short = atoi (prop->value().c_str());
897 if ((child = find_named_node (node, "shuttle-speed-factor")) != 0) {
898 if ((prop = child->property ("val")) != 0) {
899 shuttle_speed_factor = atof (prop->value().c_str());
902 if ((child = find_named_node (node, "shuttle-speed-threshold")) != 0) {
903 if ((prop = child->property ("val")) != 0) {
904 shuttle_speed_threshold = atof (prop->value().c_str());
907 if ((child = find_named_node (node, "rf-speed")) != 0) {
908 if ((prop = child->property ("val")) != 0) {
909 rf_speed = atof (prop->value().c_str());
912 if ((child = find_named_node (node, "smpte-frames-per-second")) != 0) {
913 if ((prop = child->property ("val")) != 0) {
914 set_smpte_type( atof (prop->value().c_str()), smpte_drop_frames );
917 if ((child = find_named_node (node, "smpte-drop-frames")) != 0) {
918 if ((prop = child->property ("val")) != 0) {
919 set_smpte_type( smpte_frames_per_second, (prop->value() == "yes") );
922 if ((child = find_named_node (node, "smpte-offset")) != 0) {
923 if ((prop = child->property ("val")) != 0) {
924 set_smpte_offset( atoi (prop->value().c_str()) );
927 if ((child = find_named_node (node, "smpte-offset-negative")) != 0) {
928 if ((prop = child->property ("val")) != 0) {
929 set_smpte_offset_negative( (prop->value() == "yes") );
932 if ((child = find_named_node (node, "click-sound")) != 0) {
933 if ((prop = child->property ("val")) != 0) {
934 click_sound = prop->value();
937 if ((child = find_named_node (node, "click-emphasis-sound")) != 0) {
938 if ((prop = child->property ("val")) != 0) {
939 click_emphasis_sound = prop->value();
943 if ((child = find_named_node (node, "solo-model")) != 0) {
944 if ((prop = child->property ("val")) != 0) {
945 if (prop->value() == "SoloBus")
946 _solo_model = SoloBus;
948 _solo_model = InverseMute;
952 /* BOOLEAN OPTIONS */
954 if ((child = find_named_node (node, "auto-play")) != 0) {
955 if ((prop = child->property ("val")) != 0) {
956 set_auto_play (prop->value() == "yes");
959 if ((child = find_named_node (node, "auto-input")) != 0) {
960 if ((prop = child->property ("val")) != 0) {
961 set_auto_input (prop->value() == "yes");
964 if ((child = find_named_node (node, "seamless-loop")) != 0) {
965 if ((prop = child->property ("val")) != 0) {
966 set_seamless_loop (prop->value() == "yes");
969 if ((child = find_named_node (node, "punch-in")) != 0) {
970 if ((prop = child->property ("val")) != 0) {
971 set_punch_in (prop->value() == "yes");
974 if ((child = find_named_node (node, "punch-out")) != 0) {
975 if ((prop = child->property ("val")) != 0) {
976 set_punch_out (prop->value() == "yes");
979 if ((child = find_named_node (node, "auto-return")) != 0) {
980 if ((prop = child->property ("val")) != 0) {
981 set_auto_return (prop->value() == "yes");
984 if ((child = find_named_node (node, "send-mtc")) != 0) {
985 if ((prop = child->property ("val")) != 0) {
986 set_send_mtc (prop->value() == "yes");
989 if ((child = find_named_node (node, "mmc-control")) != 0) {
990 if ((prop = child->property ("val")) != 0) {
991 set_mmc_control (prop->value() == "yes");
994 if ((child = find_named_node (node, "midi-control")) != 0) {
995 if ((prop = child->property ("val")) != 0) {
996 set_midi_control (prop->value() == "yes");
999 if ((child = find_named_node (node, "midi-feedback")) != 0) {
1000 if ((prop = child->property ("val")) != 0) {
1001 set_midi_feedback (prop->value() == "yes");
1004 // Legacy support for <recording-plugins>
1005 if ((child = find_named_node (node, "recording-plugins")) != 0) {
1006 if ((prop = child->property ("val")) != 0) {
1007 set_do_not_record_plugins (prop->value() == "no");
1010 if ((child = find_named_node (node, "do-not-record-plugins")) != 0) {
1011 if ((prop = child->property ("val")) != 0) {
1012 set_do_not_record_plugins (prop->value() == "yes");
1015 if ((child = find_named_node (node, "crossfades-active")) != 0) {
1016 if ((prop = child->property ("val")) != 0) {
1017 set_crossfades_active (prop->value() == "yes");
1020 if ((child = find_named_node (node, "audible-click")) != 0) {
1021 if ((prop = child->property ("val")) != 0) {
1022 set_clicking (prop->value() == "yes");
1026 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
1027 if ((prop = child->property ("val")) != 0) {
1028 _end_location_is_free = (prop->value() == "yes");
1032 if ((child = find_named_node (node, "layer-model")) != 0) {
1033 if ((prop = child->property ("val")) != 0) {
1034 if (prop->value() == X_("LaterHigher")) {
1035 set_layer_model (LaterHigher);
1036 } else if (prop->value() == X_("AddHigher")) {
1037 set_layer_model (AddHigher);
1039 set_layer_model (MoveAddHigher);
1044 if ((child = find_named_node (node, "xfade-model")) != 0) {
1045 if ((prop = child->property ("val")) != 0) {
1046 if (prop->value() == X_("Short")) {
1047 set_xfade_model (ShortCrossfade);
1049 set_xfade_model (FullCrossfade);
1054 if ((child = find_named_node (node, "short-xfade-length")) != 0) {
1055 if ((prop = child->property ("val")) != 0) {
1056 /* value is stored as a fractional seconds */
1057 float secs = atof (prop->value().c_str());
1058 Crossfade::set_short_xfade_length ((jack_nframes_t) floor (secs * frame_rate()));
1062 if ((child = find_named_node (node, "full-xfades-unmuted")) != 0) {
1063 if ((prop = child->property ("val")) != 0) {
1064 crossfades_active = (prop->value() == "yes");
1070 if ((child = find_named_node (node, "default-fade-steepness")) != 0) {
1071 if ((prop = child->property ("val")) != 0) {
1072 fade_steepness = atof (prop->value().c_str());
1073 have_fade_steepness = true;
1076 if ((child = find_named_node (node, "default-fade-msec")) != 0) {
1077 if ((prop = child->property ("val")) != 0) {
1078 fade_msecs = atof (prop->value().c_str());
1079 have_fade_msecs = true;
1083 if (have_fade_steepness || have_fade_msecs) {
1084 // set_default_fade (fade_steepness, fade_msecs);
1091 Session::get_options () const
1096 LocaleGuard lg (X_("POSIX"));
1098 opthead = new XMLNode ("Options");
1100 SlaveSource src = slave_source ();
1104 src_string = "none";
1110 src_string = "jack";
1113 child = opthead->add_child ("slave");
1114 child->add_property ("type", src_string);
1116 child = opthead->add_child ("send-midi-timecode");
1117 child->add_property ("val", send_midi_timecode?"yes":"no");
1119 child = opthead->add_child ("send-midi-machine-control");
1120 child->add_property ("val", send_midi_machine_control?"yes":"no");
1122 snprintf (buf, sizeof(buf)-1, "%x", (int) input_auto_connect);
1123 child = opthead->add_child ("input-auto-connect");
1124 child->add_property ("val", buf);
1126 snprintf (buf, sizeof(buf)-1, "%x", (int) output_auto_connect);
1127 child = opthead->add_child ("output-auto-connect");
1128 child->add_property ("val", buf);
1130 snprintf (buf, sizeof(buf)-1, "%d", max_level);
1131 child = opthead->add_child ("max-level");
1132 child->add_property ("val", buf);
1134 snprintf (buf, sizeof(buf)-1, "%d", min_level);
1135 child = opthead->add_child ("min-level");
1136 child->add_property ("val", buf);
1138 snprintf (buf, sizeof(buf)-1, "%f", _meter_hold);
1139 child = opthead->add_child ("meter-hold");
1140 child->add_property ("val", buf);
1142 snprintf (buf, sizeof(buf)-1, "%f", _meter_falloff);
1143 child = opthead->add_child ("meter-falloff");
1144 child->add_property ("val", buf);
1146 snprintf (buf, sizeof(buf)-1, "%u", over_length_long);
1147 child = opthead->add_child ("long-over-length");
1148 child->add_property ("val", buf);
1150 snprintf (buf, sizeof(buf)-1, "%u", over_length_short);
1151 child = opthead->add_child ("short-over-length");
1152 child->add_property ("val", buf);
1154 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_factor);
1155 child = opthead->add_child ("shuttle-speed-factor");
1156 child->add_property ("val", buf);
1158 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_threshold);
1159 child = opthead->add_child ("shuttle-speed-threshold");
1160 child->add_property ("val", buf);
1162 snprintf (buf, sizeof(buf)-1, "%f", rf_speed);
1163 child = opthead->add_child ("rf-speed");
1164 child->add_property ("val", buf);
1166 snprintf (buf, sizeof(buf)-1, "%.2f", smpte_frames_per_second);
1167 child = opthead->add_child ("smpte-frames-per-second");
1168 child->add_property ("val", buf);
1170 child = opthead->add_child ("smpte-drop-frames");
1171 child->add_property ("val", smpte_drop_frames ? "yes" : "no");
1173 snprintf (buf, sizeof(buf)-1, "%u", smpte_offset ());
1174 child = opthead->add_child ("smpte-offset");
1175 child->add_property ("val", buf);
1177 child = opthead->add_child ("smpte-offset-negative");
1178 child->add_property ("val", smpte_offset_negative () ? "yes" : "no");
1180 child = opthead->add_child ("edit-mode");
1181 switch (_edit_mode) {
1183 child->add_property ("val", "splice");
1187 child->add_property ("val", "slide");
1191 child = opthead->add_child ("auto-play");
1192 child->add_property ("val", get_auto_play () ? "yes" : "no");
1193 child = opthead->add_child ("auto-input");
1194 child->add_property ("val", get_auto_input () ? "yes" : "no");
1195 child = opthead->add_child ("seamless-loop");
1196 child->add_property ("val", get_seamless_loop () ? "yes" : "no");
1197 child = opthead->add_child ("punch-in");
1198 child->add_property ("val", get_punch_in () ? "yes" : "no");
1199 child = opthead->add_child ("punch-out");
1200 child->add_property ("val", get_punch_out () ? "yes" : "no");
1201 child = opthead->add_child ("all-safe");
1202 child->add_property ("val", get_all_safe () ? "yes" : "no");
1203 child = opthead->add_child ("auto-return");
1204 child->add_property ("val", get_auto_return () ? "yes" : "no");
1205 child = opthead->add_child ("mmc-control");
1206 child->add_property ("val", get_mmc_control () ? "yes" : "no");
1207 child = opthead->add_child ("midi-control");
1208 child->add_property ("val", get_midi_control () ? "yes" : "no");
1209 child = opthead->add_child ("midi-feedback");
1210 child->add_property ("val", get_midi_feedback () ? "yes" : "no");
1211 child = opthead->add_child ("do-not-record-plugins");
1212 child->add_property ("val", get_do_not_record_plugins () ? "yes" : "no");
1213 child = opthead->add_child ("auto-crossfade");
1214 child->add_property ("val", get_crossfades_active () ? "yes" : "no");
1215 child = opthead->add_child ("audible-click");
1216 child->add_property ("val", get_clicking () ? "yes" : "no");
1217 child = opthead->add_child ("end-marker-is-free");
1218 child->add_property ("val", _end_location_is_free ? "yes" : "no");
1220 if (click_sound.length()) {
1221 child = opthead->add_child ("click-sound");
1222 child->add_property ("val", click_sound);
1225 if (click_emphasis_sound.length()) {
1226 child = opthead->add_child ("click-emphasis-sound");
1227 child->add_property ("val", click_emphasis_sound);
1230 child = opthead->add_child ("solo-model");
1231 child->add_property ("val", _solo_model == SoloBus ? "SoloBus" : "InverseMute");
1233 child = opthead->add_child ("layer-model");
1234 switch (layer_model) {
1236 child->add_property ("val", X_("LaterHigher"));
1239 child->add_property ("val", X_("MoveAddHigher"));
1242 child->add_property ("val", X_("AddHigher"));
1246 child = opthead->add_child ("xfade-model");
1247 switch (xfade_model) {
1249 child->add_property ("val", X_("Full"));
1251 case ShortCrossfade:
1252 child->add_property ("val", X_("Short"));
1255 child = opthead->add_child ("short-xfade-length");
1256 /* store as fractions of a second */
1257 snprintf (buf, sizeof(buf)-1, "%f",
1258 (float) Crossfade::short_xfade_length() / frame_rate());
1259 child->add_property ("val", buf);
1261 child = opthead->add_child ("full-xfades-unmuted");
1262 child->add_property ("val", crossfades_active ? "yes" : "no");
1268 Session::get_state()
1274 Session::get_template()
1276 /* if we don't disable rec-enable, diskstreams
1277 will believe they need to store their capture
1278 sources in their state node.
1281 disable_record (false);
1283 return state(false);
1287 Session::state(bool full_state)
1289 XMLNode* node = new XMLNode("Session");
1292 // store libardour version, just in case
1294 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
1295 libardour_major_version, libardour_minor_version, libardour_micro_version);
1296 node->add_property("version", string(buf));
1298 /* store configuration settings */
1302 /* store the name */
1303 node->add_property ("name", _name);
1305 if (session_dirs.size() > 1) {
1309 vector<space_and_path>::iterator i = session_dirs.begin();
1310 vector<space_and_path>::iterator next;
1312 ++i; /* skip the first one */
1316 while (i != session_dirs.end()) {
1320 if (next != session_dirs.end()) {
1330 child = node->add_child ("Path");
1331 child->add_content (p);
1335 node->add_child_nocopy (get_options());
1337 child = node->add_child ("Sources");
1340 LockMonitor sl (source_lock, __LINE__, __FILE__);
1342 for (SourceList::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1344 /* Don't save information about FileSources that are empty */
1348 if ((fs = dynamic_cast<FileSource*> ((*siter).second)) != 0) {
1349 DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
1351 /* destructive file sources are OK if they are empty, because
1352 we will re-use them every time.
1356 if (fs->length() == 0) {
1362 child->add_child_nocopy ((*siter).second->get_state());
1366 child = node->add_child ("Regions");
1369 LockMonitor rl (region_lock, __LINE__, __FILE__);
1371 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1373 /* only store regions not attached to playlists */
1375 if ((*i).second->playlist() == 0) {
1376 child->add_child_nocopy (i->second->state (true));
1381 child = node->add_child ("DiskStreams");
1384 RWLockMonitor dl (diskstream_lock, false, __LINE__, __FILE__);
1385 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1386 if (!(*i)->hidden()) {
1387 child->add_child_nocopy ((*i)->get_state());
1392 node->add_child_nocopy (_locations.get_state());
1394 child = node->add_child ("Connections");
1396 LockMonitor lm (connection_lock, __LINE__, __FILE__);
1397 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1398 if (!(*i)->system_dependent()) {
1399 child->add_child_nocopy ((*i)->get_state());
1404 child = node->add_child ("Routes");
1406 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1408 RoutePublicOrderSorter cmp;
1409 RouteList public_order(routes);
1410 public_order.sort (cmp);
1412 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1413 if (!(*i)->hidden()) {
1415 child->add_child_nocopy ((*i)->get_state());
1417 child->add_child_nocopy ((*i)->get_template());
1424 child = node->add_child ("EditGroups");
1425 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1426 child->add_child_nocopy ((*i)->get_state());
1429 child = node->add_child ("MixGroups");
1430 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1431 child->add_child_nocopy ((*i)->get_state());
1434 child = node->add_child ("Playlists");
1435 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1436 if (!(*i)->hidden()) {
1437 if (!(*i)->empty()) {
1439 child->add_child_nocopy ((*i)->get_state());
1441 child->add_child_nocopy ((*i)->get_template());
1447 child = node->add_child ("UnusedPlaylists");
1448 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1449 if (!(*i)->hidden()) {
1450 if (!(*i)->empty()) {
1452 child->add_child_nocopy ((*i)->get_state());
1454 child->add_child_nocopy ((*i)->get_template());
1462 child = node->add_child ("Click");
1463 child->add_child_nocopy (_click_io->state (full_state));
1467 child = node->add_child ("NamedSelections");
1468 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1470 child->add_child_nocopy ((*i)->get_state());
1475 node->add_child_nocopy (_tempo_map->get_state());
1478 node->add_child_copy (*_extra_xml);
1485 Session::set_state (const XMLNode& node)
1489 const XMLProperty* prop;
1492 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1494 if (node.name() != "Session"){
1495 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1499 StateManager::prohibit_save ();
1501 if ((prop = node.property ("name")) != 0) {
1502 _name = prop->value ();
1505 IO::disable_ports ();
1506 IO::disable_connecting ();
1508 /* Object loading order:
1525 if (use_config_midi_ports ()) {
1528 if ((child = find_named_node (node, "Path")) != 0) {
1529 /* XXX this XML content stuff horrible API design */
1530 string raid_path = _path + ':' + child->children().front()->content();
1531 setup_raid_path (raid_path);
1533 /* the path is already set */
1536 if ((child = find_named_node (node, "extra")) != 0) {
1537 _extra_xml = new XMLNode (*child);
1540 if ((child = find_named_node (node, "Options")) == 0) {
1541 error << _("Session: XML state has no options section") << endmsg;
1542 } else if (load_options (*child)) {
1545 if ((child = find_named_node (node, "Sources")) == 0) {
1546 error << _("Session: XML state has no sources section") << endmsg;
1548 } else if (load_sources (*child)) {
1552 if ((child = find_named_node (node, "Regions")) == 0) {
1553 error << _("Session: XML state has no Regions section") << endmsg;
1555 } else if (load_regions (*child)) {
1559 if ((child = find_named_node (node, "Playlists")) == 0) {
1560 error << _("Session: XML state has no playlists section") << endmsg;
1562 } else if (load_playlists (*child)) {
1566 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1568 } else if (load_unused_playlists (*child)) {
1572 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1573 if (load_named_selections (*child)) {
1578 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1579 error << _("Session: XML state has no diskstreams section") << endmsg;
1581 } else if (load_diskstreams (*child)) {
1585 if ((child = find_named_node (node, "Connections")) == 0) {
1586 error << _("Session: XML state has no connections section") << endmsg;
1588 } else if (load_connections (*child)) {
1592 if ((child = find_named_node (node, "Locations")) == 0) {
1593 error << _("Session: XML state has no locations section") << endmsg;
1595 } else if (_locations.set_state (*child)) {
1601 if ((location = _locations.auto_loop_location()) != 0) {
1602 set_auto_loop_location (location);
1605 if ((location = _locations.auto_punch_location()) != 0) {
1606 set_auto_punch_location (location);
1609 if ((location = _locations.end_location()) == 0) {
1610 _locations.add (end_location);
1612 delete end_location;
1613 end_location = location;
1616 if ((location = _locations.start_location()) == 0) {
1617 _locations.add (start_location);
1619 delete start_location;
1620 start_location = location;
1623 _locations.save_state (_("initial state"));
1625 if ((child = find_named_node (node, "EditGroups")) == 0) {
1626 error << _("Session: XML state has no edit groups section") << endmsg;
1628 } else if (load_edit_groups (*child)) {
1632 if ((child = find_named_node (node, "MixGroups")) == 0) {
1633 error << _("Session: XML state has no mix groups section") << endmsg;
1635 } else if (load_mix_groups (*child)) {
1639 if ((child = find_named_node (node, "TempoMap")) == 0) {
1640 error << _("Session: XML state has no Tempo Map section") << endmsg;
1642 } else if (_tempo_map->set_state (*child)) {
1646 if ((child = find_named_node (node, "Routes")) == 0) {
1647 error << _("Session: XML state has no routes section") << endmsg;
1649 } else if (load_routes (*child)) {
1653 if ((child = find_named_node (node, "Click")) == 0) {
1654 warning << _("Session: XML state has no click section") << endmsg;
1655 } else if (_click_io) {
1656 _click_io->set_state (*child);
1659 /* OK, now we can set edit mode */
1661 set_edit_mode (pending_edit_mode);
1663 /* here beginneth the second phase ... */
1665 StateReady (); /* EMIT SIGNAL */
1667 _state_of_the_state = Clean;
1669 StateManager::allow_save (_("initial state"), true);
1671 if (state_was_pending) {
1672 save_state (_current_snapshot_name);
1673 remove_pending_capture_state ();
1674 state_was_pending = false;
1680 /* we failed, re-enable state saving but don't actually save internal state */
1681 StateManager::allow_save (X_("ignored"), false);
1686 Session::load_routes (const XMLNode& node)
1689 XMLNodeConstIterator niter;
1692 nlist = node.children();
1696 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1698 if ((route = XMLRouteFactory (**niter)) == 0) {
1699 error << _("Session: cannot create Route from XML description.") << endmsg;
1710 Session::XMLRouteFactory (const XMLNode& node)
1712 if (node.name() != "Route") {
1716 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1717 return new AudioTrack (*this, node);
1719 return new Route (*this, node);
1724 Session::load_regions (const XMLNode& node)
1727 XMLNodeConstIterator niter;
1728 AudioRegion* region;
1730 nlist = node.children();
1734 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1736 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1737 error << _("Session: cannot create Region from XML description.") << endmsg;
1745 Session::XMLRegionFactory (const XMLNode& node, bool full)
1747 const XMLProperty* prop;
1750 AudioRegion::SourceList sources;
1751 uint32_t nchans = 1;
1754 if (node.name() != X_("Region")) {
1758 if ((prop = node.property (X_("channels"))) != 0) {
1759 nchans = atoi (prop->value().c_str());
1763 if ((prop = node.property (X_("source-0"))) == 0) {
1764 if ((prop = node.property ("source")) == 0) {
1765 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1770 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1772 if ((source = get_source (s_id)) == 0) {
1773 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1777 sources.push_back(source);
1779 /* pickup other channels */
1781 for (uint32_t n=1; n < nchans; ++n) {
1782 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1783 if ((prop = node.property (buf)) != 0) {
1784 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1786 if ((source = get_source (s_id)) == 0) {
1787 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1790 sources.push_back(source);
1796 return new AudioRegion (sources, node);
1799 catch (failed_constructor& err) {
1805 Session::get_sources_as_xml ()
1808 XMLNode* node = new XMLNode (X_("Sources"));
1809 LockMonitor lm (source_lock, __LINE__, __FILE__);
1811 for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
1812 node->add_child_nocopy ((*i).second->get_state());
1819 Session::path_from_region_name (string name, string identifier)
1821 char buf[PATH_MAX+1];
1823 string dir = discover_best_sound_dir ();
1825 for (n = 0; n < 999999; ++n) {
1826 if (identifier.length()) {
1827 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1828 identifier.c_str(), n);
1830 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1832 if (access (buf, F_OK) != 0) {
1842 Session::load_sources (const XMLNode& node)
1845 XMLNodeConstIterator niter;
1848 nlist = node.children();
1852 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1854 if ((source = XMLSourceFactory (**niter)) == 0) {
1855 error << _("Session: cannot create Source from XML description.") << endmsg;
1863 Session::XMLSourceFactory (const XMLNode& node)
1867 if (node.name() != "Source") {
1872 if (node.property (X_("destructive")) != 0) {
1873 src = new DestructiveFileSource (node, frame_rate());
1875 src = new FileSource (node, frame_rate());
1879 catch (failed_constructor& err) {
1882 src = ExternalSource::create (node);
1885 catch (failed_constructor& err) {
1886 error << _("Found a sound file that cannot be used by Ardour. See the progammers.") << endmsg;
1895 Session::save_template (string template_name)
1898 string xml_path, bak_path, template_path;
1900 if (_state_of_the_state & CannotSave) {
1905 string dir = template_dir();
1907 if ((dp = opendir (dir.c_str()))) {
1910 if (mkdir (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)<0) {
1911 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1916 tree.set_root (&get_template());
1919 xml_path += template_name;
1920 xml_path += _template_suffix;
1922 ifstream in(xml_path.c_str());
1925 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1931 if (!tree.write (xml_path)) {
1932 error << _("mix template not saved") << endmsg;
1940 Session::rename_template (string old_name, string new_name)
1942 string old_path = template_dir() + old_name + _template_suffix;
1943 string new_path = template_dir() + new_name + _template_suffix;
1945 return rename (old_path.c_str(), new_path.c_str());
1949 Session::delete_template (string name)
1951 string template_path = template_dir();
1952 template_path += name;
1953 template_path += _template_suffix;
1955 return remove (template_path.c_str());
1959 Session::refresh_disk_space ()
1962 struct statfs statfsbuf;
1963 vector<space_and_path>::iterator i;
1964 LockMonitor lm (space_lock, __LINE__, __FILE__);
1967 /* get freespace on every FS that is part of the session path */
1969 _total_free_4k_blocks = 0;
1971 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1972 statfs ((*i).path.c_str(), &statfsbuf);
1974 scale = statfsbuf.f_bsize/4096.0;
1976 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1977 _total_free_4k_blocks += (*i).blocks;
1983 Session::ensure_sound_dir (string path, string& result)
1988 /* Ensure that the parent directory exists */
1990 if (mkdir (path.c_str(), 0775)) {
1991 if (errno != EEXIST) {
1992 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1997 /* Ensure that the sounds directory exists */
2001 result += sound_dir_name;
2003 if (mkdir (result.c_str(), 0775)) {
2004 if (errno != EEXIST) {
2005 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
2012 dead += dead_sound_dir_name;
2014 if (mkdir (dead.c_str(), 0775)) {
2015 if (errno != EEXIST) {
2016 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
2023 peak += peak_dir_name;
2025 if (mkdir (peak.c_str(), 0775)) {
2026 if (errno != EEXIST) {
2027 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
2032 /* callers expect this to be terminated ... */
2039 Session::discover_best_sound_dir (bool destructive)
2041 vector<space_and_path>::iterator i;
2044 /* destructive files all go into the same place */
2050 /* handle common case without system calls */
2052 if (session_dirs.size() == 1) {
2056 /* OK, here's the algorithm we're following here:
2058 We want to select which directory to use for
2059 the next file source to be created. Ideally,
2060 we'd like to use a round-robin process so as to
2061 get maximum performance benefits from splitting
2062 the files across multiple disks.
2064 However, in situations without much diskspace, an
2065 RR approach may end up filling up a filesystem
2066 with new files while others still have space.
2067 Its therefore important to pay some attention to
2068 the freespace in the filesystem holding each
2069 directory as well. However, if we did that by
2070 itself, we'd keep creating new files in the file
2071 system with the most space until it was as full
2072 as all others, thus negating any performance
2073 benefits of this RAID-1 like approach.
2075 So, we use a user-configurable space threshold. If
2076 there are at least 2 filesystems with more than this
2077 much space available, we use RR selection between them.
2078 If not, then we pick the filesystem with the most space.
2080 This gets a good balance between the two
2084 refresh_disk_space ();
2086 int free_enough = 0;
2088 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2089 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2094 if (free_enough >= 2) {
2096 bool found_it = false;
2098 /* use RR selection process, ensuring that the one
2102 i = last_rr_session_dir;
2105 if (++i == session_dirs.end()) {
2106 i = session_dirs.begin();
2109 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2110 if (ensure_sound_dir ((*i).path, result) == 0) {
2111 last_rr_session_dir = i;
2117 } while (i != last_rr_session_dir);
2120 result = sound_dir();
2125 /* pick FS with the most freespace (and that
2126 seems to actually work ...)
2129 vector<space_and_path> sorted;
2130 space_and_path_ascending_cmp cmp;
2132 sorted = session_dirs;
2133 sort (sorted.begin(), sorted.end(), cmp);
2135 for (i = sorted.begin(); i != sorted.end(); ++i) {
2136 if (ensure_sound_dir ((*i).path, result) == 0) {
2137 last_rr_session_dir = i;
2142 /* if the above fails, fall back to the most simplistic solution */
2144 if (i == sorted.end()) {
2153 Session::load_playlists (const XMLNode& node)
2156 XMLNodeConstIterator niter;
2159 nlist = node.children();
2163 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2165 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2166 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2174 Session::load_unused_playlists (const XMLNode& node)
2177 XMLNodeConstIterator niter;
2180 nlist = node.children();
2184 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2186 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2187 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2191 // now manually untrack it
2193 track_playlist (playlist, false);
2201 Session::XMLPlaylistFactory (const XMLNode& node)
2204 return new AudioPlaylist (*this, node);
2207 catch (failed_constructor& err) {
2213 Session::load_named_selections (const XMLNode& node)
2216 XMLNodeConstIterator niter;
2219 nlist = node.children();
2223 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2225 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2226 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2234 Session::XMLNamedSelectionFactory (const XMLNode& node)
2237 return new NamedSelection (*this, node);
2240 catch (failed_constructor& err) {
2246 Session::dead_sound_dir () const
2249 res += dead_sound_dir_name;
2255 Session::sound_dir () const
2258 res += sound_dir_name;
2264 Session::tape_dir () const
2267 res += tape_dir_name;
2273 Session::peak_dir () const
2276 res += peak_dir_name;
2282 Session::automation_dir () const
2285 res += "automation/";
2290 Session::template_dir ()
2292 string path = get_user_ardour_path();
2293 path += "templates/";
2299 Session::template_path ()
2303 path += get_user_ardour_path();
2304 if (path[path.length()-1] != ':') {
2307 path += get_system_ardour_path();
2309 vector<string> split_path;
2311 split (path, split_path, ':');
2314 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2316 path += "templates/";
2318 if (distance (i, split_path.end()) != 1) {
2327 Session::load_connections (const XMLNode& node)
2329 XMLNodeList nlist = node.children();
2330 XMLNodeConstIterator niter;
2334 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2335 if ((*niter)->name() == "InputConnection") {
2336 add_connection (new ARDOUR::InputConnection (**niter));
2337 } else if ((*niter)->name() == "OutputConnection") {
2338 add_connection (new ARDOUR::OutputConnection (**niter));
2340 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2349 Session::load_edit_groups (const XMLNode& node)
2351 return load_route_groups (node, true);
2355 Session::load_mix_groups (const XMLNode& node)
2357 return load_route_groups (node, false);
2361 Session::load_route_groups (const XMLNode& node, bool edit)
2363 XMLNodeList nlist = node.children();
2364 XMLNodeConstIterator niter;
2369 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2370 if ((*niter)->name() == "RouteGroup") {
2372 route = add_edit_group ("");
2373 route->set_state (**niter);
2375 route = add_mix_group ("");
2376 route->set_state (**niter);
2385 Session::swap_configuration(Configuration** new_config)
2387 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__); // jlc - WHY?
2388 Configuration* tmp = *new_config;
2389 *new_config = Config;
2395 Session::copy_configuration(Configuration* new_config)
2397 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
2398 new_config = new Configuration(*Config);
2402 state_file_filter (const string &str, void *arg)
2404 return (str.length() > strlen(Session::statefile_suffix()) &&
2405 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2409 bool operator()(const string* a, const string* b) {
2415 remove_end(string* state)
2417 string statename(*state);
2419 string::size_type start,end;
2420 if ((start = statename.find_last_of ('/')) != string::npos) {
2421 statename = statename.substr (start+1);
2424 if ((end = statename.rfind(".ardour")) < 0) {
2425 end = statename.length();
2428 return new string(statename.substr (0, end));
2432 Session::possible_states (string path)
2434 PathScanner scanner;
2435 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2437 transform(states->begin(), states->end(), states->begin(), remove_end);
2440 sort (states->begin(), states->end(), cmp);
2446 Session::possible_states () const
2448 return possible_states(_path);
2452 Session::auto_save()
2454 save_state (_current_snapshot_name);
2458 Session::add_edit_group (string name)
2460 RouteGroup* rg = new RouteGroup (*this, name);
2461 edit_groups.push_back (rg);
2462 edit_group_added (rg); /* EMIT SIGNAL */
2468 Session::add_mix_group (string name)
2470 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2471 mix_groups.push_back (rg);
2472 mix_group_added (rg); /* EMIT SIGNAL */
2478 Session::remove_edit_group (RouteGroup& rg)
2480 list<RouteGroup*>::iterator i;
2482 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2483 (*i)->apply (&Route::drop_edit_group, this);
2484 edit_groups.erase (i);
2485 edit_group_removed (); /* EMIT SIGNAL */
2492 Session::remove_mix_group (RouteGroup& rg)
2494 list<RouteGroup*>::iterator i;
2496 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2497 (*i)->apply (&Route::drop_mix_group, this);
2498 mix_groups.erase (i);
2499 mix_group_removed (); /* EMIT SIGNAL */
2506 Session::mix_group_by_name (string name)
2508 list<RouteGroup *>::iterator i;
2510 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2511 if ((*i)->name() == name) {
2519 Session::edit_group_by_name (string name)
2521 list<RouteGroup *>::iterator i;
2523 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2524 if ((*i)->name() == name) {
2532 Session::set_meter_hold (float val)
2535 MeterHoldChanged(); // emit
2539 Session::set_meter_falloff (float val)
2541 _meter_falloff = val;
2542 MeterFalloffChanged(); // emit
2547 Session::begin_reversible_command (string name, UndoAction* private_undo)
2549 current_cmd.clear ();
2550 current_cmd.set_name (name);
2553 current_cmd.add_undo (*private_undo);
2558 Session::commit_reversible_command (UndoAction* private_redo)
2563 current_cmd.add_redo_no_execute (*private_redo);
2566 gettimeofday (&now, 0);
2567 current_cmd.set_timestamp (now);
2569 history.add (current_cmd);
2572 Session::GlobalRouteBooleanState
2573 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2575 GlobalRouteBooleanState s;
2576 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2578 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2579 if (!(*i)->hidden()) {
2580 RouteBooleanState v;
2583 v.second = ((*i)->*method)();
2592 Session::GlobalRouteMeterState
2593 Session::get_global_route_metering ()
2595 GlobalRouteMeterState s;
2596 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2598 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2599 if (!(*i)->hidden()) {
2603 v.second = (*i)->meter_point();
2613 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2615 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2616 i->first->set_meter_point (i->second, arg);
2621 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2623 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2624 (i->first->*method) (i->second, arg);
2629 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2631 set_global_route_boolean (s, &Route::set_mute, src);
2635 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2637 set_global_route_boolean (s, &Route::set_solo, src);
2641 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2643 set_global_route_boolean (s, &Route::set_record_enable, src);
2647 Session::global_mute_memento (void* src)
2649 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2653 Session::global_metering_memento (void* src)
2655 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2659 Session::global_solo_memento (void* src)
2661 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2665 Session::global_record_enable_memento (void* src)
2667 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2671 template_filter (const string &str, void *arg)
2673 return (str.length() > strlen(Session::template_suffix()) &&
2674 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2678 Session::get_template_list (list<string> &template_names)
2680 vector<string *> *templates;
2681 PathScanner scanner;
2684 path = template_path ();
2686 templates = scanner (path, template_filter, 0, false, true);
2688 vector<string*>::iterator i;
2689 for (i = templates->begin(); i != templates->end(); ++i) {
2690 string fullpath = *(*i);
2693 start = fullpath.find_last_of ('/') + 1;
2694 if ((end = fullpath.find_last_of ('.')) <0) {
2695 end = fullpath.length();
2698 template_names.push_back(fullpath.substr(start, (end-start)));
2703 Session::read_favorite_dirs (FavoriteDirs & favs)
2705 string path = get_user_ardour_path();
2706 path += "/favorite_dirs";
2708 ifstream fav (path.c_str());
2713 if (errno != ENOENT) {
2714 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2725 getline(fav, newfav);
2731 favs.push_back (newfav);
2738 Session::write_favorite_dirs (FavoriteDirs & favs)
2740 string path = get_user_ardour_path();
2741 path += "/favorite_dirs";
2743 ofstream fav (path.c_str());
2749 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2750 fav << (*i) << endl;
2757 accept_all_non_peak_files (const string& path, void *arg)
2759 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2763 accept_all_state_files (const string& path, void *arg)
2765 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2769 Session::find_all_sources (string path, set<string>& result)
2774 if (!tree.read (path)) {
2778 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2783 XMLNodeConstIterator niter;
2785 nlist = node->children();
2789 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2793 if ((prop = (*niter)->property (X_("name"))) == 0) {
2797 if (prop->value()[0] == '/') {
2798 /* external file, ignore */
2802 string path = _path; /* /-terminated */
2803 path += sound_dir_name;
2805 path += prop->value();
2807 result.insert (path);
2814 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2816 PathScanner scanner;
2817 vector<string*>* state_files;
2819 string this_snapshot_path;
2825 if (ripped[ripped.length()-1] == '/') {
2826 ripped = ripped.substr (0, ripped.length() - 1);
2829 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2831 if (state_files == 0) {
2836 this_snapshot_path = _path;
2837 this_snapshot_path += _current_snapshot_name;
2838 this_snapshot_path += _statefile_suffix;
2840 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2842 if (exclude_this_snapshot && **i == this_snapshot_path) {
2846 if (find_all_sources (**i, result) < 0) {
2855 Session::cleanup_sources (Session::cleanup_report& rep)
2857 vector<Source*> dead_sources;
2858 vector<Playlist*> playlists_tbd;
2859 PathScanner scanner;
2861 vector<space_and_path>::iterator i;
2862 vector<space_and_path>::iterator nexti;
2863 vector<string*>* soundfiles;
2864 vector<string> unused;
2865 set<string> all_sources;
2870 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2872 /* step 1: consider deleting all unused playlists */
2874 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2877 status = AskAboutPlaylistDeletion (*x);
2886 playlists_tbd.push_back (*x);
2890 /* leave it alone */
2895 /* now delete any that were marked for deletion */
2897 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2898 PlaylistList::iterator foo;
2900 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2901 unused_playlists.erase (foo);
2906 /* step 2: clear the undo/redo history for all playlists */
2908 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2909 (*x)->drop_all_states ();
2912 /* step 3: find all un-referenced sources */
2917 for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
2919 SourceList::iterator tmp;
2924 /* only remove files that are not in use and have some size
2925 to them. otherwise we remove the current "nascent"
2929 if ((*i).second->use_cnt() == 0 && (*i).second->length() > 0) {
2930 dead_sources.push_back (i->second);
2932 /* remove this source from our own list to avoid us
2933 adding it to the list of all sources below
2942 /* Step 4: get rid of all regions in the region list that use any dead sources
2943 in case the sources themselves don't go away (they might be referenced in
2947 for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2949 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2950 AudioRegionList::iterator tmp;
2958 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2959 if (&ar->source (n) == (*i)) {
2960 /* this region is dead */
2969 /* build a list of all the possible sound directories for the session */
2971 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2976 sound_path += (*i).path;
2977 sound_path += sound_dir_name;
2979 if (nexti != session_dirs.end()) {
2986 /* now do the same thing for the files that ended up in the sounds dir(s)
2987 but are not referenced as sources in any snapshot.
2990 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2992 if (soundfiles == 0) {
2996 /* find all sources, but don't use this snapshot because the
2997 state file on disk still references sources we may have already
3001 find_all_sources_across_snapshots (all_sources, true);
3003 /* add our current source list
3006 for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
3008 ExternalSource* sfs;
3010 if ((fs = dynamic_cast<FileSource*> ((*i).second)) != 0) {
3011 all_sources.insert (fs->path());
3012 } else if ((sfs = dynamic_cast<ExternalSource*> ((*i).second)) != 0) {
3013 all_sources.insert (sfs->path());
3017 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
3022 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
3032 unused.push_back (spath);
3036 /* now try to move all unused files into the "dead_sounds" directory(ies) */
3038 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
3039 struct stat statbuf;
3041 rep.paths.push_back (*x);
3042 if (stat ((*x).c_str(), &statbuf) == 0) {
3043 rep.space += statbuf.st_size;
3048 /* don't move the file across filesystems, just
3049 stick it in the `dead_sound_dir_name' directory
3050 on whichever filesystem it was already on.
3053 newpath = PBD::dirname (*x);
3054 newpath = PBD::dirname (newpath);
3057 newpath += dead_sound_dir_name;
3059 newpath += PBD::basename ((*x));
3061 if (access (newpath.c_str(), F_OK) == 0) {
3063 /* the new path already exists, try versioning */
3065 char buf[PATH_MAX+1];
3069 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
3072 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
3073 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
3077 if (version == 999) {
3078 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
3082 newpath = newpath_v;
3087 /* it doesn't exist, or we can't read it or something */
3091 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
3092 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
3093 (*x), newpath, strerror (errno))
3099 /* see if there an easy to find peakfile for this file, and remove it.
3102 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
3103 peakpath += ".peak";
3105 if (access (peakpath.c_str(), W_OK) == 0) {
3106 if (::unlink (peakpath.c_str()) != 0) {
3107 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3108 peakpath, _path, strerror (errno))
3110 /* try to back out */
3111 rename (newpath.c_str(), _path.c_str());
3120 /* dump the history list */
3124 /* save state so we don't end up a session file
3125 referring to non-existent sources.
3131 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3136 Session::cleanup_trash_sources (Session::cleanup_report& rep)
3138 vector<space_and_path>::iterator i;
3139 string dead_sound_dir;
3140 struct dirent* dentry;
3141 struct stat statbuf;
3147 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3149 dead_sound_dir = (*i).path;
3150 dead_sound_dir += dead_sound_dir_name;
3152 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
3156 while ((dentry = readdir (dead)) != 0) {
3158 /* avoid '.' and '..' */
3160 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
3161 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3167 fullpath = dead_sound_dir;
3169 fullpath += dentry->d_name;
3171 if (stat (fullpath.c_str(), &statbuf)) {
3175 if (!S_ISREG (statbuf.st_mode)) {
3179 if (unlink (fullpath.c_str())) {
3180 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3181 fullpath, strerror (errno))
3185 rep.paths.push_back (dentry->d_name);
3186 rep.space += statbuf.st_size;
3197 Session::set_dirty ()
3199 bool was_dirty = dirty();
3201 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3204 DirtyChanged(); /* EMIT SIGNAL */
3210 Session::set_clean ()
3212 bool was_dirty = dirty();
3214 _state_of_the_state = Clean;
3217 DirtyChanged(); /* EMIT SIGNAL */