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>
84 #include <ardour/control_protocol_manager.h>
90 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 atomic_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 atomic_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;
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 ()) {
305 if (set_state (*state_tree->root())) {
310 /* we can't save till after ::when_engine_running() is called,
311 because otherwise we save state with no connections made.
312 therefore, we reset _state_of_the_state because ::set_state()
313 will have cleared it.
315 we also have to include Loading so that any events that get
316 generated between here and the end of ::when_engine_running()
317 will be processed directly rather than queued.
320 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
322 // set_auto_input (true);
323 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
324 _locations.added.connect (mem_fun (this, &Session::locations_added));
325 setup_click_sounds (0);
326 setup_midi_control ();
328 /* Pay attention ... */
330 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
331 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
333 if (_engine.running()) {
334 when_engine_running();
336 first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
339 send_full_time_code ();
340 _engine.transport_locate (0);
341 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
342 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
344 ControlProtocolManager::instance().set_session (*this);
347 _end_location_is_free = true;
349 _end_location_is_free = false;
356 Session::raid_path () const
360 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
365 return path.substr (0, path.length() - 1); // drop final colon
369 Session::set_raid_path (string path)
371 /* public-access to setup_raid_path() */
373 setup_raid_path (path);
377 Session::setup_raid_path (string path)
379 string::size_type colon;
383 string::size_type len = path.length();
388 if (path.length() == 0) {
392 session_dirs.clear ();
394 for (string::size_type n = 0; n < len; ++n) {
395 if (path[n] == ':') {
402 /* no multiple search path, just one location (common case) */
406 session_dirs.push_back (sp);
413 if (fspath[fspath.length()-1] != '/') {
416 fspath += sound_dir_name;
422 if (fspath[fspath.length()-1] != '/') {
425 fspath += tape_dir_name;
427 FileSource::set_search_path (fspath);
434 while ((colon = remaining.find_first_of (':')) != string::npos) {
437 sp.path = remaining.substr (0, colon);
438 session_dirs.push_back (sp);
440 /* add sounds to file search path */
443 if (fspath[fspath.length()-1] != '/') {
446 fspath += sound_dir_name;
449 /* add tape dir to file search path */
452 if (fspath[fspath.length()-1] != '/') {
455 fspath += tape_dir_name;
458 remaining = remaining.substr (colon+1);
461 if (remaining.length()) {
468 if (fspath[fspath.length()-1] != '/') {
471 fspath += sound_dir_name;
475 if (fspath[fspath.length()-1] != '/') {
478 fspath += tape_dir_name;
480 session_dirs.push_back (sp);
483 /* set the FileSource search path */
485 FileSource::set_search_path (fspath);
487 /* reset the round-robin soundfile path thingie */
489 last_rr_session_dir = session_dirs.begin();
493 Session::create (bool& new_session, string* mix_template, jack_nframes_t initial_length)
497 if (mkdir (_path.c_str(), 0755) < 0) {
498 if (errno == EEXIST) {
501 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
510 if (mkdir (dir.c_str(), 0755) < 0) {
511 if (errno != EEXIST) {
512 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
519 if (mkdir (dir.c_str(), 0755) < 0) {
520 if (errno != EEXIST) {
521 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
528 if (mkdir (dir.c_str(), 0755) < 0) {
529 if (errno != EEXIST) {
530 error << string_compose(_("Session: cannot create session tape dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
535 dir = dead_sound_dir ();
537 if (mkdir (dir.c_str(), 0755) < 0) {
538 if (errno != EEXIST) {
539 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
544 dir = automation_dir ();
546 if (mkdir (dir.c_str(), 0755) < 0) {
547 if (errno != EEXIST) {
548 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
554 /* check new_session so we don't overwrite an existing one */
558 std::string in_path = *mix_template;
560 ifstream in(in_path.c_str());
563 string out_path = _path;
565 out_path += _statefile_suffix;
567 ofstream out(out_path.c_str());
572 // okay, session is set up. Treat like normal saved
573 // session from now on.
579 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
585 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
592 warning << _("Session already exists. Not overwriting") << endmsg;
599 /* set initial start + end point */
601 start_location->set_end (0);
602 _locations.add (start_location);
604 end_location->set_end (initial_length);
605 _locations.add (end_location);
607 _state_of_the_state = Clean;
609 if (save_state (_current_snapshot_name)) {
618 Session::load_diskstreams (const XMLNode& node)
621 XMLNodeConstIterator citer;
623 clist = node.children();
625 for (citer = clist.begin(); citer != clist.end(); ++citer) {
630 dstream = new DiskStream (*this, **citer);
631 /* added automatically by DiskStreamCreated handler */
634 catch (failed_constructor& err) {
635 error << _("Session: could not load diskstream via XML state") << endmsg;
644 Session::remove_pending_capture_state ()
649 xml_path += _current_snapshot_name;
650 xml_path += _pending_suffix;
652 unlink (xml_path.c_str());
656 Session::save_state (string snapshot_name, bool pending)
662 if (_state_of_the_state & CannotSave) {
666 tree.set_root (&get_state());
668 if (snapshot_name.empty()) {
669 snapshot_name = _current_snapshot_name;
675 xml_path += snapshot_name;
676 xml_path += _statefile_suffix;
680 // Make backup of state file
682 if ((access (xml_path.c_str(), F_OK) == 0) &&
683 (rename(xml_path.c_str(), bak_path.c_str()))) {
684 error << _("could not backup old state file, current state not saved.") << endmsg;
691 xml_path += snapshot_name;
692 xml_path += _pending_suffix;
696 if (!tree.write (xml_path)) {
697 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
699 /* don't leave a corrupt file lying around if it is
703 if (unlink (xml_path.c_str())) {
704 error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
707 if (rename (bak_path.c_str(), xml_path.c_str())) {
708 error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
718 bool was_dirty = dirty();
720 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
723 DirtyChanged (); /* EMIT SIGNAL */
726 StateSaved (snapshot_name); /* EMIT SIGNAL */
733 Session::restore_state (string snapshot_name)
735 if (load_state (snapshot_name) == 0) {
736 set_state (*state_tree->root());
743 Session::load_state (string snapshot_name)
752 state_was_pending = false;
754 /* check for leftover pending state from a crashed capture attempt */
757 xmlpath += snapshot_name;
758 xmlpath += _pending_suffix;
760 if (!access (xmlpath.c_str(), F_OK)) {
762 /* there is pending state from a crashed capture attempt */
764 if (AskAboutPendingState()) {
765 state_was_pending = true;
769 if (!state_was_pending) {
772 xmlpath += snapshot_name;
773 xmlpath += _statefile_suffix;
776 if (access (xmlpath.c_str(), F_OK)) {
777 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
781 state_tree = new XMLTree;
785 if (state_tree->read (xmlpath)) {
788 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
797 Session::load_options (const XMLNode& node)
801 bool have_fade_msecs = false;
802 bool have_fade_steepness = false;
803 float fade_msecs = 0;
804 float fade_steepness = 0;
805 SlaveSource slave_src = None;
807 LocaleGuard lg (X_("POSIX"));
809 if ((child = find_named_node (node, "input-auto-connect")) != 0) {
810 if ((prop = child->property ("val")) != 0) {
811 sscanf (prop->value().c_str(), "%x", &x);
812 input_auto_connect = AutoConnectOption (x);
816 if ((child = find_named_node (node, "output-auto-connect")) != 0) {
817 if ((prop = child->property ("val")) != 0) {
818 sscanf (prop->value().c_str(), "%x", &x);
819 output_auto_connect = AutoConnectOption (x);
823 if ((child = find_named_node (node, "slave")) != 0) {
824 if ((prop = child->property ("type")) != 0) {
825 if (prop->value() == "none") {
827 } else if (prop->value() == "mtc") {
829 } else if (prop->value() == "jack") {
832 set_slave_source (slave_src, 0);
836 /* we cannot set edit mode if we are loading a session,
837 because it might destroy the playlist's positioning
840 if ((child = find_named_node (node, "edit-mode")) != 0) {
841 if ((prop = child->property ("val")) != 0) {
842 if (prop->value() == "slide") {
843 pending_edit_mode = Slide;
844 } else if (prop->value() == "splice") {
845 pending_edit_mode = Splice;
850 if ((child = find_named_node (node, "send-midi-timecode")) != 0) {
851 if ((prop = child->property ("val")) != 0) {
852 bool x = (prop->value() == "yes");
853 send_mtc = !x; /* force change in value */
857 if ((child = find_named_node (node, "send-midi-machine-control")) != 0) {
858 if ((prop = child->property ("val")) != 0) {
859 bool x = (prop->value() == "yes");
860 send_mmc = !x; /* force change in value */
861 set_send_mmc (prop->value() == "yes");
864 if ((child = find_named_node (node, "max-level")) != 0) {
865 if ((prop = child->property ("val")) != 0) {
866 max_level = atoi (prop->value().c_str());
869 if ((child = find_named_node (node, "min-level")) != 0) {
870 if ((prop = child->property ("val")) != 0) {
871 min_level = atoi (prop->value().c_str());
874 if ((child = find_named_node (node, "meter-hold")) != 0) {
875 if ((prop = child->property ("val")) != 0) {
876 _meter_hold = atof (prop->value().c_str());
879 if ((child = find_named_node (node, "meter-falloff")) != 0) {
880 if ((prop = child->property ("val")) != 0) {
881 _meter_falloff = atof (prop->value().c_str());
884 if ((child = find_named_node (node, "long-over-length")) != 0) {
885 if ((prop = child->property ("val")) != 0) {
886 over_length_long = atoi (prop->value().c_str());
889 if ((child = find_named_node (node, "short-over-length")) != 0) {
890 if ((prop = child->property ("val")) != 0) {
891 over_length_short = atoi (prop->value().c_str());
894 if ((child = find_named_node (node, "shuttle-speed-factor")) != 0) {
895 if ((prop = child->property ("val")) != 0) {
896 shuttle_speed_factor = atof (prop->value().c_str());
899 if ((child = find_named_node (node, "shuttle-speed-threshold")) != 0) {
900 if ((prop = child->property ("val")) != 0) {
901 shuttle_speed_threshold = atof (prop->value().c_str());
904 if ((child = find_named_node (node, "rf-speed")) != 0) {
905 if ((prop = child->property ("val")) != 0) {
906 rf_speed = atof (prop->value().c_str());
909 if ((child = find_named_node (node, "smpte-frames-per-second")) != 0) {
910 if ((prop = child->property ("val")) != 0) {
911 set_smpte_type( atof (prop->value().c_str()), smpte_drop_frames );
914 if ((child = find_named_node (node, "smpte-drop-frames")) != 0) {
915 if ((prop = child->property ("val")) != 0) {
916 set_smpte_type( smpte_frames_per_second, (prop->value() == "yes") );
919 if ((child = find_named_node (node, "smpte-offset")) != 0) {
920 if ((prop = child->property ("val")) != 0) {
921 set_smpte_offset( atoi (prop->value().c_str()) );
924 if ((child = find_named_node (node, "smpte-offset-negative")) != 0) {
925 if ((prop = child->property ("val")) != 0) {
926 set_smpte_offset_negative( (prop->value() == "yes") );
929 if ((child = find_named_node (node, "click-sound")) != 0) {
930 if ((prop = child->property ("val")) != 0) {
931 click_sound = prop->value();
934 if ((child = find_named_node (node, "click-emphasis-sound")) != 0) {
935 if ((prop = child->property ("val")) != 0) {
936 click_emphasis_sound = prop->value();
940 if ((child = find_named_node (node, "solo-model")) != 0) {
941 if ((prop = child->property ("val")) != 0) {
942 if (prop->value() == "SoloBus")
943 _solo_model = SoloBus;
945 _solo_model = InverseMute;
949 /* BOOLEAN OPTIONS */
951 if ((child = find_named_node (node, "auto-play")) != 0) {
952 if ((prop = child->property ("val")) != 0) {
953 set_auto_play (prop->value() == "yes");
956 if ((child = find_named_node (node, "auto-input")) != 0) {
957 if ((prop = child->property ("val")) != 0) {
958 set_auto_input (prop->value() == "yes");
961 if ((child = find_named_node (node, "seamless-loop")) != 0) {
962 if ((prop = child->property ("val")) != 0) {
963 set_seamless_loop (prop->value() == "yes");
966 if ((child = find_named_node (node, "punch-in")) != 0) {
967 if ((prop = child->property ("val")) != 0) {
968 set_punch_in (prop->value() == "yes");
971 if ((child = find_named_node (node, "punch-out")) != 0) {
972 if ((prop = child->property ("val")) != 0) {
973 set_punch_out (prop->value() == "yes");
976 if ((child = find_named_node (node, "auto-return")) != 0) {
977 if ((prop = child->property ("val")) != 0) {
978 set_auto_return (prop->value() == "yes");
981 if ((child = find_named_node (node, "send-mtc")) != 0) {
982 if ((prop = child->property ("val")) != 0) {
983 set_send_mtc (prop->value() == "yes");
986 if ((child = find_named_node (node, "mmc-control")) != 0) {
987 if ((prop = child->property ("val")) != 0) {
988 set_mmc_control (prop->value() == "yes");
991 if ((child = find_named_node (node, "midi-control")) != 0) {
992 if ((prop = child->property ("val")) != 0) {
993 set_midi_control (prop->value() == "yes");
996 if ((child = find_named_node (node, "midi-feedback")) != 0) {
997 if ((prop = child->property ("val")) != 0) {
998 set_midi_feedback (prop->value() == "yes");
1001 // Legacy support for <recording-plugins>
1002 if ((child = find_named_node (node, "recording-plugins")) != 0) {
1003 if ((prop = child->property ("val")) != 0) {
1004 set_do_not_record_plugins (prop->value() == "no");
1007 if ((child = find_named_node (node, "do-not-record-plugins")) != 0) {
1008 if ((prop = child->property ("val")) != 0) {
1009 set_do_not_record_plugins (prop->value() == "yes");
1012 if ((child = find_named_node (node, "crossfades-active")) != 0) {
1013 if ((prop = child->property ("val")) != 0) {
1014 set_crossfades_active (prop->value() == "yes");
1017 if ((child = find_named_node (node, "audible-click")) != 0) {
1018 if ((prop = child->property ("val")) != 0) {
1019 set_clicking (prop->value() == "yes");
1023 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
1024 if ((prop = child->property ("val")) != 0) {
1025 _end_location_is_free = (prop->value() == "yes");
1029 if ((child = find_named_node (node, "layer-model")) != 0) {
1030 if ((prop = child->property ("val")) != 0) {
1031 if (prop->value() == X_("LaterHigher")) {
1032 set_layer_model (LaterHigher);
1033 } else if (prop->value() == X_("AddHigher")) {
1034 set_layer_model (AddHigher);
1036 set_layer_model (MoveAddHigher);
1041 if ((child = find_named_node (node, "xfade-model")) != 0) {
1042 if ((prop = child->property ("val")) != 0) {
1043 if (prop->value() == X_("Short")) {
1044 set_xfade_model (ShortCrossfade);
1046 set_xfade_model (FullCrossfade);
1051 if ((child = find_named_node (node, "short-xfade-length")) != 0) {
1052 if ((prop = child->property ("val")) != 0) {
1053 /* value is stored as a fractional seconds */
1054 float secs = atof (prop->value().c_str());
1055 Crossfade::set_short_xfade_length ((jack_nframes_t) floor (secs * frame_rate()));
1059 if ((child = find_named_node (node, "full-xfades-unmuted")) != 0) {
1060 if ((prop = child->property ("val")) != 0) {
1061 crossfades_active = (prop->value() == "yes");
1067 if ((child = find_named_node (node, "default-fade-steepness")) != 0) {
1068 if ((prop = child->property ("val")) != 0) {
1069 fade_steepness = atof (prop->value().c_str());
1070 have_fade_steepness = true;
1073 if ((child = find_named_node (node, "default-fade-msec")) != 0) {
1074 if ((prop = child->property ("val")) != 0) {
1075 fade_msecs = atof (prop->value().c_str());
1076 have_fade_msecs = true;
1080 if (have_fade_steepness || have_fade_msecs) {
1081 // set_default_fade (fade_steepness, fade_msecs);
1088 Session::get_options () const
1093 LocaleGuard lg (X_("POSIX"));
1095 opthead = new XMLNode ("Options");
1097 SlaveSource src = slave_source ();
1101 src_string = "none";
1107 src_string = "jack";
1110 child = opthead->add_child ("slave");
1111 child->add_property ("type", src_string);
1113 child = opthead->add_child ("send-midi-timecode");
1114 child->add_property ("val", send_midi_timecode?"yes":"no");
1116 child = opthead->add_child ("send-midi-machine-control");
1117 child->add_property ("val", send_midi_machine_control?"yes":"no");
1119 snprintf (buf, sizeof(buf)-1, "%x", (int) input_auto_connect);
1120 child = opthead->add_child ("input-auto-connect");
1121 child->add_property ("val", buf);
1123 snprintf (buf, sizeof(buf)-1, "%x", (int) output_auto_connect);
1124 child = opthead->add_child ("output-auto-connect");
1125 child->add_property ("val", buf);
1127 snprintf (buf, sizeof(buf)-1, "%d", max_level);
1128 child = opthead->add_child ("max-level");
1129 child->add_property ("val", buf);
1131 snprintf (buf, sizeof(buf)-1, "%d", min_level);
1132 child = opthead->add_child ("min-level");
1133 child->add_property ("val", buf);
1135 snprintf (buf, sizeof(buf)-1, "%f", _meter_hold);
1136 child = opthead->add_child ("meter-hold");
1137 child->add_property ("val", buf);
1139 snprintf (buf, sizeof(buf)-1, "%f", _meter_falloff);
1140 child = opthead->add_child ("meter-falloff");
1141 child->add_property ("val", buf);
1143 snprintf (buf, sizeof(buf)-1, "%u", over_length_long);
1144 child = opthead->add_child ("long-over-length");
1145 child->add_property ("val", buf);
1147 snprintf (buf, sizeof(buf)-1, "%u", over_length_short);
1148 child = opthead->add_child ("short-over-length");
1149 child->add_property ("val", buf);
1151 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_factor);
1152 child = opthead->add_child ("shuttle-speed-factor");
1153 child->add_property ("val", buf);
1155 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_threshold);
1156 child = opthead->add_child ("shuttle-speed-threshold");
1157 child->add_property ("val", buf);
1159 snprintf (buf, sizeof(buf)-1, "%f", rf_speed);
1160 child = opthead->add_child ("rf-speed");
1161 child->add_property ("val", buf);
1163 snprintf (buf, sizeof(buf)-1, "%.2f", smpte_frames_per_second);
1164 child = opthead->add_child ("smpte-frames-per-second");
1165 child->add_property ("val", buf);
1167 child = opthead->add_child ("smpte-drop-frames");
1168 child->add_property ("val", smpte_drop_frames ? "yes" : "no");
1170 snprintf (buf, sizeof(buf)-1, "%u", smpte_offset ());
1171 child = opthead->add_child ("smpte-offset");
1172 child->add_property ("val", buf);
1174 child = opthead->add_child ("smpte-offset-negative");
1175 child->add_property ("val", smpte_offset_negative () ? "yes" : "no");
1177 child = opthead->add_child ("edit-mode");
1178 switch (_edit_mode) {
1180 child->add_property ("val", "splice");
1184 child->add_property ("val", "slide");
1188 child = opthead->add_child ("auto-play");
1189 child->add_property ("val", get_auto_play () ? "yes" : "no");
1190 child = opthead->add_child ("auto-input");
1191 child->add_property ("val", get_auto_input () ? "yes" : "no");
1192 child = opthead->add_child ("seamless-loop");
1193 child->add_property ("val", get_seamless_loop () ? "yes" : "no");
1194 child = opthead->add_child ("punch-in");
1195 child->add_property ("val", get_punch_in () ? "yes" : "no");
1196 child = opthead->add_child ("punch-out");
1197 child->add_property ("val", get_punch_out () ? "yes" : "no");
1198 child = opthead->add_child ("all-safe");
1199 child->add_property ("val", get_all_safe () ? "yes" : "no");
1200 child = opthead->add_child ("auto-return");
1201 child->add_property ("val", get_auto_return () ? "yes" : "no");
1202 child = opthead->add_child ("mmc-control");
1203 child->add_property ("val", get_mmc_control () ? "yes" : "no");
1204 child = opthead->add_child ("midi-control");
1205 child->add_property ("val", get_midi_control () ? "yes" : "no");
1206 child = opthead->add_child ("midi-feedback");
1207 child->add_property ("val", get_midi_feedback () ? "yes" : "no");
1208 child = opthead->add_child ("do-not-record-plugins");
1209 child->add_property ("val", get_do_not_record_plugins () ? "yes" : "no");
1210 child = opthead->add_child ("auto-crossfade");
1211 child->add_property ("val", get_crossfades_active () ? "yes" : "no");
1212 child = opthead->add_child ("audible-click");
1213 child->add_property ("val", get_clicking () ? "yes" : "no");
1214 child = opthead->add_child ("end-marker-is-free");
1215 child->add_property ("val", _end_location_is_free ? "yes" : "no");
1217 if (click_sound.length()) {
1218 child = opthead->add_child ("click-sound");
1219 child->add_property ("val", click_sound);
1222 if (click_emphasis_sound.length()) {
1223 child = opthead->add_child ("click-emphasis-sound");
1224 child->add_property ("val", click_emphasis_sound);
1227 child = opthead->add_child ("solo-model");
1228 child->add_property ("val", _solo_model == SoloBus ? "SoloBus" : "InverseMute");
1230 child = opthead->add_child ("layer-model");
1231 switch (layer_model) {
1233 child->add_property ("val", X_("LaterHigher"));
1236 child->add_property ("val", X_("MoveAddHigher"));
1239 child->add_property ("val", X_("AddHigher"));
1243 child = opthead->add_child ("xfade-model");
1244 switch (xfade_model) {
1246 child->add_property ("val", X_("Full"));
1248 case ShortCrossfade:
1249 child->add_property ("val", X_("Short"));
1252 child = opthead->add_child ("short-xfade-length");
1253 /* store as fractions of a second */
1254 snprintf (buf, sizeof(buf)-1, "%f",
1255 (float) Crossfade::short_xfade_length() / frame_rate());
1256 child->add_property ("val", buf);
1258 child = opthead->add_child ("full-xfades-unmuted");
1259 child->add_property ("val", crossfades_active ? "yes" : "no");
1265 Session::get_state()
1271 Session::get_template()
1273 /* if we don't disable rec-enable, diskstreams
1274 will believe they need to store their capture
1275 sources in their state node.
1278 disable_record (false);
1280 return state(false);
1284 Session::state(bool full_state)
1286 XMLNode* node = new XMLNode("Session");
1289 // store libardour version, just in case
1291 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
1292 libardour_major_version, libardour_minor_version, libardour_micro_version);
1293 node->add_property("version", string(buf));
1295 /* store configuration settings */
1299 /* store the name */
1300 node->add_property ("name", _name);
1302 if (session_dirs.size() > 1) {
1306 vector<space_and_path>::iterator i = session_dirs.begin();
1307 vector<space_and_path>::iterator next;
1309 ++i; /* skip the first one */
1313 while (i != session_dirs.end()) {
1317 if (next != session_dirs.end()) {
1327 child = node->add_child ("Path");
1328 child->add_content (p);
1332 node->add_child_nocopy (get_options());
1334 child = node->add_child ("Sources");
1337 LockMonitor sl (source_lock, __LINE__, __FILE__);
1339 for (SourceList::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1341 /* Don't save information about FileSources that are empty */
1345 if ((fs = dynamic_cast<FileSource*> ((*siter).second)) != 0) {
1346 DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
1348 /* destructive file sources are OK if they are empty, because
1349 we will re-use them every time.
1353 if (fs->length() == 0) {
1359 child->add_child_nocopy ((*siter).second->get_state());
1363 child = node->add_child ("Regions");
1366 LockMonitor rl (region_lock, __LINE__, __FILE__);
1368 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1370 /* only store regions not attached to playlists */
1372 if ((*i).second->playlist() == 0) {
1373 child->add_child_nocopy (i->second->state (true));
1378 child = node->add_child ("DiskStreams");
1381 RWLockMonitor dl (diskstream_lock, false, __LINE__, __FILE__);
1382 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1383 if (!(*i)->hidden()) {
1384 child->add_child_nocopy ((*i)->get_state());
1389 node->add_child_nocopy (_locations.get_state());
1391 child = node->add_child ("Connections");
1393 LockMonitor lm (connection_lock, __LINE__, __FILE__);
1394 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1395 if (!(*i)->system_dependent()) {
1396 child->add_child_nocopy ((*i)->get_state());
1401 child = node->add_child ("Routes");
1403 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1405 RoutePublicOrderSorter cmp;
1406 RouteList public_order(routes);
1407 public_order.sort (cmp);
1409 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1410 if (!(*i)->hidden()) {
1412 child->add_child_nocopy ((*i)->get_state());
1414 child->add_child_nocopy ((*i)->get_template());
1421 child = node->add_child ("EditGroups");
1422 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1423 child->add_child_nocopy ((*i)->get_state());
1426 child = node->add_child ("MixGroups");
1427 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1428 child->add_child_nocopy ((*i)->get_state());
1431 child = node->add_child ("Playlists");
1432 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1433 if (!(*i)->hidden()) {
1434 if (!(*i)->empty()) {
1436 child->add_child_nocopy ((*i)->get_state());
1438 child->add_child_nocopy ((*i)->get_template());
1444 child = node->add_child ("UnusedPlaylists");
1445 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1446 if (!(*i)->hidden()) {
1447 if (!(*i)->empty()) {
1449 child->add_child_nocopy ((*i)->get_state());
1451 child->add_child_nocopy ((*i)->get_template());
1459 child = node->add_child ("Click");
1460 child->add_child_nocopy (_click_io->state (full_state));
1464 child = node->add_child ("NamedSelections");
1465 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1467 child->add_child_nocopy ((*i)->get_state());
1472 node->add_child_nocopy (_tempo_map->get_state());
1475 node->add_child_copy (*_extra_xml);
1482 Session::set_state (const XMLNode& node)
1486 const XMLProperty* prop;
1489 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1491 if (node.name() != "Session"){
1492 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1496 StateManager::prohibit_save ();
1498 if ((prop = node.property ("name")) != 0) {
1499 _name = prop->value ();
1502 IO::disable_ports ();
1503 IO::disable_connecting ();
1505 /* Object loading order:
1522 if (use_config_midi_ports ()) {
1525 if ((child = find_named_node (node, "Path")) != 0) {
1526 /* XXX this XML content stuff horrible API design */
1527 string raid_path = _path + ':' + child->children().front()->content();
1528 setup_raid_path (raid_path);
1530 /* the path is already set */
1533 if ((child = find_named_node (node, "extra")) != 0) {
1534 _extra_xml = new XMLNode (*child);
1537 if ((child = find_named_node (node, "Options")) == 0) {
1538 error << _("Session: XML state has no options section") << endmsg;
1539 } else if (load_options (*child)) {
1542 if ((child = find_named_node (node, "Sources")) == 0) {
1543 error << _("Session: XML state has no sources section") << endmsg;
1545 } else if (load_sources (*child)) {
1549 if ((child = find_named_node (node, "Regions")) == 0) {
1550 error << _("Session: XML state has no Regions section") << endmsg;
1552 } else if (load_regions (*child)) {
1556 if ((child = find_named_node (node, "Playlists")) == 0) {
1557 error << _("Session: XML state has no playlists section") << endmsg;
1559 } else if (load_playlists (*child)) {
1563 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1565 } else if (load_unused_playlists (*child)) {
1569 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1570 if (load_named_selections (*child)) {
1575 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1576 error << _("Session: XML state has no diskstreams section") << endmsg;
1578 } else if (load_diskstreams (*child)) {
1582 if ((child = find_named_node (node, "Connections")) == 0) {
1583 error << _("Session: XML state has no connections section") << endmsg;
1585 } else if (load_connections (*child)) {
1589 if ((child = find_named_node (node, "Locations")) == 0) {
1590 error << _("Session: XML state has no locations section") << endmsg;
1592 } else if (_locations.set_state (*child)) {
1598 if ((location = _locations.auto_loop_location()) != 0) {
1599 set_auto_loop_location (location);
1602 if ((location = _locations.auto_punch_location()) != 0) {
1603 set_auto_punch_location (location);
1606 if ((location = _locations.end_location()) == 0) {
1607 _locations.add (end_location);
1609 delete end_location;
1610 end_location = location;
1613 if ((location = _locations.start_location()) == 0) {
1614 _locations.add (start_location);
1616 delete start_location;
1617 start_location = location;
1620 _locations.save_state (_("initial state"));
1622 if ((child = find_named_node (node, "EditGroups")) == 0) {
1623 error << _("Session: XML state has no edit groups section") << endmsg;
1625 } else if (load_edit_groups (*child)) {
1629 if ((child = find_named_node (node, "MixGroups")) == 0) {
1630 error << _("Session: XML state has no mix groups section") << endmsg;
1632 } else if (load_mix_groups (*child)) {
1636 if ((child = find_named_node (node, "TempoMap")) == 0) {
1637 error << _("Session: XML state has no Tempo Map section") << endmsg;
1639 } else if (_tempo_map->set_state (*child)) {
1643 if ((child = find_named_node (node, "Routes")) == 0) {
1644 error << _("Session: XML state has no routes section") << endmsg;
1646 } else if (load_routes (*child)) {
1650 if ((child = find_named_node (node, "Click")) == 0) {
1651 warning << _("Session: XML state has no click section") << endmsg;
1652 } else if (_click_io) {
1653 _click_io->set_state (*child);
1656 /* OK, now we can set edit mode */
1658 set_edit_mode (pending_edit_mode);
1660 /* here beginneth the second phase ... */
1662 StateReady (); /* EMIT SIGNAL */
1664 _state_of_the_state = Clean;
1666 StateManager::allow_save (_("initial state"), true);
1668 if (state_was_pending) {
1669 save_state (_current_snapshot_name);
1670 remove_pending_capture_state ();
1671 state_was_pending = false;
1677 /* we failed, re-enable state saving but don't actually save internal state */
1678 StateManager::allow_save (X_("ignored"), false);
1683 Session::load_routes (const XMLNode& node)
1686 XMLNodeConstIterator niter;
1689 nlist = node.children();
1693 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1695 if ((route = XMLRouteFactory (**niter)) == 0) {
1696 error << _("Session: cannot create Route from XML description.") << endmsg;
1707 Session::XMLRouteFactory (const XMLNode& node)
1709 if (node.name() != "Route") {
1713 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1714 return new AudioTrack (*this, node);
1716 return new Route (*this, node);
1721 Session::load_regions (const XMLNode& node)
1724 XMLNodeConstIterator niter;
1725 AudioRegion* region;
1727 nlist = node.children();
1731 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1733 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1734 error << _("Session: cannot create Region from XML description.") << endmsg;
1742 Session::XMLRegionFactory (const XMLNode& node, bool full)
1744 const XMLProperty* prop;
1747 AudioRegion::SourceList sources;
1748 uint32_t nchans = 1;
1751 if (node.name() != X_("Region")) {
1755 if ((prop = node.property (X_("channels"))) != 0) {
1756 nchans = atoi (prop->value().c_str());
1760 if ((prop = node.property (X_("source-0"))) == 0) {
1761 if ((prop = node.property ("source")) == 0) {
1762 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1767 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1769 if ((source = get_source (s_id)) == 0) {
1770 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1774 sources.push_back(source);
1776 /* pickup other channels */
1778 for (uint32_t n=1; n < nchans; ++n) {
1779 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1780 if ((prop = node.property (buf)) != 0) {
1781 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1783 if ((source = get_source (s_id)) == 0) {
1784 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1787 sources.push_back(source);
1793 return new AudioRegion (sources, node);
1796 catch (failed_constructor& err) {
1802 Session::get_sources_as_xml ()
1805 XMLNode* node = new XMLNode (X_("Sources"));
1806 LockMonitor lm (source_lock, __LINE__, __FILE__);
1808 for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
1809 node->add_child_nocopy ((*i).second->get_state());
1816 Session::path_from_region_name (string name, string identifier)
1818 char buf[PATH_MAX+1];
1820 string dir = discover_best_sound_dir ();
1822 for (n = 0; n < 999999; ++n) {
1823 if (identifier.length()) {
1824 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1825 identifier.c_str(), n);
1827 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1829 if (access (buf, F_OK) != 0) {
1839 Session::load_sources (const XMLNode& node)
1842 XMLNodeConstIterator niter;
1845 nlist = node.children();
1849 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1851 if ((source = XMLSourceFactory (**niter)) == 0) {
1852 error << _("Session: cannot create Source from XML description.") << endmsg;
1860 Session::XMLSourceFactory (const XMLNode& node)
1864 if (node.name() != "Source") {
1869 if (node.property (X_("destructive")) != 0) {
1870 src = new DestructiveFileSource (node, frame_rate());
1872 src = new FileSource (node, frame_rate());
1876 catch (failed_constructor& err) {
1879 src = ExternalSource::create (node);
1882 catch (failed_constructor& err) {
1883 error << _("Found a sound file that cannot be used by Ardour. See the progammers.") << endmsg;
1892 Session::save_template (string template_name)
1895 string xml_path, bak_path, template_path;
1897 if (_state_of_the_state & CannotSave) {
1902 string dir = template_dir();
1904 if ((dp = opendir (dir.c_str()))) {
1907 if (mkdir (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)<0) {
1908 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1913 tree.set_root (&get_template());
1916 xml_path += template_name;
1917 xml_path += _template_suffix;
1919 ifstream in(xml_path.c_str());
1922 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1928 if (!tree.write (xml_path)) {
1929 error << _("mix template not saved") << endmsg;
1937 Session::rename_template (string old_name, string new_name)
1939 string old_path = template_dir() + old_name + _template_suffix;
1940 string new_path = template_dir() + new_name + _template_suffix;
1942 return rename (old_path.c_str(), new_path.c_str());
1946 Session::delete_template (string name)
1948 string template_path = template_dir();
1949 template_path += name;
1950 template_path += _template_suffix;
1952 return remove (template_path.c_str());
1956 Session::refresh_disk_space ()
1959 struct statfs statfsbuf;
1960 vector<space_and_path>::iterator i;
1961 LockMonitor lm (space_lock, __LINE__, __FILE__);
1964 /* get freespace on every FS that is part of the session path */
1966 _total_free_4k_blocks = 0;
1968 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1969 statfs ((*i).path.c_str(), &statfsbuf);
1971 scale = statfsbuf.f_bsize/4096.0;
1973 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1974 _total_free_4k_blocks += (*i).blocks;
1980 Session::ensure_sound_dir (string path, string& result)
1985 /* Ensure that the parent directory exists */
1987 if (mkdir (path.c_str(), 0775)) {
1988 if (errno != EEXIST) {
1989 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1994 /* Ensure that the sounds directory exists */
1998 result += sound_dir_name;
2000 if (mkdir (result.c_str(), 0775)) {
2001 if (errno != EEXIST) {
2002 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
2009 dead += dead_sound_dir_name;
2011 if (mkdir (dead.c_str(), 0775)) {
2012 if (errno != EEXIST) {
2013 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
2020 peak += peak_dir_name;
2022 if (mkdir (peak.c_str(), 0775)) {
2023 if (errno != EEXIST) {
2024 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
2029 /* callers expect this to be terminated ... */
2036 Session::discover_best_sound_dir (bool destructive)
2038 vector<space_and_path>::iterator i;
2041 /* destructive files all go into the same place */
2047 /* handle common case without system calls */
2049 if (session_dirs.size() == 1) {
2053 /* OK, here's the algorithm we're following here:
2055 We want to select which directory to use for
2056 the next file source to be created. Ideally,
2057 we'd like to use a round-robin process so as to
2058 get maximum performance benefits from splitting
2059 the files across multiple disks.
2061 However, in situations without much diskspace, an
2062 RR approach may end up filling up a filesystem
2063 with new files while others still have space.
2064 Its therefore important to pay some attention to
2065 the freespace in the filesystem holding each
2066 directory as well. However, if we did that by
2067 itself, we'd keep creating new files in the file
2068 system with the most space until it was as full
2069 as all others, thus negating any performance
2070 benefits of this RAID-1 like approach.
2072 So, we use a user-configurable space threshold. If
2073 there are at least 2 filesystems with more than this
2074 much space available, we use RR selection between them.
2075 If not, then we pick the filesystem with the most space.
2077 This gets a good balance between the two
2081 refresh_disk_space ();
2083 int free_enough = 0;
2085 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2086 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2091 if (free_enough >= 2) {
2093 bool found_it = false;
2095 /* use RR selection process, ensuring that the one
2099 i = last_rr_session_dir;
2102 if (++i == session_dirs.end()) {
2103 i = session_dirs.begin();
2106 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2107 if (ensure_sound_dir ((*i).path, result) == 0) {
2108 last_rr_session_dir = i;
2114 } while (i != last_rr_session_dir);
2117 result = sound_dir();
2122 /* pick FS with the most freespace (and that
2123 seems to actually work ...)
2126 vector<space_and_path> sorted;
2127 space_and_path_ascending_cmp cmp;
2129 sorted = session_dirs;
2130 sort (sorted.begin(), sorted.end(), cmp);
2132 for (i = sorted.begin(); i != sorted.end(); ++i) {
2133 if (ensure_sound_dir ((*i).path, result) == 0) {
2134 last_rr_session_dir = i;
2139 /* if the above fails, fall back to the most simplistic solution */
2141 if (i == sorted.end()) {
2150 Session::load_playlists (const XMLNode& node)
2153 XMLNodeConstIterator niter;
2156 nlist = node.children();
2160 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2162 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2163 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2171 Session::load_unused_playlists (const XMLNode& node)
2174 XMLNodeConstIterator niter;
2177 nlist = node.children();
2181 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2183 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2184 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2188 // now manually untrack it
2190 track_playlist (playlist, false);
2198 Session::XMLPlaylistFactory (const XMLNode& node)
2201 return new AudioPlaylist (*this, node);
2204 catch (failed_constructor& err) {
2210 Session::load_named_selections (const XMLNode& node)
2213 XMLNodeConstIterator niter;
2216 nlist = node.children();
2220 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2222 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2223 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2231 Session::XMLNamedSelectionFactory (const XMLNode& node)
2234 return new NamedSelection (*this, node);
2237 catch (failed_constructor& err) {
2243 Session::dead_sound_dir () const
2246 res += dead_sound_dir_name;
2252 Session::sound_dir () const
2255 res += sound_dir_name;
2261 Session::tape_dir () const
2264 res += tape_dir_name;
2270 Session::peak_dir () const
2273 res += peak_dir_name;
2279 Session::automation_dir () const
2282 res += "automation/";
2287 Session::template_dir ()
2289 string path = get_user_ardour_path();
2290 path += "templates/";
2296 Session::suffixed_search_path (string suffix, bool data)
2300 path += get_user_ardour_path();
2301 if (path[path.length()-1] != ':') {
2306 path += get_system_data_path();
2308 path += get_system_module_path();
2311 vector<string> split_path;
2313 split (path, split_path, ':');
2316 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2321 if (distance (i, split_path.end()) != 1) {
2330 Session::template_path ()
2332 return suffixed_search_path (X_("templates"), true);
2336 Session::control_protocol_path ()
2338 return suffixed_search_path (X_("surfaces"), false);
2342 Session::load_connections (const XMLNode& node)
2344 XMLNodeList nlist = node.children();
2345 XMLNodeConstIterator niter;
2349 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2350 if ((*niter)->name() == "InputConnection") {
2351 add_connection (new ARDOUR::InputConnection (**niter));
2352 } else if ((*niter)->name() == "OutputConnection") {
2353 add_connection (new ARDOUR::OutputConnection (**niter));
2355 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2364 Session::load_edit_groups (const XMLNode& node)
2366 return load_route_groups (node, true);
2370 Session::load_mix_groups (const XMLNode& node)
2372 return load_route_groups (node, false);
2376 Session::load_route_groups (const XMLNode& node, bool edit)
2378 XMLNodeList nlist = node.children();
2379 XMLNodeConstIterator niter;
2384 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2385 if ((*niter)->name() == "RouteGroup") {
2387 rg = add_edit_group ("");
2388 rg->set_state (**niter);
2390 rg = add_mix_group ("");
2391 rg->set_state (**niter);
2400 Session::swap_configuration(Configuration** new_config)
2402 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__); // jlc - WHY?
2403 Configuration* tmp = *new_config;
2404 *new_config = Config;
2410 Session::copy_configuration(Configuration* new_config)
2412 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
2413 new_config = new Configuration(*Config);
2417 state_file_filter (const string &str, void *arg)
2419 return (str.length() > strlen(Session::statefile_suffix()) &&
2420 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2424 bool operator()(const string* a, const string* b) {
2430 remove_end(string* state)
2432 string statename(*state);
2434 string::size_type start,end;
2435 if ((start = statename.find_last_of ('/')) != string::npos) {
2436 statename = statename.substr (start+1);
2439 if ((end = statename.rfind(".ardour")) < 0) {
2440 end = statename.length();
2443 return new string(statename.substr (0, end));
2447 Session::possible_states (string path)
2449 PathScanner scanner;
2450 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2452 transform(states->begin(), states->end(), states->begin(), remove_end);
2455 sort (states->begin(), states->end(), cmp);
2461 Session::possible_states () const
2463 return possible_states(_path);
2467 Session::auto_save()
2469 save_state (_current_snapshot_name);
2473 Session::add_edit_group (string name)
2475 RouteGroup* rg = new RouteGroup (*this, name);
2476 edit_groups.push_back (rg);
2477 edit_group_added (rg); /* EMIT SIGNAL */
2483 Session::add_mix_group (string name)
2485 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2486 mix_groups.push_back (rg);
2487 mix_group_added (rg); /* EMIT SIGNAL */
2493 Session::remove_edit_group (RouteGroup& rg)
2495 list<RouteGroup*>::iterator i;
2497 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2498 (*i)->apply (&Route::drop_edit_group, this);
2499 edit_groups.erase (i);
2500 edit_group_removed (); /* EMIT SIGNAL */
2507 Session::remove_mix_group (RouteGroup& rg)
2509 list<RouteGroup*>::iterator i;
2511 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2512 (*i)->apply (&Route::drop_mix_group, this);
2513 mix_groups.erase (i);
2514 mix_group_removed (); /* EMIT SIGNAL */
2521 Session::mix_group_by_name (string name)
2523 list<RouteGroup *>::iterator i;
2525 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2526 if ((*i)->name() == name) {
2534 Session::edit_group_by_name (string name)
2536 list<RouteGroup *>::iterator i;
2538 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2539 if ((*i)->name() == name) {
2547 Session::set_meter_hold (float val)
2550 MeterHoldChanged(); // emit
2554 Session::set_meter_falloff (float val)
2556 _meter_falloff = val;
2557 MeterFalloffChanged(); // emit
2562 Session::begin_reversible_command (string name, UndoAction* private_undo)
2564 current_cmd.clear ();
2565 current_cmd.set_name (name);
2568 current_cmd.add_undo (*private_undo);
2573 Session::commit_reversible_command (UndoAction* private_redo)
2578 current_cmd.add_redo_no_execute (*private_redo);
2581 gettimeofday (&now, 0);
2582 current_cmd.set_timestamp (now);
2584 history.add (current_cmd);
2587 Session::GlobalRouteBooleanState
2588 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2590 GlobalRouteBooleanState s;
2591 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2593 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2594 if (!(*i)->hidden()) {
2595 RouteBooleanState v;
2598 v.second = ((*i)->*method)();
2607 Session::GlobalRouteMeterState
2608 Session::get_global_route_metering ()
2610 GlobalRouteMeterState s;
2611 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2613 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2614 if (!(*i)->hidden()) {
2618 v.second = (*i)->meter_point();
2628 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2630 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2631 i->first->set_meter_point (i->second, arg);
2636 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2638 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2639 (i->first->*method) (i->second, arg);
2644 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2646 set_global_route_boolean (s, &Route::set_mute, src);
2650 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2652 set_global_route_boolean (s, &Route::set_solo, src);
2656 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2658 set_global_route_boolean (s, &Route::set_record_enable, src);
2662 Session::global_mute_memento (void* src)
2664 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2668 Session::global_metering_memento (void* src)
2670 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2674 Session::global_solo_memento (void* src)
2676 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2680 Session::global_record_enable_memento (void* src)
2682 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2686 template_filter (const string &str, void *arg)
2688 return (str.length() > strlen(Session::template_suffix()) &&
2689 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2693 Session::get_template_list (list<string> &template_names)
2695 vector<string *> *templates;
2696 PathScanner scanner;
2699 path = template_path ();
2701 templates = scanner (path, template_filter, 0, false, true);
2703 vector<string*>::iterator i;
2704 for (i = templates->begin(); i != templates->end(); ++i) {
2705 string fullpath = *(*i);
2708 start = fullpath.find_last_of ('/') + 1;
2709 if ((end = fullpath.find_last_of ('.')) <0) {
2710 end = fullpath.length();
2713 template_names.push_back(fullpath.substr(start, (end-start)));
2718 Session::read_favorite_dirs (FavoriteDirs & favs)
2720 string path = get_user_ardour_path();
2721 path += "/favorite_dirs";
2723 ifstream fav (path.c_str());
2728 if (errno != ENOENT) {
2729 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2740 getline(fav, newfav);
2746 favs.push_back (newfav);
2753 Session::write_favorite_dirs (FavoriteDirs & favs)
2755 string path = get_user_ardour_path();
2756 path += "/favorite_dirs";
2758 ofstream fav (path.c_str());
2764 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2765 fav << (*i) << endl;
2772 accept_all_non_peak_files (const string& path, void *arg)
2774 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2778 accept_all_state_files (const string& path, void *arg)
2780 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2784 Session::find_all_sources (string path, set<string>& result)
2789 if (!tree.read (path)) {
2793 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2798 XMLNodeConstIterator niter;
2800 nlist = node->children();
2804 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2808 if ((prop = (*niter)->property (X_("name"))) == 0) {
2812 if (prop->value()[0] == '/') {
2813 /* external file, ignore */
2817 string path = _path; /* /-terminated */
2818 path += sound_dir_name;
2820 path += prop->value();
2822 result.insert (path);
2829 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2831 PathScanner scanner;
2832 vector<string*>* state_files;
2834 string this_snapshot_path;
2840 if (ripped[ripped.length()-1] == '/') {
2841 ripped = ripped.substr (0, ripped.length() - 1);
2844 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2846 if (state_files == 0) {
2851 this_snapshot_path = _path;
2852 this_snapshot_path += _current_snapshot_name;
2853 this_snapshot_path += _statefile_suffix;
2855 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2857 if (exclude_this_snapshot && **i == this_snapshot_path) {
2861 if (find_all_sources (**i, result) < 0) {
2870 Session::cleanup_sources (Session::cleanup_report& rep)
2872 vector<Source*> dead_sources;
2873 vector<Playlist*> playlists_tbd;
2874 PathScanner scanner;
2876 vector<space_and_path>::iterator i;
2877 vector<space_and_path>::iterator nexti;
2878 vector<string*>* soundfiles;
2879 vector<string> unused;
2880 set<string> all_sources;
2885 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2887 /* step 1: consider deleting all unused playlists */
2889 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2892 status = AskAboutPlaylistDeletion (*x);
2901 playlists_tbd.push_back (*x);
2905 /* leave it alone */
2910 /* now delete any that were marked for deletion */
2912 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2913 PlaylistList::iterator foo;
2915 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2916 unused_playlists.erase (foo);
2921 /* step 2: clear the undo/redo history for all playlists */
2923 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2924 (*x)->drop_all_states ();
2927 /* step 3: find all un-referenced sources */
2932 for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
2934 SourceList::iterator tmp;
2939 /* only remove files that are not in use and have some size
2940 to them. otherwise we remove the current "nascent"
2944 if ((*i).second->use_cnt() == 0 && (*i).second->length() > 0) {
2945 dead_sources.push_back (i->second);
2947 /* remove this source from our own list to avoid us
2948 adding it to the list of all sources below
2957 /* Step 4: get rid of all regions in the region list that use any dead sources
2958 in case the sources themselves don't go away (they might be referenced in
2962 for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2964 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2965 AudioRegionList::iterator tmp;
2973 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2974 if (&ar->source (n) == (*i)) {
2975 /* this region is dead */
2984 /* build a list of all the possible sound directories for the session */
2986 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2991 sound_path += (*i).path;
2992 sound_path += sound_dir_name;
2994 if (nexti != session_dirs.end()) {
3001 /* now do the same thing for the files that ended up in the sounds dir(s)
3002 but are not referenced as sources in any snapshot.
3005 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
3007 if (soundfiles == 0) {
3011 /* find all sources, but don't use this snapshot because the
3012 state file on disk still references sources we may have already
3016 find_all_sources_across_snapshots (all_sources, true);
3018 /* add our current source list
3021 for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
3023 ExternalSource* sfs;
3025 if ((fs = dynamic_cast<FileSource*> ((*i).second)) != 0) {
3026 all_sources.insert (fs->path());
3027 } else if ((sfs = dynamic_cast<ExternalSource*> ((*i).second)) != 0) {
3028 all_sources.insert (sfs->path());
3032 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
3037 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
3047 unused.push_back (spath);
3051 /* now try to move all unused files into the "dead_sounds" directory(ies) */
3053 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
3054 struct stat statbuf;
3056 rep.paths.push_back (*x);
3057 if (stat ((*x).c_str(), &statbuf) == 0) {
3058 rep.space += statbuf.st_size;
3063 /* don't move the file across filesystems, just
3064 stick it in the `dead_sound_dir_name' directory
3065 on whichever filesystem it was already on.
3068 newpath = PBD::dirname (*x);
3069 newpath = PBD::dirname (newpath);
3072 newpath += dead_sound_dir_name;
3074 newpath += PBD::basename ((*x));
3076 if (access (newpath.c_str(), F_OK) == 0) {
3078 /* the new path already exists, try versioning */
3080 char buf[PATH_MAX+1];
3084 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
3087 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
3088 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
3092 if (version == 999) {
3093 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
3097 newpath = newpath_v;
3102 /* it doesn't exist, or we can't read it or something */
3106 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
3107 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
3108 (*x), newpath, strerror (errno))
3114 /* see if there an easy to find peakfile for this file, and remove it.
3117 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
3118 peakpath += ".peak";
3120 if (access (peakpath.c_str(), W_OK) == 0) {
3121 if (::unlink (peakpath.c_str()) != 0) {
3122 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3123 peakpath, _path, strerror (errno))
3125 /* try to back out */
3126 rename (newpath.c_str(), _path.c_str());
3135 /* dump the history list */
3139 /* save state so we don't end up a session file
3140 referring to non-existent sources.
3146 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3151 Session::cleanup_trash_sources (Session::cleanup_report& rep)
3153 vector<space_and_path>::iterator i;
3154 string dead_sound_dir;
3155 struct dirent* dentry;
3156 struct stat statbuf;
3162 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3164 dead_sound_dir = (*i).path;
3165 dead_sound_dir += dead_sound_dir_name;
3167 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
3171 while ((dentry = readdir (dead)) != 0) {
3173 /* avoid '.' and '..' */
3175 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
3176 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3182 fullpath = dead_sound_dir;
3184 fullpath += dentry->d_name;
3186 if (stat (fullpath.c_str(), &statbuf)) {
3190 if (!S_ISREG (statbuf.st_mode)) {
3194 if (unlink (fullpath.c_str())) {
3195 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3196 fullpath, strerror (errno))
3200 rep.paths.push_back (dentry->d_name);
3201 rep.space += statbuf.st_size;
3212 Session::set_dirty ()
3214 bool was_dirty = dirty();
3216 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3219 DirtyChanged(); /* EMIT SIGNAL */
3225 Session::set_clean ()
3227 bool was_dirty = dirty();
3229 _state_of_the_state = Clean;
3232 DirtyChanged(); /* EMIT SIGNAL */