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/sndfilesource.h>
66 #include <ardour/sndfile_helpers.h>
67 #include <ardour/auditioner.h>
68 #include <ardour/export.h>
69 #include <ardour/redirect.h>
70 #include <ardour/send.h>
71 #include <ardour/insert.h>
72 #include <ardour/connection.h>
73 #include <ardour/slave.h>
74 #include <ardour/tempo.h>
75 #include <ardour/audio_track.h>
76 #include <ardour/cycle_timer.h>
77 #include <ardour/utils.h>
78 #include <ardour/named_selection.h>
79 #include <ardour/version.h>
80 #include <ardour/location.h>
81 #include <ardour/audioregion.h>
82 #include <ardour/crossfade.h>
88 using namespace ARDOUR;
91 Session::first_stage_init (string fullpath, string snapshot_name)
93 if (fullpath.length() == 0) {
94 throw failed_constructor();
98 if (!realpath(fullpath.c_str(), buf) && (errno != ENOENT)) {
99 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
100 throw failed_constructor();
104 if (_path[_path.length()-1] != '/') {
108 /* these two are just provisional settings. set_state()
109 will likely override them.
112 _name = _current_snapshot_name = snapshot_name;
113 setup_raid_path (_path);
115 _current_frame_rate = _engine.frame_rate ();
116 _tempo_map = new TempoMap (_current_frame_rate);
117 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
119 atomic_set (&processing_prohibited, 0);
122 _transport_speed = 0;
123 _last_transport_speed = 0;
124 transport_sub_state = 0;
125 _transport_frame = 0;
127 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
128 _end_location_is_free = true;
129 atomic_set (&_record_status, Disabled);
134 seamless_loop = false;
135 loop_changing = false;
137 crossfades_active = false;
140 _last_roll_location = 0;
141 _last_record_location = 0;
142 pending_locate_frame = 0;
143 pending_locate_roll = false;
144 pending_locate_flush = false;
145 dstream_buffer_size = 0;
147 state_was_pending = false;
149 outbound_mtc_smpte_frame = 0;
150 next_quarter_frame_to_send = -1;
151 current_block_size = 0;
152 _solo_latched = true;
153 _solo_model = InverseMute;
154 solo_update_disabled = false;
155 currently_soloing = false;
156 _worst_output_latency = 0;
157 _worst_input_latency = 0;
158 _worst_track_latency = 0;
159 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
162 butler_mixdown_buffer = 0;
163 butler_gain_buffer = 0;
166 midi_feedback = false;
169 post_transport_work = PostTransportWork (0);
170 atomic_set (&butler_should_do_transport_work, 0);
171 atomic_set (&butler_active, 0);
172 atomic_set (&_playback_load, 100);
173 atomic_set (&_capture_load, 100);
174 atomic_set (&_playback_load_min, 100);
175 atomic_set (&_capture_load_min, 100);
176 pending_audition_region = 0;
178 pending_edit_mode = _edit_mode;
182 input_auto_connect = AutoConnectOption (0);
183 output_auto_connect = AutoConnectOption (0);
184 _have_captured = false;
185 waiting_to_start = false;
187 _gain_automation_buffer = 0;
188 _pan_automation_buffer = 0;
190 pending_abort = false;
191 layer_model = MoveAddHigher;
192 xfade_model = ShortCrossfade;
194 /* default short fade = 15ms */
196 Crossfade::set_short_xfade_length ((jack_nframes_t) floor ((15.0 * frame_rate()) / 1000.0));
198 last_mmc_step.tv_sec = 0;
199 last_mmc_step.tv_usec = 0;
202 preroll.type = AnyTime::Frames;
204 postroll.type = AnyTime::Frames;
207 /* click sounds are unset by default, which causes us to internal
208 waveforms for clicks.
213 click_requested = false;
215 click_emphasis_data = 0;
217 click_emphasis_length = 0;
219 process_function = &Session::process_with_events;
223 _smpte_offset_negative = true;
224 last_smpte_valid = false;
226 last_rr_session_dir = session_dirs.begin();
227 refresh_disk_space ();
229 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
231 /* default configuration */
233 do_not_record_plugins = false;
234 over_length_short = 2;
235 over_length_long = 10;
236 send_midi_timecode = false;
237 send_midi_machine_control = false;
238 shuttle_speed_factor = 1.0;
239 shuttle_speed_threshold = 5;
241 _meter_hold = 100; // XXX unknown units: number of calls to meter::set()
242 _meter_falloff = 1.5f; // XXX unknown units: refresh_rate
248 average_slave_delta = 1800;
249 have_first_delta_accumulator = false;
250 delta_accumulator_cnt = 0;
251 slave_state = Stopped;
253 /* default SMPTE type is 30 FPS, non-drop */
255 set_smpte_type (30.0, false);
257 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
259 /* These are all static "per-class" signals */
261 Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
262 Source::SourceCreated.connect (mem_fun (*this, &Session::add_source));
263 Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
264 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
265 DiskStream::DiskStreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
266 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
268 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
270 /* stop IO objects from doing stuff until we're ready for them */
272 IO::disable_panners ();
273 IO::disable_ports ();
274 IO::disable_connecting ();
278 Session::second_stage_init (bool new_session)
280 SndFileSource::set_peak_dir (peak_dir());
283 if (load_state (_current_snapshot_name)) {
286 remove_empty_sounds ();
289 if (start_butler_thread()) {
293 if (start_midi_thread ()) {
297 if (init_feedback ()) {
302 if (set_state (*state_tree->root())) {
307 /* we can't save till after ::when_engine_running() is called,
308 because otherwise we save state with no connections made.
309 therefore, we reset _state_of_the_state because ::set_state()
310 will have cleared it.
312 we also have to include Loading so that any events that get
313 generated between here and the end of ::when_engine_running()
314 will be processed directly rather than queued.
317 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
319 // set_auto_input (true);
320 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
321 _locations.added.connect (mem_fun (this, &Session::locations_added));
322 setup_click_sounds (0);
323 setup_midi_control ();
325 /* Pay attention ... */
327 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
328 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
330 if (_engine.running()) {
331 when_engine_running();
333 first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
336 send_full_time_code ();
337 _engine.transport_locate (0);
338 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
339 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
340 send_all_midi_feedback();
343 _end_location_is_free = true;
345 _end_location_is_free = false;
352 Session::raid_path () const
356 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
361 return path.substr (0, path.length() - 1); // drop final colon
365 Session::set_raid_path (string path)
367 /* public-access to setup_raid_path() */
369 setup_raid_path (path);
373 Session::setup_raid_path (string path)
375 string::size_type colon;
379 string::size_type len = path.length();
384 if (path.length() == 0) {
388 session_dirs.clear ();
390 for (string::size_type n = 0; n < len; ++n) {
391 if (path[n] == ':') {
398 /* no multiple search path, just one directory (common case) */
402 session_dirs.push_back (sp);
404 FileSource::set_search_path (path + sound_dir_name);
411 while ((colon = remaining.find_first_of (':')) != string::npos) {
414 sp.path = remaining.substr (0, colon);
417 if (fspath[fspath.length()-1] != '/') {
420 fspath += sound_dir_name;
423 session_dirs.push_back (sp);
425 remaining = remaining.substr (colon+1);
428 if (remaining.length()) {
434 if (fspath[fspath.length()-1] != '/') {
437 fspath += sound_dir_name;
439 session_dirs.push_back (sp);
442 /* set the FileSource search path */
444 FileSource::set_search_path (fspath);
446 /* reset the round-robin soundfile path thingie */
448 last_rr_session_dir = session_dirs.begin();
452 Session::create (bool& new_session, string* mix_template, jack_nframes_t initial_length)
456 if (mkdir (_path.c_str(), 0755) < 0) {
457 if (errno == EEXIST) {
460 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
469 if (mkdir (dir.c_str(), 0755) < 0) {
470 if (errno != EEXIST) {
471 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
478 if (mkdir (dir.c_str(), 0755) < 0) {
479 if (errno != EEXIST) {
480 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
485 dir = dead_sound_dir ();
487 if (mkdir (dir.c_str(), 0755) < 0) {
488 if (errno != EEXIST) {
489 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
494 dir = automation_dir ();
496 if (mkdir (dir.c_str(), 0755) < 0) {
497 if (errno != EEXIST) {
498 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
504 /* check new_session so we don't overwrite an existing one */
509 string lookfor = "^";
510 lookfor += *mix_template;
511 lookfor += _template_suffix;
515 string tpath = template_path();
519 vector<string*>* result= scanner (tpath, lookfor, false, true);
522 error << string_compose (_("Could not find a template called %1 in %2"), *mix_template, tpath)
527 if (result->size() == 0) {
529 error << string_compose (_("Could not find a template called %1 in %2"), *mix_template, tpath)
534 in_path = *(result->front());
536 ifstream in(in_path.c_str());
539 string out_path = _path;
541 out_path += _statefile_suffix;
543 ofstream out(out_path.c_str());
548 // okay, session is set up. Treat like normal saved
549 // session from now on.
555 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
561 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
568 warning << _("Session already exists. Not overwriting") << endmsg;
575 /* set an initial end point */
577 end_location->set_end (initial_length);
578 _locations.add (end_location);
580 _state_of_the_state = Clean;
582 if (save_state (_current_snapshot_name)) {
591 Session::load_diskstreams (const XMLNode& node)
594 XMLNodeConstIterator citer;
596 clist = node.children();
598 for (citer = clist.begin(); citer != clist.end(); ++citer) {
603 dstream = new DiskStream (*this, **citer);
604 /* added automatically by DiskStreamCreated handler */
607 catch (failed_constructor& err) {
608 error << _("Session: could not load diskstream via XML state") << endmsg;
617 Session::remove_pending_capture_state ()
622 xml_path += _current_snapshot_name;
623 xml_path += _pending_suffix;
625 unlink (xml_path.c_str());
629 Session::save_state (string snapshot_name, bool pending)
635 if (_state_of_the_state & CannotSave) {
639 tree.set_root (&get_state());
641 if (snapshot_name.empty()) {
642 snapshot_name = _current_snapshot_name;
648 xml_path += snapshot_name;
649 xml_path += _statefile_suffix;
653 // Make backup of state file
655 if ((access (xml_path.c_str(), F_OK) == 0) &&
656 (rename(xml_path.c_str(), bak_path.c_str()))) {
657 error << _("could not backup old state file, current state not saved.") << endmsg;
664 xml_path += snapshot_name;
665 xml_path += _pending_suffix;
669 if (!tree.write (xml_path)) {
670 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
672 /* don't leave a corrupt file lying around if it is
676 if (unlink (xml_path.c_str())) {
677 error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
680 if (rename (bak_path.c_str(), xml_path.c_str())) {
681 error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
691 bool was_dirty = dirty();
693 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
696 DirtyChanged (); /* EMIT SIGNAL */
699 StateSaved (snapshot_name); /* EMIT SIGNAL */
706 Session::restore_state (string snapshot_name)
708 if (load_state (snapshot_name) == 0) {
709 set_state (*state_tree->root());
716 Session::load_state (string snapshot_name)
725 state_was_pending = false;
727 /* check for leftover pending state from a crashed capture attempt */
730 xmlpath += snapshot_name;
731 xmlpath += _pending_suffix;
733 if (!access (xmlpath.c_str(), F_OK)) {
735 /* there is pending state from a crashed capture attempt */
737 if (AskAboutPendingState()) {
738 state_was_pending = true;
742 if (!state_was_pending) {
745 xmlpath += snapshot_name;
746 xmlpath += _statefile_suffix;
749 if (access (xmlpath.c_str(), F_OK)) {
750 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
754 state_tree = new XMLTree;
758 if (state_tree->read (xmlpath)) {
761 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
770 Session::load_options (const XMLNode& node)
774 bool have_fade_msecs = false;
775 bool have_fade_steepness = false;
776 float fade_msecs = 0;
777 float fade_steepness = 0;
778 SlaveSource slave_src = None;
780 LocaleGuard lg (X_("POSIX"));
782 if ((child = find_named_node (node, "input-auto-connect")) != 0) {
783 if ((prop = child->property ("val")) != 0) {
784 sscanf (prop->value().c_str(), "%x", &x);
785 input_auto_connect = AutoConnectOption (x);
789 if ((child = find_named_node (node, "output-auto-connect")) != 0) {
790 if ((prop = child->property ("val")) != 0) {
791 sscanf (prop->value().c_str(), "%x", &x);
792 output_auto_connect = AutoConnectOption (x);
796 if ((child = find_named_node (node, "slave")) != 0) {
797 if ((prop = child->property ("type")) != 0) {
798 if (prop->value() == "none") {
800 } else if (prop->value() == "mtc") {
802 } else if (prop->value() == "jack") {
805 set_slave_source (slave_src, 0);
809 /* we cannot set edit mode if we are loading a session,
810 because it might destroy the playlist's positioning
813 if ((child = find_named_node (node, "edit-mode")) != 0) {
814 if ((prop = child->property ("val")) != 0) {
815 if (prop->value() == "slide") {
816 pending_edit_mode = Slide;
817 } else if (prop->value() == "splice") {
818 pending_edit_mode = Splice;
823 if ((child = find_named_node (node, "send-midi-timecode")) != 0) {
824 if ((prop = child->property ("val")) != 0) {
825 bool x = (prop->value() == "yes");
826 send_mtc = !x; /* force change in value */
830 if ((child = find_named_node (node, "send-midi-machine-control")) != 0) {
831 if ((prop = child->property ("val")) != 0) {
832 bool x = (prop->value() == "yes");
833 send_mmc = !x; /* force change in value */
834 set_send_mmc (prop->value() == "yes");
837 if ((child = find_named_node (node, "max-level")) != 0) {
838 if ((prop = child->property ("val")) != 0) {
839 max_level = atoi (prop->value().c_str());
842 if ((child = find_named_node (node, "min-level")) != 0) {
843 if ((prop = child->property ("val")) != 0) {
844 min_level = atoi (prop->value().c_str());
847 if ((child = find_named_node (node, "meter-hold")) != 0) {
848 if ((prop = child->property ("val")) != 0) {
849 _meter_hold = atof (prop->value().c_str());
852 if ((child = find_named_node (node, "meter-falloff")) != 0) {
853 if ((prop = child->property ("val")) != 0) {
854 _meter_falloff = atof (prop->value().c_str());
857 if ((child = find_named_node (node, "long-over-length")) != 0) {
858 if ((prop = child->property ("val")) != 0) {
859 over_length_long = atoi (prop->value().c_str());
862 if ((child = find_named_node (node, "short-over-length")) != 0) {
863 if ((prop = child->property ("val")) != 0) {
864 over_length_short = atoi (prop->value().c_str());
867 if ((child = find_named_node (node, "shuttle-speed-factor")) != 0) {
868 if ((prop = child->property ("val")) != 0) {
869 shuttle_speed_factor = atof (prop->value().c_str());
872 if ((child = find_named_node (node, "shuttle-speed-threshold")) != 0) {
873 if ((prop = child->property ("val")) != 0) {
874 shuttle_speed_threshold = atof (prop->value().c_str());
877 if ((child = find_named_node (node, "rf-speed")) != 0) {
878 if ((prop = child->property ("val")) != 0) {
879 rf_speed = atof (prop->value().c_str());
882 if ((child = find_named_node (node, "smpte-frames-per-second")) != 0) {
883 if ((prop = child->property ("val")) != 0) {
884 set_smpte_type( atof (prop->value().c_str()), smpte_drop_frames );
887 if ((child = find_named_node (node, "smpte-drop-frames")) != 0) {
888 if ((prop = child->property ("val")) != 0) {
889 set_smpte_type( smpte_frames_per_second, (prop->value() == "yes") );
892 if ((child = find_named_node (node, "smpte-offset")) != 0) {
893 if ((prop = child->property ("val")) != 0) {
894 set_smpte_offset( atoi (prop->value().c_str()) );
897 if ((child = find_named_node (node, "smpte-offset-negative")) != 0) {
898 if ((prop = child->property ("val")) != 0) {
899 set_smpte_offset_negative( (prop->value() == "yes") );
902 if ((child = find_named_node (node, "click-sound")) != 0) {
903 if ((prop = child->property ("val")) != 0) {
904 click_sound = prop->value();
907 if ((child = find_named_node (node, "click-emphasis-sound")) != 0) {
908 if ((prop = child->property ("val")) != 0) {
909 click_emphasis_sound = prop->value();
913 if ((child = find_named_node (node, "solo-model")) != 0) {
914 if ((prop = child->property ("val")) != 0) {
915 if (prop->value() == "SoloBus")
916 _solo_model = SoloBus;
918 _solo_model = InverseMute;
922 /* BOOLEAN OPTIONS */
924 if ((child = find_named_node (node, "auto-play")) != 0) {
925 if ((prop = child->property ("val")) != 0) {
926 set_auto_play (prop->value() == "yes");
929 if ((child = find_named_node (node, "auto-input")) != 0) {
930 if ((prop = child->property ("val")) != 0) {
931 set_auto_input (prop->value() == "yes");
934 if ((child = find_named_node (node, "seamless-loop")) != 0) {
935 if ((prop = child->property ("val")) != 0) {
936 set_seamless_loop (prop->value() == "yes");
939 if ((child = find_named_node (node, "punch-in")) != 0) {
940 if ((prop = child->property ("val")) != 0) {
941 set_punch_in (prop->value() == "yes");
944 if ((child = find_named_node (node, "punch-out")) != 0) {
945 if ((prop = child->property ("val")) != 0) {
946 set_punch_out (prop->value() == "yes");
949 if ((child = find_named_node (node, "auto-return")) != 0) {
950 if ((prop = child->property ("val")) != 0) {
951 set_auto_return (prop->value() == "yes");
954 if ((child = find_named_node (node, "send-mtc")) != 0) {
955 if ((prop = child->property ("val")) != 0) {
956 set_send_mtc (prop->value() == "yes");
959 if ((child = find_named_node (node, "mmc-control")) != 0) {
960 if ((prop = child->property ("val")) != 0) {
961 set_mmc_control (prop->value() == "yes");
964 if ((child = find_named_node (node, "midi-control")) != 0) {
965 if ((prop = child->property ("val")) != 0) {
966 set_midi_control (prop->value() == "yes");
969 if ((child = find_named_node (node, "midi-feedback")) != 0) {
970 if ((prop = child->property ("val")) != 0) {
971 set_midi_feedback (prop->value() == "yes");
974 // Legacy support for <recording-plugins>
975 if ((child = find_named_node (node, "recording-plugins")) != 0) {
976 if ((prop = child->property ("val")) != 0) {
977 set_do_not_record_plugins (prop->value() == "no");
980 if ((child = find_named_node (node, "do-not-record-plugins")) != 0) {
981 if ((prop = child->property ("val")) != 0) {
982 set_do_not_record_plugins (prop->value() == "yes");
985 if ((child = find_named_node (node, "crossfades-active")) != 0) {
986 if ((prop = child->property ("val")) != 0) {
987 set_crossfades_active (prop->value() == "yes");
990 if ((child = find_named_node (node, "audible-click")) != 0) {
991 if ((prop = child->property ("val")) != 0) {
992 set_clicking (prop->value() == "yes");
996 if ((child = find_named_node (node, "layer-model")) != 0) {
997 if ((prop = child->property ("val")) != 0) {
998 if (prop->value() == X_("LaterHigher")) {
999 set_layer_model (LaterHigher);
1000 } else if (prop->value() == X_("AddHigher")) {
1001 set_layer_model (AddHigher);
1003 set_layer_model (MoveAddHigher);
1008 if ((child = find_named_node (node, "xfade-model")) != 0) {
1009 if ((prop = child->property ("val")) != 0) {
1010 if (prop->value() == X_("Short")) {
1011 set_xfade_model (ShortCrossfade);
1013 set_xfade_model (FullCrossfade);
1018 if ((child = find_named_node (node, "short-xfade-length")) != 0) {
1019 if ((prop = child->property ("val")) != 0) {
1020 /* value is stored as a fractional seconds */
1021 float secs = atof (prop->value().c_str());
1022 Crossfade::set_short_xfade_length ((jack_nframes_t) floor (secs * frame_rate()));
1026 if ((child = find_named_node (node, "full-xfades-unmuted")) != 0) {
1027 if ((prop = child->property ("val")) != 0) {
1028 crossfades_active = (prop->value() == "yes");
1034 if ((child = find_named_node (node, "default-fade-steepness")) != 0) {
1035 if ((prop = child->property ("val")) != 0) {
1036 fade_steepness = atof (prop->value().c_str());
1037 have_fade_steepness = true;
1040 if ((child = find_named_node (node, "default-fade-msec")) != 0) {
1041 if ((prop = child->property ("val")) != 0) {
1042 fade_msecs = atof (prop->value().c_str());
1043 have_fade_msecs = true;
1047 if (have_fade_steepness || have_fade_msecs) {
1048 // set_default_fade (fade_steepness, fade_msecs);
1055 Session::get_options () const
1060 LocaleGuard lg (X_("POSIX"));
1062 opthead = new XMLNode ("Options");
1064 SlaveSource src = slave_source ();
1068 src_string = "none";
1074 src_string = "jack";
1077 child = opthead->add_child ("slave");
1078 child->add_property ("type", src_string);
1080 child = opthead->add_child ("send-midi-timecode");
1081 child->add_property ("val", send_midi_timecode?"yes":"no");
1083 child = opthead->add_child ("send-midi-machine-control");
1084 child->add_property ("val", send_midi_machine_control?"yes":"no");
1086 snprintf (buf, sizeof(buf)-1, "%x", (int) input_auto_connect);
1087 child = opthead->add_child ("input-auto-connect");
1088 child->add_property ("val", buf);
1090 snprintf (buf, sizeof(buf)-1, "%x", (int) output_auto_connect);
1091 child = opthead->add_child ("output-auto-connect");
1092 child->add_property ("val", buf);
1094 snprintf (buf, sizeof(buf)-1, "%d", max_level);
1095 child = opthead->add_child ("max-level");
1096 child->add_property ("val", buf);
1098 snprintf (buf, sizeof(buf)-1, "%d", min_level);
1099 child = opthead->add_child ("min-level");
1100 child->add_property ("val", buf);
1102 snprintf (buf, sizeof(buf)-1, "%f", _meter_hold);
1103 child = opthead->add_child ("meter-hold");
1104 child->add_property ("val", buf);
1106 snprintf (buf, sizeof(buf)-1, "%f", _meter_falloff);
1107 child = opthead->add_child ("meter-falloff");
1108 child->add_property ("val", buf);
1110 snprintf (buf, sizeof(buf)-1, "%u", over_length_long);
1111 child = opthead->add_child ("long-over-length");
1112 child->add_property ("val", buf);
1114 snprintf (buf, sizeof(buf)-1, "%u", over_length_short);
1115 child = opthead->add_child ("short-over-length");
1116 child->add_property ("val", buf);
1118 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_factor);
1119 child = opthead->add_child ("shuttle-speed-factor");
1120 child->add_property ("val", buf);
1122 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_threshold);
1123 child = opthead->add_child ("shuttle-speed-threshold");
1124 child->add_property ("val", buf);
1126 snprintf (buf, sizeof(buf)-1, "%f", rf_speed);
1127 child = opthead->add_child ("rf-speed");
1128 child->add_property ("val", buf);
1130 snprintf (buf, sizeof(buf)-1, "%.2f", smpte_frames_per_second);
1131 child = opthead->add_child ("smpte-frames-per-second");
1132 child->add_property ("val", buf);
1134 child = opthead->add_child ("smpte-drop-frames");
1135 child->add_property ("val", smpte_drop_frames ? "yes" : "no");
1137 snprintf (buf, sizeof(buf)-1, "%u", smpte_offset ());
1138 child = opthead->add_child ("smpte-offset");
1139 child->add_property ("val", buf);
1141 child = opthead->add_child ("smpte-offset-negative");
1142 child->add_property ("val", smpte_offset_negative () ? "yes" : "no");
1144 child = opthead->add_child ("edit-mode");
1145 switch (_edit_mode) {
1147 child->add_property ("val", "splice");
1151 child->add_property ("val", "slide");
1155 child = opthead->add_child ("auto-play");
1156 child->add_property ("val", get_auto_play () ? "yes" : "no");
1157 child = opthead->add_child ("auto-input");
1158 child->add_property ("val", get_auto_input () ? "yes" : "no");
1159 child = opthead->add_child ("seamless-loop");
1160 child->add_property ("val", get_seamless_loop () ? "yes" : "no");
1161 child = opthead->add_child ("punch-in");
1162 child->add_property ("val", get_punch_in () ? "yes" : "no");
1163 child = opthead->add_child ("punch-out");
1164 child->add_property ("val", get_punch_out () ? "yes" : "no");
1165 child = opthead->add_child ("all-safe");
1166 child->add_property ("val", get_all_safe () ? "yes" : "no");
1167 child = opthead->add_child ("auto-return");
1168 child->add_property ("val", get_auto_return () ? "yes" : "no");
1169 child = opthead->add_child ("mmc-control");
1170 child->add_property ("val", get_mmc_control () ? "yes" : "no");
1171 child = opthead->add_child ("midi-control");
1172 child->add_property ("val", get_midi_control () ? "yes" : "no");
1173 child = opthead->add_child ("midi-feedback");
1174 child->add_property ("val", get_midi_feedback () ? "yes" : "no");
1175 child = opthead->add_child ("do-not-record-plugins");
1176 child->add_property ("val", get_do_not_record_plugins () ? "yes" : "no");
1177 child = opthead->add_child ("auto-crossfade");
1178 child->add_property ("val", get_crossfades_active () ? "yes" : "no");
1179 child = opthead->add_child ("audible-click");
1180 child->add_property ("val", get_clicking () ? "yes" : "no");
1182 if (click_sound.length()) {
1183 child = opthead->add_child ("click-sound");
1184 child->add_property ("val", click_sound);
1187 if (click_emphasis_sound.length()) {
1188 child = opthead->add_child ("click-emphasis-sound");
1189 child->add_property ("val", click_emphasis_sound);
1192 child = opthead->add_child ("solo-model");
1193 child->add_property ("val", _solo_model == SoloBus ? "SoloBus" : "InverseMute");
1195 child = opthead->add_child ("layer-model");
1196 switch (layer_model) {
1198 child->add_property ("val", X_("LaterHigher"));
1201 child->add_property ("val", X_("MoveAddHigher"));
1204 child->add_property ("val", X_("AddHigher"));
1208 child = opthead->add_child ("xfade-model");
1209 switch (xfade_model) {
1211 child->add_property ("val", X_("Full"));
1213 case ShortCrossfade:
1214 child->add_property ("val", X_("Short"));
1217 child = opthead->add_child ("short-xfade-length");
1218 /* store as fractions of a second */
1219 snprintf (buf, sizeof(buf)-1, "%f",
1220 (float) Crossfade::short_xfade_length() / frame_rate());
1221 child->add_property ("val", buf);
1223 child = opthead->add_child ("full-xfades-unmuted");
1224 child->add_property ("val", crossfades_active ? "yes" : "no");
1230 Session::get_state()
1236 Session::get_template()
1238 /* if we don't disable rec-enable, diskstreams
1239 will believe they need to store their capture
1240 sources in their state node.
1245 return state(false);
1249 Session::state(bool full_state)
1251 XMLNode* node = new XMLNode("Session");
1254 // store libardour version, just in case
1256 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
1257 libardour_major_version, libardour_minor_version, libardour_micro_version);
1258 node->add_property("version", string(buf));
1260 /* store configuration settings */
1264 /* store the name */
1265 node->add_property ("name", _name);
1267 if (session_dirs.size() > 1) {
1271 vector<space_and_path>::iterator i = session_dirs.begin();
1272 vector<space_and_path>::iterator next;
1274 ++i; /* skip the first one */
1278 while (i != session_dirs.end()) {
1282 if (next != session_dirs.end()) {
1292 child = node->add_child ("Path");
1293 child->add_content (p);
1297 node->add_child_nocopy (get_options());
1299 child = node->add_child ("Sources");
1302 LockMonitor sl (source_lock, __LINE__, __FILE__);
1304 for (SourceList::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1306 /* Don't save information about FileSources that are empty */
1310 if ((fs = dynamic_cast<FileSource*> ((*siter).second)) != 0) {
1311 if (fs->length() == 0) {
1316 child->add_child_nocopy ((*siter).second->get_state());
1320 child = node->add_child ("Regions");
1323 LockMonitor rl (region_lock, __LINE__, __FILE__);
1325 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1327 /* only store regions not attached to playlists */
1329 if ((*i).second->playlist() == 0) {
1330 child->add_child_nocopy (i->second->state (true));
1335 child = node->add_child ("DiskStreams");
1338 RWLockMonitor dl (diskstream_lock, false, __LINE__, __FILE__);
1339 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1340 if (!(*i)->hidden()) {
1341 child->add_child_nocopy ((*i)->get_state());
1346 node->add_child_nocopy (_locations.get_state());
1348 child = node->add_child ("Connections");
1350 LockMonitor lm (connection_lock, __LINE__, __FILE__);
1351 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1352 if (!(*i)->system_dependent()) {
1353 child->add_child_nocopy ((*i)->get_state());
1358 child = node->add_child ("Routes");
1360 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1362 RoutePublicOrderSorter cmp;
1363 RouteList public_order(routes);
1364 public_order.sort (cmp);
1366 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1367 if (!(*i)->hidden()) {
1369 child->add_child_nocopy ((*i)->get_state());
1371 child->add_child_nocopy ((*i)->get_template());
1378 child = node->add_child ("EditGroups");
1379 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1380 child->add_child_nocopy ((*i)->get_state());
1383 child = node->add_child ("MixGroups");
1384 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1385 child->add_child_nocopy ((*i)->get_state());
1388 child = node->add_child ("Playlists");
1389 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1390 if (!(*i)->hidden()) {
1391 if (!(*i)->empty()) {
1393 child->add_child_nocopy ((*i)->get_state());
1395 child->add_child_nocopy ((*i)->get_template());
1401 child = node->add_child ("UnusedPlaylists");
1402 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1403 if (!(*i)->hidden()) {
1404 if (!(*i)->empty()) {
1406 child->add_child_nocopy ((*i)->get_state());
1408 child->add_child_nocopy ((*i)->get_template());
1416 child = node->add_child ("Click");
1417 child->add_child_nocopy (_click_io->state (full_state));
1421 child = node->add_child ("NamedSelections");
1422 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1424 child->add_child_nocopy ((*i)->get_state());
1429 node->add_child_nocopy (_tempo_map->get_state());
1432 node->add_child_copy (*_extra_xml);
1439 Session::set_state (const XMLNode& node)
1443 const XMLProperty* prop;
1446 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1448 if (node.name() != "Session"){
1449 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1453 StateManager::prohibit_save ();
1455 if ((prop = node.property ("name")) != 0) {
1456 _name = prop->value ();
1459 IO::disable_ports ();
1460 IO::disable_connecting ();
1462 /* Object loading order:
1479 if (use_config_midi_ports ()) {
1482 if ((child = find_named_node (node, "Path")) != 0) {
1483 /* XXX this XML content stuff horrible API design */
1484 string raid_path = _path + ':' + child->children().front()->content();
1485 setup_raid_path (raid_path);
1487 /* the path is already set */
1490 if ((child = find_named_node (node, "extra")) != 0) {
1491 _extra_xml = new XMLNode (*child);
1494 if ((child = find_named_node (node, "Options")) == 0) {
1495 error << _("Session: XML state has no options section") << endmsg;
1496 } else if (load_options (*child)) {
1499 if ((child = find_named_node (node, "Sources")) == 0) {
1500 error << _("Session: XML state has no sources section") << endmsg;
1502 } else if (load_sources (*child)) {
1506 if ((child = find_named_node (node, "Regions")) == 0) {
1507 error << _("Session: XML state has no Regions section") << endmsg;
1509 } else if (load_regions (*child)) {
1513 if ((child = find_named_node (node, "Playlists")) == 0) {
1514 error << _("Session: XML state has no playlists section") << endmsg;
1516 } else if (load_playlists (*child)) {
1520 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1522 } else if (load_unused_playlists (*child)) {
1526 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1527 if (load_named_selections (*child)) {
1532 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1533 error << _("Session: XML state has no diskstreams section") << endmsg;
1535 } else if (load_diskstreams (*child)) {
1539 if ((child = find_named_node (node, "Connections")) == 0) {
1540 error << _("Session: XML state has no connections section") << endmsg;
1542 } else if (load_connections (*child)) {
1546 if ((child = find_named_node (node, "Locations")) == 0) {
1547 error << _("Session: XML state has no locations section") << endmsg;
1549 } else if (_locations.set_state (*child)) {
1555 if ((location = _locations.auto_loop_location()) != 0) {
1556 set_auto_loop_location (location);
1559 if ((location = _locations.auto_punch_location()) != 0) {
1560 set_auto_punch_location (location);
1563 if ((location = _locations.end_location()) == 0) {
1564 _locations.add (end_location);
1566 end_location = location;
1569 _locations.save_state (_("initial state"));
1571 if ((child = find_named_node (node, "EditGroups")) == 0) {
1572 error << _("Session: XML state has no edit groups section") << endmsg;
1574 } else if (load_edit_groups (*child)) {
1578 if ((child = find_named_node (node, "MixGroups")) == 0) {
1579 error << _("Session: XML state has no mix groups section") << endmsg;
1581 } else if (load_mix_groups (*child)) {
1585 if ((child = find_named_node (node, "TempoMap")) == 0) {
1586 error << _("Session: XML state has no Tempo Map section") << endmsg;
1588 } else if (_tempo_map->set_state (*child)) {
1592 if ((child = find_named_node (node, "Routes")) == 0) {
1593 error << _("Session: XML state has no routes section") << endmsg;
1595 } else if (load_routes (*child)) {
1599 if ((child = find_named_node (node, "Click")) == 0) {
1600 warning << _("Session: XML state has no click section") << endmsg;
1601 } else if (_click_io) {
1602 _click_io->set_state (*child);
1605 /* OK, now we can set edit mode */
1607 set_edit_mode (pending_edit_mode);
1609 /* here beginneth the second phase ... */
1611 StateReady (); /* EMIT SIGNAL */
1613 _state_of_the_state = Clean;
1615 StateManager::allow_save (_("initial state"), true);
1617 if (state_was_pending) {
1618 save_state (_current_snapshot_name);
1619 remove_pending_capture_state ();
1620 state_was_pending = false;
1626 /* we failed, re-enable state saving but don't actually save internal state */
1627 StateManager::allow_save (X_("ignored"), false);
1632 Session::load_routes (const XMLNode& node)
1635 XMLNodeConstIterator niter;
1638 nlist = node.children();
1642 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1644 if ((route = XMLRouteFactory (**niter)) == 0) {
1645 error << _("Session: cannot create Route from XML description.") << endmsg;
1656 Session::XMLRouteFactory (const XMLNode& node)
1658 if (node.name() != "Route") {
1662 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1663 return new AudioTrack (*this, node);
1665 return new Route (*this, node);
1670 Session::load_regions (const XMLNode& node)
1673 XMLNodeConstIterator niter;
1674 AudioRegion* region;
1676 nlist = node.children();
1680 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1682 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1683 error << _("Session: cannot create Region from XML description.") << endmsg;
1691 Session::XMLRegionFactory (const XMLNode& node, bool full)
1693 const XMLProperty* prop;
1696 AudioRegion::SourceList sources;
1697 uint32_t nchans = 1;
1700 if (node.name() != X_("Region")) {
1704 if ((prop = node.property (X_("channels"))) != 0) {
1705 nchans = atoi (prop->value().c_str());
1709 if ((prop = node.property (X_("source-0"))) == 0) {
1710 if ((prop = node.property ("source")) == 0) {
1711 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1716 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1718 if ((source = get_source (s_id)) == 0) {
1719 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1723 sources.push_back(source);
1725 /* pickup other channels */
1727 for (uint32_t n=1; n < nchans; ++n) {
1728 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1729 if ((prop = node.property (buf)) != 0) {
1730 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1732 if ((source = get_source (s_id)) == 0) {
1733 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1736 sources.push_back(source);
1742 return new AudioRegion (sources, node);
1745 catch (failed_constructor& err) {
1751 Session::get_sources_as_xml ()
1754 XMLNode* node = new XMLNode (X_("Sources"));
1755 LockMonitor lm (source_lock, __LINE__, __FILE__);
1757 for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
1758 node->add_child_nocopy ((*i).second->get_state());
1765 Session::path_from_region_name (string name, string identifier)
1767 char buf[PATH_MAX+1];
1769 string dir = discover_best_sound_dir ();
1771 for (n = 0; n < 999999; ++n) {
1772 if (identifier.length()) {
1773 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1774 identifier.c_str(), n);
1776 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1778 if (access (buf, F_OK) != 0) {
1788 Session::load_sources (const XMLNode& node)
1791 XMLNodeConstIterator niter;
1794 nlist = node.children();
1798 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1800 if ((source = XMLSourceFactory (**niter)) == 0) {
1801 error << _("Session: cannot create Source from XML description.") << endmsg;
1809 Session::XMLSourceFactory (const XMLNode& node)
1813 if (node.name() != "Source") {
1818 src = new FileSource (node, frame_rate());
1821 catch (failed_constructor& err) {
1824 src = new SndFileSource (node);
1827 catch (failed_constructor& err) {
1828 error << _("Found a sound file that cannot be used by Ardour. See the progammers.") << endmsg;
1837 Session::save_template (string template_name)
1840 string xml_path, bak_path, template_path;
1842 if (_state_of_the_state & CannotSave) {
1847 string dir = template_dir();
1849 if ((dp = opendir (dir.c_str()))) {
1852 if (mkdir (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)<0) {
1853 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1858 tree.set_root (&get_template());
1861 xml_path += template_name;
1862 xml_path += _template_suffix;
1864 ifstream in(xml_path.c_str());
1867 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1873 if (!tree.write (xml_path)) {
1874 error << _("mix template not saved") << endmsg;
1882 Session::rename_template (string old_name, string new_name)
1884 string old_path = template_dir() + old_name + _template_suffix;
1885 string new_path = template_dir() + new_name + _template_suffix;
1887 return rename (old_path.c_str(), new_path.c_str());
1891 Session::delete_template (string name)
1893 string template_path = template_dir();
1894 template_path += name;
1895 template_path += _template_suffix;
1897 return remove (template_path.c_str());
1901 Session::refresh_disk_space ()
1904 struct statfs statfsbuf;
1905 vector<space_and_path>::iterator i;
1906 LockMonitor lm (space_lock, __LINE__, __FILE__);
1909 /* get freespace on every FS that is part of the session path */
1911 _total_free_4k_blocks = 0;
1913 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1914 statfs ((*i).path.c_str(), &statfsbuf);
1916 scale = statfsbuf.f_bsize/4096.0;
1918 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1919 _total_free_4k_blocks += (*i).blocks;
1925 Session::ensure_sound_dir (string path, string& result)
1930 /* Ensure that the parent directory exists */
1932 if (mkdir (path.c_str(), 0775)) {
1933 if (errno != EEXIST) {
1934 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1939 /* Ensure that the sounds directory exists */
1943 result += sound_dir_name;
1945 if (mkdir (result.c_str(), 0775)) {
1946 if (errno != EEXIST) {
1947 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1954 dead += dead_sound_dir_name;
1956 if (mkdir (dead.c_str(), 0775)) {
1957 if (errno != EEXIST) {
1958 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1965 peak += peak_dir_name;
1967 if (mkdir (peak.c_str(), 0775)) {
1968 if (errno != EEXIST) {
1969 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1974 /* callers expect this to be terminated ... */
1981 Session::discover_best_sound_dir ()
1983 vector<space_and_path>::iterator i;
1986 /* handle common case without system calls */
1988 if (session_dirs.size() == 1) {
1992 /* OK, here's the algorithm we're following here:
1994 We want to select which directory to use for
1995 the next file source to be created. Ideally,
1996 we'd like to use a round-robin process so as to
1997 get maximum performance benefits from splitting
1998 the files across multiple disks.
2000 However, in situations without much diskspace, an
2001 RR approach may end up filling up a filesystem
2002 with new files while others still have space.
2003 Its therefore important to pay some attention to
2004 the freespace in the filesystem holding each
2005 directory as well. However, if we did that by
2006 itself, we'd keep creating new files in the file
2007 system with the most space until it was as full
2008 as all others, thus negating any performance
2009 benefits of this RAID-1 like approach.
2011 So, we use a user-configurable space threshold. If
2012 there are at least 2 filesystems with more than this
2013 much space available, we use RR selection between them.
2014 If not, then we pick the filesystem with the most space.
2016 This gets a good balance between the two
2020 refresh_disk_space ();
2022 int free_enough = 0;
2024 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2025 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2030 if (free_enough >= 2) {
2032 bool found_it = false;
2034 /* use RR selection process, ensuring that the one
2038 i = last_rr_session_dir;
2041 if (++i == session_dirs.end()) {
2042 i = session_dirs.begin();
2045 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2046 if (ensure_sound_dir ((*i).path, result) == 0) {
2047 last_rr_session_dir = i;
2053 } while (i != last_rr_session_dir);
2056 result = sound_dir();
2061 /* pick FS with the most freespace (and that
2062 seems to actually work ...)
2065 vector<space_and_path> sorted;
2066 space_and_path_ascending_cmp cmp;
2068 sorted = session_dirs;
2069 sort (sorted.begin(), sorted.end(), cmp);
2071 for (i = sorted.begin(); i != sorted.end(); ++i) {
2072 if (ensure_sound_dir ((*i).path, result) == 0) {
2073 last_rr_session_dir = i;
2078 /* if the above fails, fall back to the most simplistic solution */
2080 if (i == sorted.end()) {
2089 Session::load_playlists (const XMLNode& node)
2092 XMLNodeConstIterator niter;
2095 nlist = node.children();
2099 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2101 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2102 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2110 Session::load_unused_playlists (const XMLNode& node)
2113 XMLNodeConstIterator niter;
2116 nlist = node.children();
2120 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2122 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2123 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2127 // now manually untrack it
2129 track_playlist (playlist, false);
2137 Session::XMLPlaylistFactory (const XMLNode& node)
2140 return new AudioPlaylist (*this, node);
2143 catch (failed_constructor& err) {
2149 Session::load_named_selections (const XMLNode& node)
2152 XMLNodeConstIterator niter;
2155 nlist = node.children();
2159 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2161 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2162 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2170 Session::XMLNamedSelectionFactory (const XMLNode& node)
2173 return new NamedSelection (*this, node);
2176 catch (failed_constructor& err) {
2182 Session::dead_sound_dir () const
2185 res += dead_sound_dir_name;
2191 Session::sound_dir () const
2194 res += sound_dir_name;
2200 Session::peak_dir () const
2203 res += peak_dir_name;
2209 Session::automation_dir () const
2212 res += "automation/";
2217 Session::template_dir ()
2219 string path = Config->get_user_ardour_path();
2220 path += "templates/";
2226 Session::template_path ()
2230 path += Config->get_user_ardour_path();
2231 if (path[path.length()-1] != ':') {
2234 path += Config->get_system_ardour_path();
2236 vector<string> split_path;
2238 split (path, split_path, ':');
2241 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2243 path += "templates/";
2245 if (distance (i, split_path.end()) != 1) {
2254 Session::load_connections (const XMLNode& node)
2256 XMLNodeList nlist = node.children();
2257 XMLNodeConstIterator niter;
2261 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2262 if ((*niter)->name() == "InputConnection") {
2263 add_connection (new ARDOUR::InputConnection (**niter));
2264 } else if ((*niter)->name() == "OutputConnection") {
2265 add_connection (new ARDOUR::OutputConnection (**niter));
2267 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2276 Session::load_edit_groups (const XMLNode& node)
2278 return load_route_groups (node, true);
2282 Session::load_mix_groups (const XMLNode& node)
2284 return load_route_groups (node, false);
2288 Session::load_route_groups (const XMLNode& node, bool edit)
2290 XMLNodeList nlist = node.children();
2291 XMLNodeConstIterator niter;
2296 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2297 if ((*niter)->name() == "RouteGroup") {
2299 route = add_edit_group ("");
2300 route->set_state (**niter);
2302 route = add_mix_group ("");
2303 route->set_state (**niter);
2312 Session::swap_configuration(Configuration** new_config)
2314 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__); // jlc - WHY?
2315 Configuration* tmp = *new_config;
2316 *new_config = Config;
2322 Session::copy_configuration(Configuration* new_config)
2324 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
2325 new_config = new Configuration(*Config);
2329 state_file_filter (const string &str, void *arg)
2331 return (str.length() > strlen(Session::statefile_suffix()) &&
2332 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2336 bool operator()(const string* a, const string* b) {
2342 remove_end(string* state)
2344 string statename(*state);
2346 string::size_type start,end;
2347 if ((start = statename.find_last_of ('/')) != string::npos) {
2348 statename = statename.substr (start+1);
2351 if ((end = statename.rfind(".ardour")) < 0) {
2352 end = statename.length();
2355 return new string(statename.substr (0, end));
2359 Session::possible_states (string path)
2361 PathScanner scanner;
2362 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2364 transform(states->begin(), states->end(), states->begin(), remove_end);
2367 sort (states->begin(), states->end(), cmp);
2373 Session::possible_states () const
2375 return possible_states(_path);
2379 Session::auto_save()
2381 save_state (_current_snapshot_name);
2385 Session::add_edit_group (string name)
2387 RouteGroup* rg = new RouteGroup (name);
2388 edit_groups.push_back (rg);
2389 edit_group_added (rg); /* EMIT SIGNAL */
2395 Session::add_mix_group (string name)
2397 RouteGroup* rg = new RouteGroup (name, RouteGroup::Relative);
2398 mix_groups.push_back (rg);
2399 mix_group_added (rg); /* EMIT SIGNAL */
2405 Session::mix_group_by_name (string name)
2407 list<RouteGroup *>::iterator i;
2409 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2410 if ((*i)->name() == name) {
2418 Session::edit_group_by_name (string name)
2420 list<RouteGroup *>::iterator i;
2422 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2423 if ((*i)->name() == name) {
2431 Session::set_meter_hold (float val)
2434 MeterHoldChanged(); // emit
2438 Session::set_meter_falloff (float val)
2440 _meter_falloff = val;
2441 MeterFalloffChanged(); // emit
2446 Session::begin_reversible_command (string name, UndoAction* private_undo)
2448 current_cmd.clear ();
2449 current_cmd.set_name (name);
2452 current_cmd.add_undo (*private_undo);
2457 Session::commit_reversible_command (UndoAction* private_redo)
2462 current_cmd.add_redo_no_execute (*private_redo);
2465 gettimeofday (&now, 0);
2466 current_cmd.set_timestamp (now);
2468 history.add (current_cmd);
2471 Session::GlobalRouteBooleanState
2472 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2474 GlobalRouteBooleanState s;
2475 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2477 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2478 if (!(*i)->hidden()) {
2479 RouteBooleanState v;
2482 v.second = ((*i)->*method)();
2491 Session::GlobalRouteMeterState
2492 Session::get_global_route_metering ()
2494 GlobalRouteMeterState s;
2495 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2497 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2498 if (!(*i)->hidden()) {
2502 v.second = (*i)->meter_point();
2512 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2514 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2515 i->first->set_meter_point (i->second, arg);
2520 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2522 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2523 (i->first->*method) (i->second, arg);
2528 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2530 set_global_route_boolean (s, &Route::set_mute, src);
2534 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2536 set_global_route_boolean (s, &Route::set_solo, src);
2540 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2542 set_global_route_boolean (s, &Route::set_record_enable, src);
2546 Session::global_mute_memento (void* src)
2548 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2552 Session::global_metering_memento (void* src)
2554 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2558 Session::global_solo_memento (void* src)
2560 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2564 Session::global_record_enable_memento (void* src)
2566 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2570 template_filter (const string &str, void *arg)
2572 return (str.length() > strlen(Session::template_suffix()) &&
2573 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2577 Session::get_template_list (list<string> &template_names)
2579 vector<string *> *templates;
2580 PathScanner scanner;
2583 path = template_path ();
2585 templates = scanner (path, template_filter, 0, false, true);
2587 vector<string*>::iterator i;
2588 for (i = templates->begin(); i != templates->end(); ++i) {
2589 string fullpath = *(*i);
2592 start = fullpath.find_last_of ('/') + 1;
2593 if ((end = fullpath.find_last_of ('.')) <0) {
2594 end = fullpath.length();
2597 template_names.push_back(fullpath.substr(start, (end-start)));
2602 Session::read_favorite_dirs (FavoriteDirs & favs)
2604 string path = Config->get_user_ardour_path();
2605 path += "/favorite_dirs";
2607 ifstream fav (path.c_str());
2612 if (errno != ENOENT) {
2613 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2624 getline(fav, newfav);
2630 favs.push_back (newfav);
2637 Session::write_favorite_dirs (FavoriteDirs & favs)
2639 string path = Config->get_user_ardour_path();
2640 path += "/favorite_dirs";
2642 ofstream fav (path.c_str());
2648 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2649 fav << (*i) << endl;
2656 accept_all_non_peak_files (const string& path, void *arg)
2658 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2662 accept_all_state_files (const string& path, void *arg)
2664 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2668 Session::find_all_sources (string path, set<string>& result)
2673 if (!tree.read (path)) {
2677 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2682 XMLNodeConstIterator niter;
2684 nlist = node->children();
2688 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2692 if ((prop = (*niter)->property (X_("name"))) == 0) {
2696 if (prop->value()[0] == '/') {
2697 /* external file, ignore */
2701 string path = _path; /* /-terminated */
2702 path += sound_dir_name;
2704 path += prop->value();
2706 result.insert (path);
2713 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2715 PathScanner scanner;
2716 vector<string*>* state_files;
2718 string this_snapshot_path;
2724 if (ripped[ripped.length()-1] == '/') {
2725 ripped = ripped.substr (0, ripped.length() - 1);
2728 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2730 if (state_files == 0) {
2735 this_snapshot_path = _path;
2736 this_snapshot_path += _current_snapshot_name;
2737 this_snapshot_path += _statefile_suffix;
2739 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2741 if (exclude_this_snapshot && **i == this_snapshot_path) {
2745 if (find_all_sources (**i, result) < 0) {
2754 Session::cleanup_sources (Session::cleanup_report& rep)
2756 vector<Source*> dead_sources;
2757 vector<Playlist*> playlists_tbd;
2758 PathScanner scanner;
2760 vector<space_and_path>::iterator i;
2761 vector<space_and_path>::iterator nexti;
2762 vector<string*>* soundfiles;
2763 vector<string> unused;
2764 set<string> all_sources;
2769 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2771 /* step 1: consider deleting all unused playlists */
2773 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2776 status = AskAboutPlaylistDeletion (*x);
2785 playlists_tbd.push_back (*x);
2789 /* leave it alone */
2794 /* now delete any that were marked for deletion */
2796 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2797 PlaylistList::iterator foo;
2799 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2800 unused_playlists.erase (foo);
2805 /* step 2: clear the undo/redo history for all playlists */
2807 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2808 (*x)->drop_all_states ();
2811 /* step 3: find all un-referenced sources */
2816 for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
2818 SourceList::iterator tmp;
2823 /* only remove files that are not in use and have some size
2824 to them. otherwise we remove the current "nascent"
2828 if ((*i).second->use_cnt() == 0 && (*i).second->length() > 0) {
2829 dead_sources.push_back (i->second);
2831 /* remove this source from our own list to avoid us
2832 adding it to the list of all sources below
2841 /* Step 4: get rid of all regions in the region list that use any dead sources
2842 in case the sources themselves don't go away (they might be referenced in
2846 for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2848 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2849 AudioRegionList::iterator tmp;
2857 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2858 if (&ar->source (n) == (*i)) {
2859 /* this region is dead */
2868 /* build a list of all the possible sound directories for the session */
2870 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2875 sound_path += (*i).path;
2876 sound_path += sound_dir_name;
2878 if (nexti != session_dirs.end()) {
2885 /* now do the same thing for the files that ended up in the sounds dir(s)
2886 but are not referenced as sources in any snapshot.
2889 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2891 if (soundfiles == 0) {
2895 /* find all sources, but don't use this snapshot because the
2896 state file on disk still references sources we may have already
2900 find_all_sources_across_snapshots (all_sources, true);
2902 /* add our current source list
2905 for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
2909 if ((fs = dynamic_cast<FileSource*> ((*i).second)) != 0) {
2910 all_sources.insert (fs->path());
2911 } else if ((sfs = dynamic_cast<SndFileSource*> ((*i).second)) != 0) {
2912 all_sources.insert (sfs->path());
2916 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2921 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2931 unused.push_back (spath);
2935 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2937 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2938 struct stat statbuf;
2940 rep.paths.push_back (*x);
2941 if (stat ((*x).c_str(), &statbuf) == 0) {
2942 rep.space += statbuf.st_size;
2947 /* don't move the file across filesystems, just
2948 stick it in the `dead_sound_dir_name' directory
2949 on whichever filesystem it was already on.
2952 newpath = PBD::dirname (*x);
2953 newpath = PBD::dirname (newpath);
2956 newpath += dead_sound_dir_name;
2958 newpath += PBD::basename ((*x));
2960 if (access (newpath.c_str(), F_OK) == 0) {
2962 /* the new path already exists, try versioning */
2964 char buf[PATH_MAX+1];
2968 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2971 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2972 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2976 if (version == 999) {
2977 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2981 newpath = newpath_v;
2986 /* it doesn't exist, or we can't read it or something */
2990 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2991 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2992 (*x), newpath, strerror (errno))
2998 /* see if there an easy to find peakfile for this file, and remove it.
3001 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
3002 peakpath += ".peak";
3004 if (access (peakpath.c_str(), W_OK) == 0) {
3005 if (::unlink (peakpath.c_str()) != 0) {
3006 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3007 peakpath, _path, strerror (errno))
3009 /* try to back out */
3010 rename (newpath.c_str(), _path.c_str());
3019 /* dump the history list */
3023 /* save state so we don't end up a session file
3024 referring to non-existent sources.
3030 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3035 Session::cleanup_trash_sources (Session::cleanup_report& rep)
3037 vector<space_and_path>::iterator i;
3038 string dead_sound_dir;
3039 struct dirent* dentry;
3040 struct stat statbuf;
3046 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3048 dead_sound_dir = (*i).path;
3049 dead_sound_dir += dead_sound_dir_name;
3051 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
3055 while ((dentry = readdir (dead)) != 0) {
3057 /* avoid '.' and '..' */
3059 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
3060 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3066 fullpath = dead_sound_dir;
3068 fullpath += dentry->d_name;
3070 if (stat (fullpath.c_str(), &statbuf)) {
3074 if (!S_ISREG (statbuf.st_mode)) {
3078 if (unlink (fullpath.c_str())) {
3079 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3080 fullpath, strerror (errno))
3084 rep.paths.push_back (dentry->d_name);
3085 rep.space += statbuf.st_size;
3096 Session::set_dirty ()
3098 bool was_dirty = dirty();
3100 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3103 DirtyChanged(); /* EMIT SIGNAL */
3109 Session::set_clean ()
3111 bool was_dirty = dirty();
3113 _state_of_the_state = Clean;
3116 DirtyChanged(); /* EMIT SIGNAL */