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 cerr << "STart get template\n";
1246 return state(false);
1250 Session::state(bool full_state)
1252 XMLNode* node = new XMLNode("Session");
1255 // store libardour version, just in case
1257 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
1258 libardour_major_version, libardour_minor_version, libardour_micro_version);
1259 node->add_property("version", string(buf));
1261 /* store configuration settings */
1265 /* store the name */
1266 node->add_property ("name", _name);
1268 if (session_dirs.size() > 1) {
1272 vector<space_and_path>::iterator i = session_dirs.begin();
1273 vector<space_and_path>::iterator next;
1275 ++i; /* skip the first one */
1279 while (i != session_dirs.end()) {
1283 if (next != session_dirs.end()) {
1293 child = node->add_child ("Path");
1294 child->add_content (p);
1298 node->add_child_nocopy (get_options());
1300 child = node->add_child ("Sources");
1303 LockMonitor sl (source_lock, __LINE__, __FILE__);
1305 for (SourceList::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1307 /* Don't save information about FileSources that are empty */
1311 if ((fs = dynamic_cast<FileSource*> ((*siter).second)) != 0) {
1312 if (fs->length() == 0) {
1317 child->add_child_nocopy ((*siter).second->get_state());
1321 child = node->add_child ("Regions");
1324 LockMonitor rl (region_lock, __LINE__, __FILE__);
1326 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1328 /* only store regions not attached to playlists */
1330 if ((*i).second->playlist() == 0) {
1331 child->add_child_nocopy (i->second->state (true));
1336 child = node->add_child ("DiskStreams");
1339 RWLockMonitor dl (diskstream_lock, false, __LINE__, __FILE__);
1340 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1341 if (!(*i)->hidden()) {
1342 child->add_child_nocopy ((*i)->get_state());
1347 node->add_child_nocopy (_locations.get_state());
1349 child = node->add_child ("Connections");
1351 LockMonitor lm (connection_lock, __LINE__, __FILE__);
1352 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1353 if (!(*i)->system_dependent()) {
1354 child->add_child_nocopy ((*i)->get_state());
1359 child = node->add_child ("Routes");
1361 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1363 RoutePublicOrderSorter cmp;
1364 RouteList public_order(routes);
1365 public_order.sort (cmp);
1367 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1368 if (!(*i)->hidden()) {
1370 child->add_child_nocopy ((*i)->get_state());
1372 child->add_child_nocopy ((*i)->get_template());
1379 child = node->add_child ("EditGroups");
1380 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1381 child->add_child_nocopy ((*i)->get_state());
1384 child = node->add_child ("MixGroups");
1385 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1386 child->add_child_nocopy ((*i)->get_state());
1389 child = node->add_child ("Playlists");
1390 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1391 if (!(*i)->hidden()) {
1392 if (!(*i)->empty()) {
1394 child->add_child_nocopy ((*i)->get_state());
1396 child->add_child_nocopy ((*i)->get_template());
1402 child = node->add_child ("UnusedPlaylists");
1403 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1404 if (!(*i)->hidden()) {
1405 if (!(*i)->empty()) {
1407 child->add_child_nocopy ((*i)->get_state());
1409 child->add_child_nocopy ((*i)->get_template());
1417 child = node->add_child ("Click");
1418 child->add_child_nocopy (_click_io->state (full_state));
1422 child = node->add_child ("NamedSelections");
1423 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1425 child->add_child_nocopy ((*i)->get_state());
1430 node->add_child_nocopy (_tempo_map->get_state());
1433 node->add_child_copy (*_extra_xml);
1440 Session::set_state (const XMLNode& node)
1444 const XMLProperty* prop;
1447 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1449 if (node.name() != "Session"){
1450 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1454 StateManager::prohibit_save ();
1456 if ((prop = node.property ("name")) != 0) {
1457 _name = prop->value ();
1460 IO::disable_ports ();
1461 IO::disable_connecting ();
1463 /* Object loading order:
1480 if (use_config_midi_ports ()) {
1483 if ((child = find_named_node (node, "Path")) != 0) {
1484 /* XXX this XML content stuff horrible API design */
1485 string raid_path = _path + ':' + child->children().front()->content();
1486 setup_raid_path (raid_path);
1488 /* the path is already set */
1491 if ((child = find_named_node (node, "extra")) != 0) {
1492 _extra_xml = new XMLNode (*child);
1495 if ((child = find_named_node (node, "Options")) == 0) {
1496 error << _("Session: XML state has no options section") << endmsg;
1497 } else if (load_options (*child)) {
1500 if ((child = find_named_node (node, "Sources")) == 0) {
1501 error << _("Session: XML state has no sources section") << endmsg;
1503 } else if (load_sources (*child)) {
1507 if ((child = find_named_node (node, "Regions")) == 0) {
1508 error << _("Session: XML state has no Regions section") << endmsg;
1510 } else if (load_regions (*child)) {
1514 if ((child = find_named_node (node, "Playlists")) == 0) {
1515 error << _("Session: XML state has no playlists section") << endmsg;
1517 } else if (load_playlists (*child)) {
1521 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1523 } else if (load_unused_playlists (*child)) {
1527 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1528 if (load_named_selections (*child)) {
1533 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1534 error << _("Session: XML state has no diskstreams section") << endmsg;
1536 } else if (load_diskstreams (*child)) {
1540 if ((child = find_named_node (node, "Connections")) == 0) {
1541 error << _("Session: XML state has no connections section") << endmsg;
1543 } else if (load_connections (*child)) {
1547 if ((child = find_named_node (node, "Locations")) == 0) {
1548 error << _("Session: XML state has no locations section") << endmsg;
1550 } else if (_locations.set_state (*child)) {
1556 if ((location = _locations.auto_loop_location()) != 0) {
1557 set_auto_loop_location (location);
1560 if ((location = _locations.auto_punch_location()) != 0) {
1561 set_auto_punch_location (location);
1564 if ((location = _locations.end_location()) == 0) {
1565 _locations.add (end_location);
1567 end_location = location;
1570 _locations.save_state (_("initial state"));
1572 if ((child = find_named_node (node, "EditGroups")) == 0) {
1573 error << _("Session: XML state has no edit groups section") << endmsg;
1575 } else if (load_edit_groups (*child)) {
1579 if ((child = find_named_node (node, "MixGroups")) == 0) {
1580 error << _("Session: XML state has no mix groups section") << endmsg;
1582 } else if (load_mix_groups (*child)) {
1586 if ((child = find_named_node (node, "TempoMap")) == 0) {
1587 error << _("Session: XML state has no Tempo Map section") << endmsg;
1589 } else if (_tempo_map->set_state (*child)) {
1593 if ((child = find_named_node (node, "Routes")) == 0) {
1594 error << _("Session: XML state has no routes section") << endmsg;
1596 } else if (load_routes (*child)) {
1600 if ((child = find_named_node (node, "Click")) == 0) {
1601 warning << _("Session: XML state has no click section") << endmsg;
1602 } else if (_click_io) {
1603 _click_io->set_state (*child);
1606 /* OK, now we can set edit mode */
1608 set_edit_mode (pending_edit_mode);
1610 /* here beginneth the second phase ... */
1612 StateReady (); /* EMIT SIGNAL */
1614 _state_of_the_state = Clean;
1616 StateManager::allow_save (_("initial state"), true);
1618 if (state_was_pending) {
1619 save_state (_current_snapshot_name);
1620 remove_pending_capture_state ();
1621 state_was_pending = false;
1627 /* we failed, re-enable state saving but don't actually save internal state */
1628 StateManager::allow_save (X_("ignored"), false);
1633 Session::load_routes (const XMLNode& node)
1636 XMLNodeConstIterator niter;
1639 nlist = node.children();
1643 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1645 if ((route = XMLRouteFactory (**niter)) == 0) {
1646 error << _("Session: cannot create Route from XML description.") << endmsg;
1657 Session::XMLRouteFactory (const XMLNode& node)
1659 if (node.name() != "Route") {
1663 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1664 return new AudioTrack (*this, node);
1666 return new Route (*this, node);
1671 Session::load_regions (const XMLNode& node)
1674 XMLNodeConstIterator niter;
1675 AudioRegion* region;
1677 nlist = node.children();
1681 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1683 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1684 error << _("Session: cannot create Region from XML description.") << endmsg;
1692 Session::XMLRegionFactory (const XMLNode& node, bool full)
1694 const XMLProperty* prop;
1697 AudioRegion::SourceList sources;
1698 uint32_t nchans = 1;
1701 if (node.name() != X_("Region")) {
1705 if ((prop = node.property (X_("channels"))) != 0) {
1706 nchans = atoi (prop->value().c_str());
1710 if ((prop = node.property (X_("source-0"))) == 0) {
1711 if ((prop = node.property ("source")) == 0) {
1712 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1717 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1719 if ((source = get_source (s_id)) == 0) {
1720 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1724 sources.push_back(source);
1726 /* pickup other channels */
1728 for (uint32_t n=1; n < nchans; ++n) {
1729 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1730 if ((prop = node.property (buf)) != 0) {
1731 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1733 if ((source = get_source (s_id)) == 0) {
1734 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1737 sources.push_back(source);
1743 return new AudioRegion (sources, node);
1746 catch (failed_constructor& err) {
1752 Session::get_sources_as_xml ()
1755 XMLNode* node = new XMLNode (X_("Sources"));
1756 LockMonitor lm (source_lock, __LINE__, __FILE__);
1758 for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
1759 node->add_child_nocopy ((*i).second->get_state());
1766 Session::path_from_region_name (string name, string identifier)
1768 char buf[PATH_MAX+1];
1770 string dir = discover_best_sound_dir ();
1772 for (n = 0; n < 999999; ++n) {
1773 if (identifier.length()) {
1774 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1775 identifier.c_str(), n);
1777 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1779 if (access (buf, F_OK) != 0) {
1789 Session::load_sources (const XMLNode& node)
1792 XMLNodeConstIterator niter;
1795 nlist = node.children();
1799 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1801 if ((source = XMLSourceFactory (**niter)) == 0) {
1802 error << _("Session: cannot create Source from XML description.") << endmsg;
1810 Session::XMLSourceFactory (const XMLNode& node)
1814 if (node.name() != "Source") {
1819 src = new FileSource (node, frame_rate());
1822 catch (failed_constructor& err) {
1825 src = new SndFileSource (node);
1828 catch (failed_constructor& err) {
1829 error << _("Found a sound file that cannot be used by Ardour. See the progammers.") << endmsg;
1838 Session::save_template (string template_name)
1841 string xml_path, bak_path, template_path;
1843 if (_state_of_the_state & CannotSave) {
1848 string dir = template_dir();
1850 if ((dp = opendir (dir.c_str()))) {
1853 if (mkdir (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)<0) {
1854 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1859 tree.set_root (&get_template());
1862 xml_path += template_name;
1863 xml_path += _template_suffix;
1865 ifstream in(xml_path.c_str());
1868 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1874 if (!tree.write (xml_path)) {
1875 error << _("mix template not saved") << endmsg;
1883 Session::rename_template (string old_name, string new_name)
1885 string old_path = template_dir() + old_name + _template_suffix;
1886 string new_path = template_dir() + new_name + _template_suffix;
1888 return rename (old_path.c_str(), new_path.c_str());
1892 Session::delete_template (string name)
1894 string template_path = template_dir();
1895 template_path += name;
1896 template_path += _template_suffix;
1898 return remove (template_path.c_str());
1902 Session::refresh_disk_space ()
1905 struct statfs statfsbuf;
1906 vector<space_and_path>::iterator i;
1907 LockMonitor lm (space_lock, __LINE__, __FILE__);
1910 /* get freespace on every FS that is part of the session path */
1912 _total_free_4k_blocks = 0;
1914 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1915 statfs ((*i).path.c_str(), &statfsbuf);
1917 scale = statfsbuf.f_bsize/4096.0;
1919 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1920 _total_free_4k_blocks += (*i).blocks;
1926 Session::ensure_sound_dir (string path, string& result)
1931 /* Ensure that the parent directory exists */
1933 if (mkdir (path.c_str(), 0775)) {
1934 if (errno != EEXIST) {
1935 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1940 /* Ensure that the sounds directory exists */
1944 result += sound_dir_name;
1946 if (mkdir (result.c_str(), 0775)) {
1947 if (errno != EEXIST) {
1948 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1955 dead += dead_sound_dir_name;
1957 if (mkdir (dead.c_str(), 0775)) {
1958 if (errno != EEXIST) {
1959 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1966 peak += peak_dir_name;
1968 if (mkdir (peak.c_str(), 0775)) {
1969 if (errno != EEXIST) {
1970 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1975 /* callers expect this to be terminated ... */
1982 Session::discover_best_sound_dir ()
1984 vector<space_and_path>::iterator i;
1987 /* handle common case without system calls */
1989 if (session_dirs.size() == 1) {
1993 /* OK, here's the algorithm we're following here:
1995 We want to select which directory to use for
1996 the next file source to be created. Ideally,
1997 we'd like to use a round-robin process so as to
1998 get maximum performance benefits from splitting
1999 the files across multiple disks.
2001 However, in situations without much diskspace, an
2002 RR approach may end up filling up a filesystem
2003 with new files while others still have space.
2004 Its therefore important to pay some attention to
2005 the freespace in the filesystem holding each
2006 directory as well. However, if we did that by
2007 itself, we'd keep creating new files in the file
2008 system with the most space until it was as full
2009 as all others, thus negating any performance
2010 benefits of this RAID-1 like approach.
2012 So, we use a user-configurable space threshold. If
2013 there are at least 2 filesystems with more than this
2014 much space available, we use RR selection between them.
2015 If not, then we pick the filesystem with the most space.
2017 This gets a good balance between the two
2021 refresh_disk_space ();
2023 int free_enough = 0;
2025 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2026 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2031 if (free_enough >= 2) {
2033 bool found_it = false;
2035 /* use RR selection process, ensuring that the one
2039 i = last_rr_session_dir;
2042 if (++i == session_dirs.end()) {
2043 i = session_dirs.begin();
2046 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2047 if (ensure_sound_dir ((*i).path, result) == 0) {
2048 last_rr_session_dir = i;
2054 } while (i != last_rr_session_dir);
2057 result = sound_dir();
2062 /* pick FS with the most freespace (and that
2063 seems to actually work ...)
2066 vector<space_and_path> sorted;
2067 space_and_path_ascending_cmp cmp;
2069 sorted = session_dirs;
2070 sort (sorted.begin(), sorted.end(), cmp);
2072 for (i = sorted.begin(); i != sorted.end(); ++i) {
2073 if (ensure_sound_dir ((*i).path, result) == 0) {
2074 last_rr_session_dir = i;
2079 /* if the above fails, fall back to the most simplistic solution */
2081 if (i == sorted.end()) {
2090 Session::load_playlists (const XMLNode& node)
2093 XMLNodeConstIterator niter;
2096 nlist = node.children();
2100 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2102 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2103 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2111 Session::load_unused_playlists (const XMLNode& node)
2114 XMLNodeConstIterator niter;
2117 nlist = node.children();
2121 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2123 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2124 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2128 // now manually untrack it
2130 track_playlist (playlist, false);
2138 Session::XMLPlaylistFactory (const XMLNode& node)
2141 return new AudioPlaylist (*this, node);
2144 catch (failed_constructor& err) {
2150 Session::load_named_selections (const XMLNode& node)
2153 XMLNodeConstIterator niter;
2156 nlist = node.children();
2160 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2162 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2163 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2171 Session::XMLNamedSelectionFactory (const XMLNode& node)
2174 return new NamedSelection (*this, node);
2177 catch (failed_constructor& err) {
2183 Session::dead_sound_dir () const
2186 res += dead_sound_dir_name;
2192 Session::sound_dir () const
2195 res += sound_dir_name;
2201 Session::peak_dir () const
2204 res += peak_dir_name;
2210 Session::automation_dir () const
2213 res += "automation/";
2218 Session::template_dir ()
2220 string path = Config->get_user_ardour_path();
2221 path += "templates/";
2227 Session::template_path ()
2231 path += Config->get_user_ardour_path();
2232 if (path[path.length()-1] != ':') {
2235 path += Config->get_system_ardour_path();
2237 vector<string> split_path;
2239 split (path, split_path, ':');
2242 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2244 path += "templates/";
2246 if (distance (i, split_path.end()) != 1) {
2255 Session::load_connections (const XMLNode& node)
2257 XMLNodeList nlist = node.children();
2258 XMLNodeConstIterator niter;
2262 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2263 if ((*niter)->name() == "InputConnection") {
2264 add_connection (new ARDOUR::InputConnection (**niter));
2265 } else if ((*niter)->name() == "OutputConnection") {
2266 add_connection (new ARDOUR::OutputConnection (**niter));
2268 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2277 Session::load_edit_groups (const XMLNode& node)
2279 return load_route_groups (node, true);
2283 Session::load_mix_groups (const XMLNode& node)
2285 return load_route_groups (node, false);
2289 Session::load_route_groups (const XMLNode& node, bool edit)
2291 XMLNodeList nlist = node.children();
2292 XMLNodeConstIterator niter;
2297 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2298 if ((*niter)->name() == "RouteGroup") {
2300 route = add_edit_group ("");
2301 route->set_state (**niter);
2303 route = add_mix_group ("");
2304 route->set_state (**niter);
2313 Session::swap_configuration(Configuration** new_config)
2315 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__); // jlc - WHY?
2316 Configuration* tmp = *new_config;
2317 *new_config = Config;
2323 Session::copy_configuration(Configuration* new_config)
2325 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
2326 new_config = new Configuration(*Config);
2330 state_file_filter (const string &str, void *arg)
2332 return (str.length() > strlen(Session::statefile_suffix()) &&
2333 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2337 bool operator()(const string* a, const string* b) {
2343 remove_end(string* state)
2345 string statename(*state);
2347 string::size_type start,end;
2348 if ((start = statename.find_last_of ('/')) != string::npos) {
2349 statename = statename.substr (start+1);
2352 if ((end = statename.rfind(".ardour")) < 0) {
2353 end = statename.length();
2356 return new string(statename.substr (0, end));
2360 Session::possible_states (string path)
2362 PathScanner scanner;
2363 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2365 transform(states->begin(), states->end(), states->begin(), remove_end);
2368 sort (states->begin(), states->end(), cmp);
2374 Session::possible_states () const
2376 return possible_states(_path);
2380 Session::auto_save()
2382 save_state (_current_snapshot_name);
2386 Session::add_edit_group (string name)
2388 RouteGroup* rg = new RouteGroup (name);
2389 edit_groups.push_back (rg);
2390 edit_group_added (rg); /* EMIT SIGNAL */
2396 Session::add_mix_group (string name)
2398 RouteGroup* rg = new RouteGroup (name, RouteGroup::Relative);
2399 mix_groups.push_back (rg);
2400 mix_group_added (rg); /* EMIT SIGNAL */
2406 Session::mix_group_by_name (string name)
2408 list<RouteGroup *>::iterator i;
2410 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2411 if ((*i)->name() == name) {
2419 Session::edit_group_by_name (string name)
2421 list<RouteGroup *>::iterator i;
2423 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2424 if ((*i)->name() == name) {
2432 Session::set_meter_hold (float val)
2435 MeterHoldChanged(); // emit
2439 Session::set_meter_falloff (float val)
2441 _meter_falloff = val;
2442 MeterFalloffChanged(); // emit
2447 Session::begin_reversible_command (string name, UndoAction* private_undo)
2449 current_cmd.clear ();
2450 current_cmd.set_name (name);
2453 current_cmd.add_undo (*private_undo);
2458 Session::commit_reversible_command (UndoAction* private_redo)
2463 current_cmd.add_redo_no_execute (*private_redo);
2466 gettimeofday (&now, 0);
2467 current_cmd.set_timestamp (now);
2469 history.add (current_cmd);
2472 Session::GlobalRouteBooleanState
2473 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2475 GlobalRouteBooleanState s;
2476 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2478 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2479 if (!(*i)->hidden()) {
2480 RouteBooleanState v;
2483 v.second = ((*i)->*method)();
2492 Session::GlobalRouteMeterState
2493 Session::get_global_route_metering ()
2495 GlobalRouteMeterState s;
2496 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2498 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2499 if (!(*i)->hidden()) {
2503 v.second = (*i)->meter_point();
2513 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2515 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2516 i->first->set_meter_point (i->second, arg);
2521 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2523 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2524 (i->first->*method) (i->second, arg);
2529 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2531 set_global_route_boolean (s, &Route::set_mute, src);
2535 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2537 set_global_route_boolean (s, &Route::set_solo, src);
2541 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2543 set_global_route_boolean (s, &Route::set_record_enable, src);
2547 Session::global_mute_memento (void* src)
2549 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2553 Session::global_metering_memento (void* src)
2555 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2559 Session::global_solo_memento (void* src)
2561 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2565 Session::global_record_enable_memento (void* src)
2567 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2571 template_filter (const string &str, void *arg)
2573 return (str.length() > strlen(Session::template_suffix()) &&
2574 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2578 Session::get_template_list (list<string> &template_names)
2580 vector<string *> *templates;
2581 PathScanner scanner;
2584 path = template_path ();
2586 templates = scanner (path, template_filter, 0, false, true);
2588 vector<string*>::iterator i;
2589 for (i = templates->begin(); i != templates->end(); ++i) {
2590 string fullpath = *(*i);
2593 start = fullpath.find_last_of ('/') + 1;
2594 if ((end = fullpath.find_last_of ('.')) <0) {
2595 end = fullpath.length();
2598 template_names.push_back(fullpath.substr(start, (end-start)));
2603 Session::read_favorite_dirs (FavoriteDirs & favs)
2605 string path = Config->get_user_ardour_path();
2606 path += "/favorite_dirs";
2608 ifstream fav (path.c_str());
2613 if (errno != ENOENT) {
2614 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2625 getline(fav, newfav);
2631 favs.push_back (newfav);
2638 Session::write_favorite_dirs (FavoriteDirs & favs)
2640 string path = Config->get_user_ardour_path();
2641 path += "/favorite_dirs";
2643 ofstream fav (path.c_str());
2649 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2650 fav << (*i) << endl;
2657 accept_all_non_peak_files (const string& path, void *arg)
2659 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2663 accept_all_state_files (const string& path, void *arg)
2665 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2669 Session::find_all_sources (string path, set<string>& result)
2674 if (!tree.read (path)) {
2678 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2683 XMLNodeConstIterator niter;
2685 nlist = node->children();
2689 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2693 if ((prop = (*niter)->property (X_("name"))) == 0) {
2697 if (prop->value()[0] == '/') {
2698 /* external file, ignore */
2702 string path = _path; /* /-terminated */
2703 path += sound_dir_name;
2705 path += prop->value();
2707 result.insert (path);
2714 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2716 PathScanner scanner;
2717 vector<string*>* state_files;
2719 string this_snapshot_path;
2725 if (ripped[ripped.length()-1] == '/') {
2726 ripped = ripped.substr (0, ripped.length() - 1);
2729 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2731 if (state_files == 0) {
2736 this_snapshot_path = _path;
2737 this_snapshot_path += _current_snapshot_name;
2738 this_snapshot_path += _statefile_suffix;
2740 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2742 if (exclude_this_snapshot && **i == this_snapshot_path) {
2746 if (find_all_sources (**i, result) < 0) {
2755 Session::cleanup_sources (Session::cleanup_report& rep)
2757 vector<Source*> dead_sources;
2758 vector<Playlist*> playlists_tbd;
2759 PathScanner scanner;
2761 vector<space_and_path>::iterator i;
2762 vector<space_and_path>::iterator nexti;
2763 vector<string*>* soundfiles;
2764 vector<string> unused;
2765 set<string> all_sources;
2770 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2772 /* step 1: consider deleting all unused playlists */
2774 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2777 status = AskAboutPlaylistDeletion (*x);
2786 playlists_tbd.push_back (*x);
2790 /* leave it alone */
2795 /* now delete any that were marked for deletion */
2797 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2798 PlaylistList::iterator foo;
2800 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2801 unused_playlists.erase (foo);
2806 /* step 2: clear the undo/redo history for all playlists */
2808 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2809 (*x)->drop_all_states ();
2812 /* step 3: find all un-referenced sources */
2817 for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
2819 SourceList::iterator tmp;
2824 /* only remove files that are not in use and have some size
2825 to them. otherwise we remove the current "nascent"
2829 if ((*i).second->use_cnt() == 0 && (*i).second->length() > 0) {
2830 dead_sources.push_back (i->second);
2832 /* remove this source from our own list to avoid us
2833 adding it to the list of all sources below
2842 /* Step 4: get rid of all regions in the region list that use any dead sources
2843 in case the sources themselves don't go away (they might be referenced in
2847 for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2849 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2850 AudioRegionList::iterator tmp;
2858 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2859 if (&ar->source (n) == (*i)) {
2860 /* this region is dead */
2869 /* build a list of all the possible sound directories for the session */
2871 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2876 sound_path += (*i).path;
2877 sound_path += sound_dir_name;
2879 if (nexti != session_dirs.end()) {
2886 /* now do the same thing for the files that ended up in the sounds dir(s)
2887 but are not referenced as sources in any snapshot.
2890 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2892 if (soundfiles == 0) {
2896 /* find all sources, but don't use this snapshot because the
2897 state file on disk still references sources we may have already
2901 find_all_sources_across_snapshots (all_sources, true);
2903 /* add our current source list
2906 for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
2910 if ((fs = dynamic_cast<FileSource*> ((*i).second)) != 0) {
2911 all_sources.insert (fs->path());
2912 } else if ((sfs = dynamic_cast<SndFileSource*> ((*i).second)) != 0) {
2913 all_sources.insert (sfs->path());
2917 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2922 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2932 unused.push_back (spath);
2936 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2938 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2939 struct stat statbuf;
2941 rep.paths.push_back (*x);
2942 if (stat ((*x).c_str(), &statbuf) == 0) {
2943 rep.space += statbuf.st_size;
2948 /* don't move the file across filesystems, just
2949 stick it in the `dead_sound_dir_name' directory
2950 on whichever filesystem it was already on.
2953 newpath = PBD::dirname (*x);
2954 newpath = PBD::dirname (newpath);
2957 newpath += dead_sound_dir_name;
2959 newpath += PBD::basename ((*x));
2961 if (access (newpath.c_str(), F_OK) == 0) {
2963 /* the new path already exists, try versioning */
2965 char buf[PATH_MAX+1];
2969 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2972 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2973 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2977 if (version == 999) {
2978 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2982 newpath = newpath_v;
2987 /* it doesn't exist, or we can't read it or something */
2991 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2992 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2993 (*x), newpath, strerror (errno))
2999 /* see if there an easy to find peakfile for this file, and remove it.
3002 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
3003 peakpath += ".peak";
3005 if (access (peakpath.c_str(), W_OK) == 0) {
3006 if (::unlink (peakpath.c_str()) != 0) {
3007 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3008 peakpath, _path, strerror (errno))
3010 /* try to back out */
3011 rename (newpath.c_str(), _path.c_str());
3020 /* dump the history list */
3024 /* save state so we don't end up a session file
3025 referring to non-existent sources.
3031 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3036 Session::cleanup_trash_sources (Session::cleanup_report& rep)
3038 vector<space_and_path>::iterator i;
3039 string dead_sound_dir;
3040 struct dirent* dentry;
3041 struct stat statbuf;
3047 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3049 dead_sound_dir = (*i).path;
3050 dead_sound_dir += dead_sound_dir_name;
3052 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
3056 while ((dentry = readdir (dead)) != 0) {
3058 /* avoid '.' and '..' */
3060 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
3061 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3067 fullpath = dead_sound_dir;
3069 fullpath += dentry->d_name;
3071 if (stat (fullpath.c_str(), &statbuf)) {
3075 if (!S_ISREG (statbuf.st_mode)) {
3079 if (unlink (fullpath.c_str())) {
3080 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3081 fullpath, strerror (errno))
3085 rep.paths.push_back (dentry->d_name);
3086 rep.space += statbuf.st_size;
3097 Session::set_dirty ()
3099 bool was_dirty = dirty();
3101 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3104 DirtyChanged(); /* EMIT SIGNAL */
3110 Session::set_clean ()
3112 bool was_dirty = dirty();
3114 _state_of_the_state = Clean;
3117 DirtyChanged(); /* EMIT SIGNAL */