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 _worst_output_latency = 0;
159 _worst_input_latency = 0;
160 _worst_track_latency = 0;
161 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
164 butler_mixdown_buffer = 0;
165 butler_gain_buffer = 0;
168 midi_feedback = false;
171 post_transport_work = PostTransportWork (0);
172 atomic_set (&butler_should_do_transport_work, 0);
173 atomic_set (&butler_active, 0);
174 atomic_set (&_playback_load, 100);
175 atomic_set (&_capture_load, 100);
176 atomic_set (&_playback_load_min, 100);
177 atomic_set (&_capture_load_min, 100);
178 pending_audition_region = 0;
180 pending_edit_mode = _edit_mode;
184 input_auto_connect = AutoConnectOption (0);
185 output_auto_connect = AutoConnectOption (0);
186 _have_captured = false;
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 cerr << "use pending state\n";
769 state_was_pending = true;
771 cerr << "do not use pending state\n";
775 if (!state_was_pending) {
778 xmlpath += snapshot_name;
779 xmlpath += _statefile_suffix;
782 if (access (xmlpath.c_str(), F_OK)) {
783 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
787 state_tree = new XMLTree;
791 if (state_tree->read (xmlpath)) {
794 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
803 Session::load_options (const XMLNode& node)
807 bool have_fade_msecs = false;
808 bool have_fade_steepness = false;
809 float fade_msecs = 0;
810 float fade_steepness = 0;
811 SlaveSource slave_src = None;
813 LocaleGuard lg (X_("POSIX"));
815 if ((child = find_named_node (node, "input-auto-connect")) != 0) {
816 if ((prop = child->property ("val")) != 0) {
817 sscanf (prop->value().c_str(), "%x", &x);
818 input_auto_connect = AutoConnectOption (x);
822 if ((child = find_named_node (node, "output-auto-connect")) != 0) {
823 if ((prop = child->property ("val")) != 0) {
824 sscanf (prop->value().c_str(), "%x", &x);
825 output_auto_connect = AutoConnectOption (x);
829 if ((child = find_named_node (node, "slave")) != 0) {
830 if ((prop = child->property ("type")) != 0) {
831 if (prop->value() == "none") {
833 } else if (prop->value() == "mtc") {
835 } else if (prop->value() == "jack") {
838 set_slave_source (slave_src, 0);
842 /* we cannot set edit mode if we are loading a session,
843 because it might destroy the playlist's positioning
846 if ((child = find_named_node (node, "edit-mode")) != 0) {
847 if ((prop = child->property ("val")) != 0) {
848 if (prop->value() == "slide") {
849 pending_edit_mode = Slide;
850 } else if (prop->value() == "splice") {
851 pending_edit_mode = Splice;
856 if ((child = find_named_node (node, "send-midi-timecode")) != 0) {
857 if ((prop = child->property ("val")) != 0) {
858 bool x = (prop->value() == "yes");
859 send_mtc = !x; /* force change in value */
863 if ((child = find_named_node (node, "send-midi-machine-control")) != 0) {
864 if ((prop = child->property ("val")) != 0) {
865 bool x = (prop->value() == "yes");
866 send_mmc = !x; /* force change in value */
867 set_send_mmc (prop->value() == "yes");
870 if ((child = find_named_node (node, "max-level")) != 0) {
871 if ((prop = child->property ("val")) != 0) {
872 max_level = atoi (prop->value().c_str());
875 if ((child = find_named_node (node, "min-level")) != 0) {
876 if ((prop = child->property ("val")) != 0) {
877 min_level = atoi (prop->value().c_str());
880 if ((child = find_named_node (node, "meter-hold")) != 0) {
881 if ((prop = child->property ("val")) != 0) {
882 _meter_hold = atof (prop->value().c_str());
885 if ((child = find_named_node (node, "meter-falloff")) != 0) {
886 if ((prop = child->property ("val")) != 0) {
887 _meter_falloff = atof (prop->value().c_str());
890 if ((child = find_named_node (node, "long-over-length")) != 0) {
891 if ((prop = child->property ("val")) != 0) {
892 over_length_long = atoi (prop->value().c_str());
895 if ((child = find_named_node (node, "short-over-length")) != 0) {
896 if ((prop = child->property ("val")) != 0) {
897 over_length_short = atoi (prop->value().c_str());
900 if ((child = find_named_node (node, "shuttle-speed-factor")) != 0) {
901 if ((prop = child->property ("val")) != 0) {
902 shuttle_speed_factor = atof (prop->value().c_str());
905 if ((child = find_named_node (node, "shuttle-speed-threshold")) != 0) {
906 if ((prop = child->property ("val")) != 0) {
907 shuttle_speed_threshold = atof (prop->value().c_str());
910 if ((child = find_named_node (node, "rf-speed")) != 0) {
911 if ((prop = child->property ("val")) != 0) {
912 rf_speed = atof (prop->value().c_str());
915 if ((child = find_named_node (node, "smpte-frames-per-second")) != 0) {
916 if ((prop = child->property ("val")) != 0) {
917 set_smpte_type( atof (prop->value().c_str()), smpte_drop_frames );
920 if ((child = find_named_node (node, "smpte-drop-frames")) != 0) {
921 if ((prop = child->property ("val")) != 0) {
922 set_smpte_type( smpte_frames_per_second, (prop->value() == "yes") );
925 if ((child = find_named_node (node, "smpte-offset")) != 0) {
926 if ((prop = child->property ("val")) != 0) {
927 set_smpte_offset( atoi (prop->value().c_str()) );
930 if ((child = find_named_node (node, "smpte-offset-negative")) != 0) {
931 if ((prop = child->property ("val")) != 0) {
932 set_smpte_offset_negative( (prop->value() == "yes") );
935 if ((child = find_named_node (node, "click-sound")) != 0) {
936 if ((prop = child->property ("val")) != 0) {
937 click_sound = prop->value();
940 if ((child = find_named_node (node, "click-emphasis-sound")) != 0) {
941 if ((prop = child->property ("val")) != 0) {
942 click_emphasis_sound = prop->value();
946 if ((child = find_named_node (node, "solo-model")) != 0) {
947 if ((prop = child->property ("val")) != 0) {
948 if (prop->value() == "SoloBus")
949 _solo_model = SoloBus;
951 _solo_model = InverseMute;
955 /* BOOLEAN OPTIONS */
957 if ((child = find_named_node (node, "auto-play")) != 0) {
958 if ((prop = child->property ("val")) != 0) {
959 set_auto_play (prop->value() == "yes");
962 if ((child = find_named_node (node, "auto-input")) != 0) {
963 if ((prop = child->property ("val")) != 0) {
964 set_auto_input (prop->value() == "yes");
967 if ((child = find_named_node (node, "seamless-loop")) != 0) {
968 if ((prop = child->property ("val")) != 0) {
969 set_seamless_loop (prop->value() == "yes");
972 if ((child = find_named_node (node, "punch-in")) != 0) {
973 if ((prop = child->property ("val")) != 0) {
974 set_punch_in (prop->value() == "yes");
977 if ((child = find_named_node (node, "punch-out")) != 0) {
978 if ((prop = child->property ("val")) != 0) {
979 set_punch_out (prop->value() == "yes");
982 if ((child = find_named_node (node, "auto-return")) != 0) {
983 if ((prop = child->property ("val")) != 0) {
984 set_auto_return (prop->value() == "yes");
987 if ((child = find_named_node (node, "send-mtc")) != 0) {
988 if ((prop = child->property ("val")) != 0) {
989 set_send_mtc (prop->value() == "yes");
992 if ((child = find_named_node (node, "mmc-control")) != 0) {
993 if ((prop = child->property ("val")) != 0) {
994 set_mmc_control (prop->value() == "yes");
997 if ((child = find_named_node (node, "midi-control")) != 0) {
998 if ((prop = child->property ("val")) != 0) {
999 set_midi_control (prop->value() == "yes");
1002 if ((child = find_named_node (node, "midi-feedback")) != 0) {
1003 if ((prop = child->property ("val")) != 0) {
1004 set_midi_feedback (prop->value() == "yes");
1007 // Legacy support for <recording-plugins>
1008 if ((child = find_named_node (node, "recording-plugins")) != 0) {
1009 if ((prop = child->property ("val")) != 0) {
1010 set_do_not_record_plugins (prop->value() == "no");
1013 if ((child = find_named_node (node, "do-not-record-plugins")) != 0) {
1014 if ((prop = child->property ("val")) != 0) {
1015 set_do_not_record_plugins (prop->value() == "yes");
1018 if ((child = find_named_node (node, "crossfades-active")) != 0) {
1019 if ((prop = child->property ("val")) != 0) {
1020 set_crossfades_active (prop->value() == "yes");
1023 if ((child = find_named_node (node, "audible-click")) != 0) {
1024 if ((prop = child->property ("val")) != 0) {
1025 set_clicking (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");
1215 if (click_sound.length()) {
1216 child = opthead->add_child ("click-sound");
1217 child->add_property ("val", click_sound);
1220 if (click_emphasis_sound.length()) {
1221 child = opthead->add_child ("click-emphasis-sound");
1222 child->add_property ("val", click_emphasis_sound);
1225 child = opthead->add_child ("solo-model");
1226 child->add_property ("val", _solo_model == SoloBus ? "SoloBus" : "InverseMute");
1228 child = opthead->add_child ("layer-model");
1229 switch (layer_model) {
1231 child->add_property ("val", X_("LaterHigher"));
1234 child->add_property ("val", X_("MoveAddHigher"));
1237 child->add_property ("val", X_("AddHigher"));
1241 child = opthead->add_child ("xfade-model");
1242 switch (xfade_model) {
1244 child->add_property ("val", X_("Full"));
1246 case ShortCrossfade:
1247 child->add_property ("val", X_("Short"));
1250 child = opthead->add_child ("short-xfade-length");
1251 /* store as fractions of a second */
1252 snprintf (buf, sizeof(buf)-1, "%f",
1253 (float) Crossfade::short_xfade_length() / frame_rate());
1254 child->add_property ("val", buf);
1256 child = opthead->add_child ("full-xfades-unmuted");
1257 child->add_property ("val", crossfades_active ? "yes" : "no");
1263 Session::get_state()
1269 Session::get_template()
1271 /* if we don't disable rec-enable, diskstreams
1272 will believe they need to store their capture
1273 sources in their state node.
1276 disable_record (false);
1278 return state(false);
1282 Session::state(bool full_state)
1284 XMLNode* node = new XMLNode("Session");
1287 // store libardour version, just in case
1289 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
1290 libardour_major_version, libardour_minor_version, libardour_micro_version);
1291 node->add_property("version", string(buf));
1293 /* store configuration settings */
1297 /* store the name */
1298 node->add_property ("name", _name);
1300 if (session_dirs.size() > 1) {
1304 vector<space_and_path>::iterator i = session_dirs.begin();
1305 vector<space_and_path>::iterator next;
1307 ++i; /* skip the first one */
1311 while (i != session_dirs.end()) {
1315 if (next != session_dirs.end()) {
1325 child = node->add_child ("Path");
1326 child->add_content (p);
1330 node->add_child_nocopy (get_options());
1332 child = node->add_child ("Sources");
1335 LockMonitor sl (source_lock, __LINE__, __FILE__);
1337 for (SourceList::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1339 /* Don't save information about FileSources that are empty */
1343 if ((fs = dynamic_cast<FileSource*> ((*siter).second)) != 0) {
1344 DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
1346 /* destructive file sources are OK if they are empty, because
1347 we will re-use them every time.
1351 if (fs->length() == 0) {
1357 child->add_child_nocopy ((*siter).second->get_state());
1361 child = node->add_child ("Regions");
1364 LockMonitor rl (region_lock, __LINE__, __FILE__);
1366 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1368 /* only store regions not attached to playlists */
1370 if ((*i).second->playlist() == 0) {
1371 child->add_child_nocopy (i->second->state (true));
1376 child = node->add_child ("DiskStreams");
1379 RWLockMonitor dl (diskstream_lock, false, __LINE__, __FILE__);
1380 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1381 if (!(*i)->hidden()) {
1382 child->add_child_nocopy ((*i)->get_state());
1387 node->add_child_nocopy (_locations.get_state());
1389 child = node->add_child ("Connections");
1391 LockMonitor lm (connection_lock, __LINE__, __FILE__);
1392 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1393 if (!(*i)->system_dependent()) {
1394 child->add_child_nocopy ((*i)->get_state());
1399 child = node->add_child ("Routes");
1401 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1403 RoutePublicOrderSorter cmp;
1404 RouteList public_order(routes);
1405 public_order.sort (cmp);
1407 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1408 if (!(*i)->hidden()) {
1410 child->add_child_nocopy ((*i)->get_state());
1412 child->add_child_nocopy ((*i)->get_template());
1419 child = node->add_child ("EditGroups");
1420 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1421 child->add_child_nocopy ((*i)->get_state());
1424 child = node->add_child ("MixGroups");
1425 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1426 child->add_child_nocopy ((*i)->get_state());
1429 child = node->add_child ("Playlists");
1430 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1431 if (!(*i)->hidden()) {
1432 if (!(*i)->empty()) {
1434 child->add_child_nocopy ((*i)->get_state());
1436 child->add_child_nocopy ((*i)->get_template());
1442 child = node->add_child ("UnusedPlaylists");
1443 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1444 if (!(*i)->hidden()) {
1445 if (!(*i)->empty()) {
1447 child->add_child_nocopy ((*i)->get_state());
1449 child->add_child_nocopy ((*i)->get_template());
1457 child = node->add_child ("Click");
1458 child->add_child_nocopy (_click_io->state (full_state));
1462 child = node->add_child ("NamedSelections");
1463 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1465 child->add_child_nocopy ((*i)->get_state());
1470 node->add_child_nocopy (_tempo_map->get_state());
1473 node->add_child_copy (*_extra_xml);
1480 Session::set_state (const XMLNode& node)
1484 const XMLProperty* prop;
1487 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1489 if (node.name() != "Session"){
1490 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1494 StateManager::prohibit_save ();
1496 if ((prop = node.property ("name")) != 0) {
1497 _name = prop->value ();
1500 IO::disable_ports ();
1501 IO::disable_connecting ();
1503 /* Object loading order:
1520 if (use_config_midi_ports ()) {
1523 if ((child = find_named_node (node, "Path")) != 0) {
1524 /* XXX this XML content stuff horrible API design */
1525 string raid_path = _path + ':' + child->children().front()->content();
1526 setup_raid_path (raid_path);
1528 /* the path is already set */
1531 if ((child = find_named_node (node, "extra")) != 0) {
1532 _extra_xml = new XMLNode (*child);
1535 if ((child = find_named_node (node, "Options")) == 0) {
1536 error << _("Session: XML state has no options section") << endmsg;
1537 } else if (load_options (*child)) {
1540 if ((child = find_named_node (node, "Sources")) == 0) {
1541 error << _("Session: XML state has no sources section") << endmsg;
1543 } else if (load_sources (*child)) {
1547 if ((child = find_named_node (node, "Regions")) == 0) {
1548 error << _("Session: XML state has no Regions section") << endmsg;
1550 } else if (load_regions (*child)) {
1554 if ((child = find_named_node (node, "Playlists")) == 0) {
1555 error << _("Session: XML state has no playlists section") << endmsg;
1557 } else if (load_playlists (*child)) {
1561 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1563 } else if (load_unused_playlists (*child)) {
1567 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1568 if (load_named_selections (*child)) {
1573 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1574 error << _("Session: XML state has no diskstreams section") << endmsg;
1576 } else if (load_diskstreams (*child)) {
1580 if ((child = find_named_node (node, "Connections")) == 0) {
1581 error << _("Session: XML state has no connections section") << endmsg;
1583 } else if (load_connections (*child)) {
1587 if ((child = find_named_node (node, "Locations")) == 0) {
1588 error << _("Session: XML state has no locations section") << endmsg;
1590 } else if (_locations.set_state (*child)) {
1596 if ((location = _locations.auto_loop_location()) != 0) {
1597 set_auto_loop_location (location);
1600 if ((location = _locations.auto_punch_location()) != 0) {
1601 set_auto_punch_location (location);
1604 if ((location = _locations.end_location()) == 0) {
1605 _locations.add (end_location);
1607 delete end_location;
1608 end_location = location;
1611 if ((location = _locations.start_location()) == 0) {
1612 _locations.add (start_location);
1614 delete start_location;
1615 start_location = location;
1618 _locations.save_state (_("initial state"));
1620 if ((child = find_named_node (node, "EditGroups")) == 0) {
1621 error << _("Session: XML state has no edit groups section") << endmsg;
1623 } else if (load_edit_groups (*child)) {
1627 if ((child = find_named_node (node, "MixGroups")) == 0) {
1628 error << _("Session: XML state has no mix groups section") << endmsg;
1630 } else if (load_mix_groups (*child)) {
1634 if ((child = find_named_node (node, "TempoMap")) == 0) {
1635 error << _("Session: XML state has no Tempo Map section") << endmsg;
1637 } else if (_tempo_map->set_state (*child)) {
1641 if ((child = find_named_node (node, "Routes")) == 0) {
1642 error << _("Session: XML state has no routes section") << endmsg;
1644 } else if (load_routes (*child)) {
1648 if ((child = find_named_node (node, "Click")) == 0) {
1649 warning << _("Session: XML state has no click section") << endmsg;
1650 } else if (_click_io) {
1651 _click_io->set_state (*child);
1654 /* OK, now we can set edit mode */
1656 set_edit_mode (pending_edit_mode);
1658 /* here beginneth the second phase ... */
1660 StateReady (); /* EMIT SIGNAL */
1662 _state_of_the_state = Clean;
1664 StateManager::allow_save (_("initial state"), true);
1666 if (state_was_pending) {
1667 save_state (_current_snapshot_name);
1668 remove_pending_capture_state ();
1669 state_was_pending = false;
1675 /* we failed, re-enable state saving but don't actually save internal state */
1676 StateManager::allow_save (X_("ignored"), false);
1681 Session::load_routes (const XMLNode& node)
1684 XMLNodeConstIterator niter;
1687 nlist = node.children();
1691 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1693 if ((route = XMLRouteFactory (**niter)) == 0) {
1694 error << _("Session: cannot create Route from XML description.") << endmsg;
1705 Session::XMLRouteFactory (const XMLNode& node)
1707 if (node.name() != "Route") {
1711 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1712 return new AudioTrack (*this, node);
1714 return new Route (*this, node);
1719 Session::load_regions (const XMLNode& node)
1722 XMLNodeConstIterator niter;
1723 AudioRegion* region;
1725 nlist = node.children();
1729 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1731 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1732 error << _("Session: cannot create Region from XML description.") << endmsg;
1740 Session::XMLRegionFactory (const XMLNode& node, bool full)
1742 const XMLProperty* prop;
1745 AudioRegion::SourceList sources;
1746 uint32_t nchans = 1;
1749 if (node.name() != X_("Region")) {
1753 if ((prop = node.property (X_("channels"))) != 0) {
1754 nchans = atoi (prop->value().c_str());
1758 if ((prop = node.property (X_("source-0"))) == 0) {
1759 if ((prop = node.property ("source")) == 0) {
1760 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1765 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1767 if ((source = get_source (s_id)) == 0) {
1768 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1772 sources.push_back(source);
1774 /* pickup other channels */
1776 for (uint32_t n=1; n < nchans; ++n) {
1777 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1778 if ((prop = node.property (buf)) != 0) {
1779 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1781 if ((source = get_source (s_id)) == 0) {
1782 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1785 sources.push_back(source);
1791 return new AudioRegion (sources, node);
1794 catch (failed_constructor& err) {
1800 Session::get_sources_as_xml ()
1803 XMLNode* node = new XMLNode (X_("Sources"));
1804 LockMonitor lm (source_lock, __LINE__, __FILE__);
1806 for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
1807 node->add_child_nocopy ((*i).second->get_state());
1814 Session::path_from_region_name (string name, string identifier)
1816 char buf[PATH_MAX+1];
1818 string dir = discover_best_sound_dir ();
1820 for (n = 0; n < 999999; ++n) {
1821 if (identifier.length()) {
1822 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1823 identifier.c_str(), n);
1825 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1827 if (access (buf, F_OK) != 0) {
1837 Session::load_sources (const XMLNode& node)
1840 XMLNodeConstIterator niter;
1843 nlist = node.children();
1847 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1849 if ((source = XMLSourceFactory (**niter)) == 0) {
1850 error << _("Session: cannot create Source from XML description.") << endmsg;
1858 Session::XMLSourceFactory (const XMLNode& node)
1862 if (node.name() != "Source") {
1867 if (node.property (X_("destructive")) != 0) {
1868 src = new DestructiveFileSource (node, frame_rate());
1870 src = new FileSource (node, frame_rate());
1874 catch (failed_constructor& err) {
1877 src = ExternalSource::create (node);
1880 catch (failed_constructor& err) {
1881 error << _("Found a sound file that cannot be used by Ardour. See the progammers.") << endmsg;
1890 Session::save_template (string template_name)
1893 string xml_path, bak_path, template_path;
1895 if (_state_of_the_state & CannotSave) {
1900 string dir = template_dir();
1902 if ((dp = opendir (dir.c_str()))) {
1905 if (mkdir (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)<0) {
1906 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1911 tree.set_root (&get_template());
1914 xml_path += template_name;
1915 xml_path += _template_suffix;
1917 ifstream in(xml_path.c_str());
1920 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1926 if (!tree.write (xml_path)) {
1927 error << _("mix template not saved") << endmsg;
1935 Session::rename_template (string old_name, string new_name)
1937 string old_path = template_dir() + old_name + _template_suffix;
1938 string new_path = template_dir() + new_name + _template_suffix;
1940 return rename (old_path.c_str(), new_path.c_str());
1944 Session::delete_template (string name)
1946 string template_path = template_dir();
1947 template_path += name;
1948 template_path += _template_suffix;
1950 return remove (template_path.c_str());
1954 Session::refresh_disk_space ()
1957 struct statfs statfsbuf;
1958 vector<space_and_path>::iterator i;
1959 LockMonitor lm (space_lock, __LINE__, __FILE__);
1962 /* get freespace on every FS that is part of the session path */
1964 _total_free_4k_blocks = 0;
1966 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1967 statfs ((*i).path.c_str(), &statfsbuf);
1969 scale = statfsbuf.f_bsize/4096.0;
1971 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1972 _total_free_4k_blocks += (*i).blocks;
1978 Session::ensure_sound_dir (string path, string& result)
1983 /* Ensure that the parent directory exists */
1985 if (mkdir (path.c_str(), 0775)) {
1986 if (errno != EEXIST) {
1987 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1992 /* Ensure that the sounds directory exists */
1996 result += sound_dir_name;
1998 if (mkdir (result.c_str(), 0775)) {
1999 if (errno != EEXIST) {
2000 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
2007 dead += dead_sound_dir_name;
2009 if (mkdir (dead.c_str(), 0775)) {
2010 if (errno != EEXIST) {
2011 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
2018 peak += peak_dir_name;
2020 if (mkdir (peak.c_str(), 0775)) {
2021 if (errno != EEXIST) {
2022 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
2027 /* callers expect this to be terminated ... */
2034 Session::discover_best_sound_dir (bool destructive)
2036 vector<space_and_path>::iterator i;
2039 /* destructive files all go into the same place */
2045 /* handle common case without system calls */
2047 if (session_dirs.size() == 1) {
2051 /* OK, here's the algorithm we're following here:
2053 We want to select which directory to use for
2054 the next file source to be created. Ideally,
2055 we'd like to use a round-robin process so as to
2056 get maximum performance benefits from splitting
2057 the files across multiple disks.
2059 However, in situations without much diskspace, an
2060 RR approach may end up filling up a filesystem
2061 with new files while others still have space.
2062 Its therefore important to pay some attention to
2063 the freespace in the filesystem holding each
2064 directory as well. However, if we did that by
2065 itself, we'd keep creating new files in the file
2066 system with the most space until it was as full
2067 as all others, thus negating any performance
2068 benefits of this RAID-1 like approach.
2070 So, we use a user-configurable space threshold. If
2071 there are at least 2 filesystems with more than this
2072 much space available, we use RR selection between them.
2073 If not, then we pick the filesystem with the most space.
2075 This gets a good balance between the two
2079 refresh_disk_space ();
2081 int free_enough = 0;
2083 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2084 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2089 if (free_enough >= 2) {
2091 bool found_it = false;
2093 /* use RR selection process, ensuring that the one
2097 i = last_rr_session_dir;
2100 if (++i == session_dirs.end()) {
2101 i = session_dirs.begin();
2104 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2105 if (ensure_sound_dir ((*i).path, result) == 0) {
2106 last_rr_session_dir = i;
2112 } while (i != last_rr_session_dir);
2115 result = sound_dir();
2120 /* pick FS with the most freespace (and that
2121 seems to actually work ...)
2124 vector<space_and_path> sorted;
2125 space_and_path_ascending_cmp cmp;
2127 sorted = session_dirs;
2128 sort (sorted.begin(), sorted.end(), cmp);
2130 for (i = sorted.begin(); i != sorted.end(); ++i) {
2131 if (ensure_sound_dir ((*i).path, result) == 0) {
2132 last_rr_session_dir = i;
2137 /* if the above fails, fall back to the most simplistic solution */
2139 if (i == sorted.end()) {
2148 Session::load_playlists (const XMLNode& node)
2151 XMLNodeConstIterator niter;
2154 nlist = node.children();
2158 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2160 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2161 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2169 Session::load_unused_playlists (const XMLNode& node)
2172 XMLNodeConstIterator niter;
2175 nlist = node.children();
2179 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2181 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2182 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2186 // now manually untrack it
2188 track_playlist (playlist, false);
2196 Session::XMLPlaylistFactory (const XMLNode& node)
2199 return new AudioPlaylist (*this, node);
2202 catch (failed_constructor& err) {
2208 Session::load_named_selections (const XMLNode& node)
2211 XMLNodeConstIterator niter;
2214 nlist = node.children();
2218 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2220 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2221 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2229 Session::XMLNamedSelectionFactory (const XMLNode& node)
2232 return new NamedSelection (*this, node);
2235 catch (failed_constructor& err) {
2241 Session::dead_sound_dir () const
2244 res += dead_sound_dir_name;
2250 Session::sound_dir () const
2253 res += sound_dir_name;
2259 Session::tape_dir () const
2262 res += tape_dir_name;
2268 Session::peak_dir () const
2271 res += peak_dir_name;
2277 Session::automation_dir () const
2280 res += "automation/";
2285 Session::template_dir ()
2287 string path = get_user_ardour_path();
2288 path += "templates/";
2294 Session::template_path ()
2298 path += get_user_ardour_path();
2299 if (path[path.length()-1] != ':') {
2302 path += get_system_ardour_path();
2304 vector<string> split_path;
2306 split (path, split_path, ':');
2309 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2311 path += "templates/";
2313 if (distance (i, split_path.end()) != 1) {
2322 Session::load_connections (const XMLNode& node)
2324 XMLNodeList nlist = node.children();
2325 XMLNodeConstIterator niter;
2329 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2330 if ((*niter)->name() == "InputConnection") {
2331 add_connection (new ARDOUR::InputConnection (**niter));
2332 } else if ((*niter)->name() == "OutputConnection") {
2333 add_connection (new ARDOUR::OutputConnection (**niter));
2335 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2344 Session::load_edit_groups (const XMLNode& node)
2346 return load_route_groups (node, true);
2350 Session::load_mix_groups (const XMLNode& node)
2352 return load_route_groups (node, false);
2356 Session::load_route_groups (const XMLNode& node, bool edit)
2358 XMLNodeList nlist = node.children();
2359 XMLNodeConstIterator niter;
2364 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2365 if ((*niter)->name() == "RouteGroup") {
2367 route = add_edit_group ("");
2368 route->set_state (**niter);
2370 route = add_mix_group ("");
2371 route->set_state (**niter);
2380 Session::swap_configuration(Configuration** new_config)
2382 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__); // jlc - WHY?
2383 Configuration* tmp = *new_config;
2384 *new_config = Config;
2390 Session::copy_configuration(Configuration* new_config)
2392 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
2393 new_config = new Configuration(*Config);
2397 state_file_filter (const string &str, void *arg)
2399 return (str.length() > strlen(Session::statefile_suffix()) &&
2400 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2404 bool operator()(const string* a, const string* b) {
2410 remove_end(string* state)
2412 string statename(*state);
2414 string::size_type start,end;
2415 if ((start = statename.find_last_of ('/')) != string::npos) {
2416 statename = statename.substr (start+1);
2419 if ((end = statename.rfind(".ardour")) < 0) {
2420 end = statename.length();
2423 return new string(statename.substr (0, end));
2427 Session::possible_states (string path)
2429 PathScanner scanner;
2430 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2432 transform(states->begin(), states->end(), states->begin(), remove_end);
2435 sort (states->begin(), states->end(), cmp);
2441 Session::possible_states () const
2443 return possible_states(_path);
2447 Session::auto_save()
2449 save_state (_current_snapshot_name);
2453 Session::add_edit_group (string name)
2455 RouteGroup* rg = new RouteGroup (*this, name);
2456 edit_groups.push_back (rg);
2457 edit_group_added (rg); /* EMIT SIGNAL */
2463 Session::add_mix_group (string name)
2465 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2466 mix_groups.push_back (rg);
2467 mix_group_added (rg); /* EMIT SIGNAL */
2473 Session::remove_edit_group (RouteGroup& rg)
2475 list<RouteGroup*>::iterator i;
2477 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2478 (*i)->apply (&Route::drop_edit_group, this);
2479 edit_groups.erase (i);
2480 edit_group_removed (); /* EMIT SIGNAL */
2487 Session::remove_mix_group (RouteGroup& rg)
2489 list<RouteGroup*>::iterator i;
2491 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2492 (*i)->apply (&Route::drop_mix_group, this);
2493 mix_groups.erase (i);
2494 mix_group_removed (); /* EMIT SIGNAL */
2501 Session::mix_group_by_name (string name)
2503 list<RouteGroup *>::iterator i;
2505 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2506 if ((*i)->name() == name) {
2514 Session::edit_group_by_name (string name)
2516 list<RouteGroup *>::iterator i;
2518 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2519 if ((*i)->name() == name) {
2527 Session::set_meter_hold (float val)
2530 MeterHoldChanged(); // emit
2534 Session::set_meter_falloff (float val)
2536 _meter_falloff = val;
2537 MeterFalloffChanged(); // emit
2542 Session::begin_reversible_command (string name, UndoAction* private_undo)
2544 current_cmd.clear ();
2545 current_cmd.set_name (name);
2548 current_cmd.add_undo (*private_undo);
2553 Session::commit_reversible_command (UndoAction* private_redo)
2558 current_cmd.add_redo_no_execute (*private_redo);
2561 gettimeofday (&now, 0);
2562 current_cmd.set_timestamp (now);
2564 history.add (current_cmd);
2567 Session::GlobalRouteBooleanState
2568 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2570 GlobalRouteBooleanState s;
2571 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2573 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2574 if (!(*i)->hidden()) {
2575 RouteBooleanState v;
2578 v.second = ((*i)->*method)();
2587 Session::GlobalRouteMeterState
2588 Session::get_global_route_metering ()
2590 GlobalRouteMeterState s;
2591 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2593 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2594 if (!(*i)->hidden()) {
2598 v.second = (*i)->meter_point();
2608 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2610 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2611 i->first->set_meter_point (i->second, arg);
2616 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2618 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2619 (i->first->*method) (i->second, arg);
2624 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2626 set_global_route_boolean (s, &Route::set_mute, src);
2630 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2632 set_global_route_boolean (s, &Route::set_solo, src);
2636 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2638 set_global_route_boolean (s, &Route::set_record_enable, src);
2642 Session::global_mute_memento (void* src)
2644 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2648 Session::global_metering_memento (void* src)
2650 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2654 Session::global_solo_memento (void* src)
2656 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2660 Session::global_record_enable_memento (void* src)
2662 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2666 template_filter (const string &str, void *arg)
2668 return (str.length() > strlen(Session::template_suffix()) &&
2669 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2673 Session::get_template_list (list<string> &template_names)
2675 vector<string *> *templates;
2676 PathScanner scanner;
2679 path = template_path ();
2681 templates = scanner (path, template_filter, 0, false, true);
2683 vector<string*>::iterator i;
2684 for (i = templates->begin(); i != templates->end(); ++i) {
2685 string fullpath = *(*i);
2688 start = fullpath.find_last_of ('/') + 1;
2689 if ((end = fullpath.find_last_of ('.')) <0) {
2690 end = fullpath.length();
2693 template_names.push_back(fullpath.substr(start, (end-start)));
2698 Session::read_favorite_dirs (FavoriteDirs & favs)
2700 string path = get_user_ardour_path();
2701 path += "/favorite_dirs";
2703 ifstream fav (path.c_str());
2708 if (errno != ENOENT) {
2709 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2720 getline(fav, newfav);
2726 favs.push_back (newfav);
2733 Session::write_favorite_dirs (FavoriteDirs & favs)
2735 string path = get_user_ardour_path();
2736 path += "/favorite_dirs";
2738 ofstream fav (path.c_str());
2744 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2745 fav << (*i) << endl;
2752 accept_all_non_peak_files (const string& path, void *arg)
2754 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2758 accept_all_state_files (const string& path, void *arg)
2760 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2764 Session::find_all_sources (string path, set<string>& result)
2769 if (!tree.read (path)) {
2773 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2778 XMLNodeConstIterator niter;
2780 nlist = node->children();
2784 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2788 if ((prop = (*niter)->property (X_("name"))) == 0) {
2792 if (prop->value()[0] == '/') {
2793 /* external file, ignore */
2797 string path = _path; /* /-terminated */
2798 path += sound_dir_name;
2800 path += prop->value();
2802 result.insert (path);
2809 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2811 PathScanner scanner;
2812 vector<string*>* state_files;
2814 string this_snapshot_path;
2820 if (ripped[ripped.length()-1] == '/') {
2821 ripped = ripped.substr (0, ripped.length() - 1);
2824 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2826 if (state_files == 0) {
2831 this_snapshot_path = _path;
2832 this_snapshot_path += _current_snapshot_name;
2833 this_snapshot_path += _statefile_suffix;
2835 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2837 if (exclude_this_snapshot && **i == this_snapshot_path) {
2841 if (find_all_sources (**i, result) < 0) {
2850 Session::cleanup_sources (Session::cleanup_report& rep)
2852 vector<Source*> dead_sources;
2853 vector<Playlist*> playlists_tbd;
2854 PathScanner scanner;
2856 vector<space_and_path>::iterator i;
2857 vector<space_and_path>::iterator nexti;
2858 vector<string*>* soundfiles;
2859 vector<string> unused;
2860 set<string> all_sources;
2865 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2867 /* step 1: consider deleting all unused playlists */
2869 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2872 status = AskAboutPlaylistDeletion (*x);
2881 playlists_tbd.push_back (*x);
2885 /* leave it alone */
2890 /* now delete any that were marked for deletion */
2892 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2893 PlaylistList::iterator foo;
2895 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2896 unused_playlists.erase (foo);
2901 /* step 2: clear the undo/redo history for all playlists */
2903 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2904 (*x)->drop_all_states ();
2907 /* step 3: find all un-referenced sources */
2912 for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
2914 SourceList::iterator tmp;
2919 /* only remove files that are not in use and have some size
2920 to them. otherwise we remove the current "nascent"
2924 if ((*i).second->use_cnt() == 0 && (*i).second->length() > 0) {
2925 dead_sources.push_back (i->second);
2927 /* remove this source from our own list to avoid us
2928 adding it to the list of all sources below
2937 /* Step 4: get rid of all regions in the region list that use any dead sources
2938 in case the sources themselves don't go away (they might be referenced in
2942 for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2944 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2945 AudioRegionList::iterator tmp;
2953 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2954 if (&ar->source (n) == (*i)) {
2955 /* this region is dead */
2964 /* build a list of all the possible sound directories for the session */
2966 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2971 sound_path += (*i).path;
2972 sound_path += sound_dir_name;
2974 if (nexti != session_dirs.end()) {
2981 /* now do the same thing for the files that ended up in the sounds dir(s)
2982 but are not referenced as sources in any snapshot.
2985 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2987 if (soundfiles == 0) {
2991 /* find all sources, but don't use this snapshot because the
2992 state file on disk still references sources we may have already
2996 find_all_sources_across_snapshots (all_sources, true);
2998 /* add our current source list
3001 for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
3003 ExternalSource* sfs;
3005 if ((fs = dynamic_cast<FileSource*> ((*i).second)) != 0) {
3006 all_sources.insert (fs->path());
3007 } else if ((sfs = dynamic_cast<ExternalSource*> ((*i).second)) != 0) {
3008 all_sources.insert (sfs->path());
3012 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
3017 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
3027 unused.push_back (spath);
3031 /* now try to move all unused files into the "dead_sounds" directory(ies) */
3033 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
3034 struct stat statbuf;
3036 rep.paths.push_back (*x);
3037 if (stat ((*x).c_str(), &statbuf) == 0) {
3038 rep.space += statbuf.st_size;
3043 /* don't move the file across filesystems, just
3044 stick it in the `dead_sound_dir_name' directory
3045 on whichever filesystem it was already on.
3048 newpath = PBD::dirname (*x);
3049 newpath = PBD::dirname (newpath);
3052 newpath += dead_sound_dir_name;
3054 newpath += PBD::basename ((*x));
3056 if (access (newpath.c_str(), F_OK) == 0) {
3058 /* the new path already exists, try versioning */
3060 char buf[PATH_MAX+1];
3064 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
3067 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
3068 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
3072 if (version == 999) {
3073 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
3077 newpath = newpath_v;
3082 /* it doesn't exist, or we can't read it or something */
3086 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
3087 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
3088 (*x), newpath, strerror (errno))
3094 /* see if there an easy to find peakfile for this file, and remove it.
3097 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
3098 peakpath += ".peak";
3100 if (access (peakpath.c_str(), W_OK) == 0) {
3101 if (::unlink (peakpath.c_str()) != 0) {
3102 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3103 peakpath, _path, strerror (errno))
3105 /* try to back out */
3106 rename (newpath.c_str(), _path.c_str());
3115 /* dump the history list */
3119 /* save state so we don't end up a session file
3120 referring to non-existent sources.
3126 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3131 Session::cleanup_trash_sources (Session::cleanup_report& rep)
3133 vector<space_and_path>::iterator i;
3134 string dead_sound_dir;
3135 struct dirent* dentry;
3136 struct stat statbuf;
3142 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3144 dead_sound_dir = (*i).path;
3145 dead_sound_dir += dead_sound_dir_name;
3147 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
3151 while ((dentry = readdir (dead)) != 0) {
3153 /* avoid '.' and '..' */
3155 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
3156 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3162 fullpath = dead_sound_dir;
3164 fullpath += dentry->d_name;
3166 if (stat (fullpath.c_str(), &statbuf)) {
3170 if (!S_ISREG (statbuf.st_mode)) {
3174 if (unlink (fullpath.c_str())) {
3175 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3176 fullpath, strerror (errno))
3180 rep.paths.push_back (dentry->d_name);
3181 rep.space += statbuf.st_size;
3192 Session::set_dirty ()
3194 bool was_dirty = dirty();
3196 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3199 DirtyChanged(); /* EMIT SIGNAL */
3205 Session::set_clean ()
3207 bool was_dirty = dirty();
3209 _state_of_the_state = Clean;
3212 DirtyChanged(); /* EMIT SIGNAL */