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 recording_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 if ((child = find_named_node (node, "recording-plugins")) != 0) {
975 if ((prop = child->property ("val")) != 0) {
976 set_recording_plugins (prop->value() == "yes");
979 if ((child = find_named_node (node, "crossfades-active")) != 0) {
980 if ((prop = child->property ("val")) != 0) {
981 set_crossfades_active (prop->value() == "yes");
984 if ((child = find_named_node (node, "audible-click")) != 0) {
985 if ((prop = child->property ("val")) != 0) {
986 set_clicking (prop->value() == "yes");
990 if ((child = find_named_node (node, "layer-model")) != 0) {
991 if ((prop = child->property ("val")) != 0) {
992 if (prop->value() == X_("LaterHigher")) {
993 set_layer_model (LaterHigher);
994 } else if (prop->value() == X_("AddHigher")) {
995 set_layer_model (AddHigher);
997 set_layer_model (MoveAddHigher);
1002 if ((child = find_named_node (node, "xfade-model")) != 0) {
1003 if ((prop = child->property ("val")) != 0) {
1004 if (prop->value() == X_("Short")) {
1005 set_xfade_model (ShortCrossfade);
1007 set_xfade_model (FullCrossfade);
1012 if ((child = find_named_node (node, "short-xfade-length")) != 0) {
1013 if ((prop = child->property ("val")) != 0) {
1014 /* value is stored as a fractional seconds */
1015 float secs = atof (prop->value().c_str());
1016 Crossfade::set_short_xfade_length ((jack_nframes_t) floor (secs * frame_rate()));
1020 if ((child = find_named_node (node, "full-xfades-unmuted")) != 0) {
1021 if ((prop = child->property ("val")) != 0) {
1022 crossfades_active = (prop->value() == "yes");
1028 if ((child = find_named_node (node, "default-fade-steepness")) != 0) {
1029 if ((prop = child->property ("val")) != 0) {
1030 fade_steepness = atof (prop->value().c_str());
1031 have_fade_steepness = true;
1034 if ((child = find_named_node (node, "default-fade-msec")) != 0) {
1035 if ((prop = child->property ("val")) != 0) {
1036 fade_msecs = atof (prop->value().c_str());
1037 have_fade_msecs = true;
1041 if (have_fade_steepness || have_fade_msecs) {
1042 // set_default_fade (fade_steepness, fade_msecs);
1049 Session::get_options () const
1054 LocaleGuard lg (X_("POSIX"));
1056 opthead = new XMLNode ("Options");
1058 SlaveSource src = slave_source ();
1062 src_string = "none";
1068 src_string = "jack";
1071 child = opthead->add_child ("slave");
1072 child->add_property ("type", src_string);
1074 child = opthead->add_child ("send-midi-timecode");
1075 child->add_property ("val", send_midi_timecode?"yes":"no");
1077 child = opthead->add_child ("send-midi-machine-control");
1078 child->add_property ("val", send_midi_machine_control?"yes":"no");
1080 snprintf (buf, sizeof(buf)-1, "%x", (int) input_auto_connect);
1081 child = opthead->add_child ("input-auto-connect");
1082 child->add_property ("val", buf);
1084 snprintf (buf, sizeof(buf)-1, "%x", (int) output_auto_connect);
1085 child = opthead->add_child ("output-auto-connect");
1086 child->add_property ("val", buf);
1088 snprintf (buf, sizeof(buf)-1, "%d", max_level);
1089 child = opthead->add_child ("max-level");
1090 child->add_property ("val", buf);
1092 snprintf (buf, sizeof(buf)-1, "%d", min_level);
1093 child = opthead->add_child ("min-level");
1094 child->add_property ("val", buf);
1096 snprintf (buf, sizeof(buf)-1, "%f", _meter_hold);
1097 child = opthead->add_child ("meter-hold");
1098 child->add_property ("val", buf);
1100 snprintf (buf, sizeof(buf)-1, "%f", _meter_falloff);
1101 child = opthead->add_child ("meter-falloff");
1102 child->add_property ("val", buf);
1104 snprintf (buf, sizeof(buf)-1, "%u", over_length_long);
1105 child = opthead->add_child ("long-over-length");
1106 child->add_property ("val", buf);
1108 snprintf (buf, sizeof(buf)-1, "%u", over_length_short);
1109 child = opthead->add_child ("short-over-length");
1110 child->add_property ("val", buf);
1112 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_factor);
1113 child = opthead->add_child ("shuttle-speed-factor");
1114 child->add_property ("val", buf);
1116 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_threshold);
1117 child = opthead->add_child ("shuttle-speed-threshold");
1118 child->add_property ("val", buf);
1120 snprintf (buf, sizeof(buf)-1, "%f", rf_speed);
1121 child = opthead->add_child ("rf-speed");
1122 child->add_property ("val", buf);
1124 snprintf (buf, sizeof(buf)-1, "%.2f", smpte_frames_per_second);
1125 child = opthead->add_child ("smpte-frames-per-second");
1126 child->add_property ("val", buf);
1128 child = opthead->add_child ("smpte-drop-frames");
1129 child->add_property ("val", smpte_drop_frames ? "yes" : "no");
1131 snprintf (buf, sizeof(buf)-1, "%u", smpte_offset ());
1132 child = opthead->add_child ("smpte-offset");
1133 child->add_property ("val", buf);
1135 child = opthead->add_child ("smpte-offset-negative");
1136 child->add_property ("val", smpte_offset_negative () ? "yes" : "no");
1138 child = opthead->add_child ("edit-mode");
1139 switch (_edit_mode) {
1141 child->add_property ("val", "splice");
1145 child->add_property ("val", "slide");
1149 child = opthead->add_child ("auto-play");
1150 child->add_property ("val", get_auto_play () ? "yes" : "no");
1151 child = opthead->add_child ("auto-input");
1152 child->add_property ("val", get_auto_input () ? "yes" : "no");
1153 child = opthead->add_child ("seamless-loop");
1154 child->add_property ("val", get_seamless_loop () ? "yes" : "no");
1155 child = opthead->add_child ("punch-in");
1156 child->add_property ("val", get_punch_in () ? "yes" : "no");
1157 child = opthead->add_child ("punch-out");
1158 child->add_property ("val", get_punch_out () ? "yes" : "no");
1159 child = opthead->add_child ("all-safe");
1160 child->add_property ("val", get_all_safe () ? "yes" : "no");
1161 child = opthead->add_child ("auto-return");
1162 child->add_property ("val", get_auto_return () ? "yes" : "no");
1163 child = opthead->add_child ("mmc-control");
1164 child->add_property ("val", get_mmc_control () ? "yes" : "no");
1165 child = opthead->add_child ("midi-control");
1166 child->add_property ("val", get_midi_control () ? "yes" : "no");
1167 child = opthead->add_child ("midi-feedback");
1168 child->add_property ("val", get_midi_feedback () ? "yes" : "no");
1169 child = opthead->add_child ("recording-plugins");
1170 child->add_property ("val", get_recording_plugins () ? "yes" : "no");
1171 child = opthead->add_child ("auto-crossfade");
1172 child->add_property ("val", get_crossfades_active () ? "yes" : "no");
1173 child = opthead->add_child ("audible-click");
1174 child->add_property ("val", get_clicking () ? "yes" : "no");
1176 if (click_sound.length()) {
1177 child = opthead->add_child ("click-sound");
1178 child->add_property ("val", click_sound);
1181 if (click_emphasis_sound.length()) {
1182 child = opthead->add_child ("click-emphasis-sound");
1183 child->add_property ("val", click_emphasis_sound);
1186 child = opthead->add_child ("solo-model");
1187 child->add_property ("val", _solo_model == SoloBus ? "SoloBus" : "InverseMute");
1189 child = opthead->add_child ("layer-model");
1190 switch (layer_model) {
1192 child->add_property ("val", X_("LaterHigher"));
1195 child->add_property ("val", X_("MoveAddHigher"));
1198 child->add_property ("val", X_("AddHigher"));
1202 child = opthead->add_child ("xfade-model");
1203 switch (xfade_model) {
1205 child->add_property ("val", X_("Full"));
1207 case ShortCrossfade:
1208 child->add_property ("val", X_("Short"));
1211 child = opthead->add_child ("short-xfade-length");
1212 /* store as fractions of a second */
1213 snprintf (buf, sizeof(buf)-1, "%f",
1214 (float) Crossfade::short_xfade_length() / frame_rate());
1215 child->add_property ("val", buf);
1217 child = opthead->add_child ("full-xfades-unmuted");
1218 child->add_property ("val", crossfades_active ? "yes" : "no");
1224 Session::get_state()
1230 Session::get_template()
1232 /* if we don't disable rec-enable, diskstreams
1233 will believe they need to store their capture
1234 sources in their state node.
1239 cerr << "STart get template\n";
1240 return state(false);
1244 Session::state(bool full_state)
1246 XMLNode* node = new XMLNode("Session");
1249 // store libardour version, just in case
1251 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
1252 libardour_major_version, libardour_minor_version, libardour_micro_version);
1253 node->add_property("version", string(buf));
1255 /* store configuration settings */
1259 /* store the name */
1260 node->add_property ("name", _name);
1262 if (session_dirs.size() > 1) {
1266 vector<space_and_path>::iterator i = session_dirs.begin();
1267 vector<space_and_path>::iterator next;
1269 ++i; /* skip the first one */
1273 while (i != session_dirs.end()) {
1277 if (next != session_dirs.end()) {
1287 child = node->add_child ("Path");
1288 child->add_content (p);
1292 node->add_child_nocopy (get_options());
1294 child = node->add_child ("Sources");
1297 LockMonitor sl (source_lock, __LINE__, __FILE__);
1299 for (SourceList::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1301 /* Don't save information about FileSources that are empty */
1305 if ((fs = dynamic_cast<FileSource*> ((*siter).second)) != 0) {
1306 if (fs->length() == 0) {
1311 child->add_child_nocopy ((*siter).second->get_state());
1315 child = node->add_child ("Regions");
1318 LockMonitor rl (region_lock, __LINE__, __FILE__);
1320 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1322 /* only store regions not attached to playlists */
1324 if ((*i).second->playlist() == 0) {
1325 child->add_child_nocopy (i->second->state (true));
1330 child = node->add_child ("DiskStreams");
1333 RWLockMonitor dl (diskstream_lock, false, __LINE__, __FILE__);
1334 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1335 if (!(*i)->hidden()) {
1336 child->add_child_nocopy ((*i)->get_state());
1341 node->add_child_nocopy (_locations.get_state());
1343 child = node->add_child ("Connections");
1345 LockMonitor lm (connection_lock, __LINE__, __FILE__);
1346 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1347 if (!(*i)->system_dependent()) {
1348 child->add_child_nocopy ((*i)->get_state());
1353 child = node->add_child ("Routes");
1355 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1357 RoutePublicOrderSorter cmp;
1358 RouteList public_order(routes);
1359 public_order.sort (cmp);
1361 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1362 if (!(*i)->hidden()) {
1364 child->add_child_nocopy ((*i)->get_state());
1366 child->add_child_nocopy ((*i)->get_template());
1373 child = node->add_child ("EditGroups");
1374 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1375 child->add_child_nocopy ((*i)->get_state());
1378 child = node->add_child ("MixGroups");
1379 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1380 child->add_child_nocopy ((*i)->get_state());
1383 child = node->add_child ("Playlists");
1384 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1385 if (!(*i)->hidden()) {
1386 if (!(*i)->empty()) {
1388 child->add_child_nocopy ((*i)->get_state());
1390 child->add_child_nocopy ((*i)->get_template());
1396 child = node->add_child ("UnusedPlaylists");
1397 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1398 if (!(*i)->hidden()) {
1399 if (!(*i)->empty()) {
1401 child->add_child_nocopy ((*i)->get_state());
1403 child->add_child_nocopy ((*i)->get_template());
1411 child = node->add_child ("Click");
1412 child->add_child_nocopy (_click_io->state (full_state));
1416 child = node->add_child ("NamedSelections");
1417 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1419 child->add_child_nocopy ((*i)->get_state());
1424 node->add_child_nocopy (_tempo_map->get_state());
1427 node->add_child_copy (*_extra_xml);
1434 Session::set_state (const XMLNode& node)
1438 const XMLProperty* prop;
1441 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1443 if (node.name() != "Session"){
1444 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1448 StateManager::set_allow_save (false);
1450 if ((prop = node.property ("name")) != 0) {
1451 _name = prop->value ();
1454 IO::disable_ports ();
1455 IO::disable_connecting ();
1457 /* Object loading order:
1474 if (use_config_midi_ports ()) {
1477 if ((child = find_named_node (node, "Path")) != 0) {
1478 /* XXX this XML content stuff horrible API design */
1479 string raid_path = _path + ':' + child->children().front()->content();
1480 setup_raid_path (raid_path);
1482 /* the path is already set */
1485 if ((child = find_named_node (node, "extra")) != 0) {
1486 _extra_xml = new XMLNode (*child);
1489 if ((child = find_named_node (node, "Options")) == 0) {
1490 error << _("Session: XML state has no options section") << endmsg;
1491 } else if (load_options (*child)) {
1494 if ((child = find_named_node (node, "Sources")) == 0) {
1495 error << _("Session: XML state has no sources section") << endmsg;
1497 } else if (load_sources (*child)) {
1501 if ((child = find_named_node (node, "Regions")) == 0) {
1502 error << _("Session: XML state has no Regions section") << endmsg;
1504 } else if (load_regions (*child)) {
1508 if ((child = find_named_node (node, "Playlists")) == 0) {
1509 error << _("Session: XML state has no playlists section") << endmsg;
1511 } else if (load_playlists (*child)) {
1515 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1517 } else if (load_unused_playlists (*child)) {
1521 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1522 if (load_named_selections (*child)) {
1527 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1528 error << _("Session: XML state has no diskstreams section") << endmsg;
1530 } else if (load_diskstreams (*child)) {
1534 if ((child = find_named_node (node, "Connections")) == 0) {
1535 error << _("Session: XML state has no connections section") << endmsg;
1537 } else if (load_connections (*child)) {
1541 if ((child = find_named_node (node, "Locations")) == 0) {
1542 error << _("Session: XML state has no locations section") << endmsg;
1544 } else if (_locations.set_state (*child)) {
1550 if ((location = _locations.auto_loop_location()) != 0) {
1551 set_auto_loop_location (location);
1554 if ((location = _locations.auto_punch_location()) != 0) {
1555 set_auto_punch_location (location);
1558 if ((location = _locations.end_location()) == 0) {
1559 _locations.add (end_location);
1561 end_location = location;
1564 _locations.save_state (_("initial state"));
1566 if ((child = find_named_node (node, "EditGroups")) == 0) {
1567 error << _("Session: XML state has no edit groups section") << endmsg;
1569 } else if (load_edit_groups (*child)) {
1573 if ((child = find_named_node (node, "MixGroups")) == 0) {
1574 error << _("Session: XML state has no mix groups section") << endmsg;
1576 } else if (load_mix_groups (*child)) {
1580 if ((child = find_named_node (node, "TempoMap")) == 0) {
1581 error << _("Session: XML state has no Tempo Map section") << endmsg;
1583 } else if (_tempo_map->set_state (*child)) {
1587 if ((child = find_named_node (node, "Routes")) == 0) {
1588 error << _("Session: XML state has no routes section") << endmsg;
1590 } else if (load_routes (*child)) {
1594 if ((child = find_named_node (node, "Click")) == 0) {
1595 warning << _("Session: XML state has no click section") << endmsg;
1596 } else if (_click_io) {
1597 _click_io->set_state (*child);
1600 /* OK, now we can set edit mode */
1602 set_edit_mode (pending_edit_mode);
1604 /* here beginneth the second phase ... */
1606 StateReady (); /* EMIT SIGNAL */
1608 _state_of_the_state = Clean;
1610 StateManager::set_allow_save (true);
1612 if (state_was_pending) {
1613 save_state (_current_snapshot_name);
1614 remove_pending_capture_state ();
1615 state_was_pending = false;
1621 /* yes, doing it twice doesn't hurt and makes the code easier */
1622 StateManager::set_allow_save (true);
1627 Session::load_routes (const XMLNode& node)
1630 XMLNodeConstIterator niter;
1633 nlist = node.children();
1637 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1639 if ((route = XMLRouteFactory (**niter)) == 0) {
1640 error << _("Session: cannot create Route from XML description.") << endmsg;
1651 Session::XMLRouteFactory (const XMLNode& node)
1653 if (node.name() != "Route") {
1657 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1658 return new AudioTrack (*this, node);
1660 return new Route (*this, node);
1665 Session::load_regions (const XMLNode& node)
1668 XMLNodeConstIterator niter;
1669 AudioRegion* region;
1671 nlist = node.children();
1675 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1677 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1678 error << _("Session: cannot create Region from XML description.") << endmsg;
1686 Session::XMLRegionFactory (const XMLNode& node, bool full)
1688 const XMLProperty* prop;
1691 AudioRegion::SourceList sources;
1692 uint32_t nchans = 1;
1695 if (node.name() != X_("Region")) {
1699 if ((prop = node.property (X_("channels"))) != 0) {
1700 nchans = atoi (prop->value().c_str());
1704 if ((prop = node.property (X_("source-0"))) == 0) {
1705 if ((prop = node.property ("source")) == 0) {
1706 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1711 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1713 if ((source = get_source (s_id)) == 0) {
1714 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1718 sources.push_back(source);
1720 /* pickup other channels */
1722 for (uint32_t n=1; n < nchans; ++n) {
1723 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1724 if ((prop = node.property (buf)) != 0) {
1725 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1727 if ((source = get_source (s_id)) == 0) {
1728 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1731 sources.push_back(source);
1737 return new AudioRegion (sources, node);
1740 catch (failed_constructor& err) {
1746 Session::get_sources_as_xml ()
1749 XMLNode* node = new XMLNode (X_("Sources"));
1750 LockMonitor lm (source_lock, __LINE__, __FILE__);
1752 for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
1753 node->add_child_nocopy ((*i).second->get_state());
1760 Session::path_from_region_name (string name, string identifier)
1762 char buf[PATH_MAX+1];
1764 string dir = discover_best_sound_dir ();
1766 for (n = 0; n < 999999; ++n) {
1767 if (identifier.length()) {
1768 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1769 identifier.c_str(), n);
1771 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1773 if (access (buf, F_OK) != 0) {
1783 Session::load_sources (const XMLNode& node)
1786 XMLNodeConstIterator niter;
1789 nlist = node.children();
1793 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1795 if ((source = XMLSourceFactory (**niter)) == 0) {
1796 error << _("Session: cannot create Source from XML description.") << endmsg;
1804 Session::XMLSourceFactory (const XMLNode& node)
1808 if (node.name() != "Source") {
1813 src = new FileSource (node, frame_rate());
1816 catch (failed_constructor& err) {
1819 src = new SndFileSource (node);
1822 catch (failed_constructor& err) {
1823 error << _("Found a sound file that cannot be used by Ardour. See the progammers.") << endmsg;
1832 Session::save_template (string template_name)
1835 string xml_path, bak_path, template_path;
1837 if (_state_of_the_state & CannotSave) {
1842 string dir = template_dir();
1844 if ((dp = opendir (dir.c_str()))) {
1847 if (mkdir (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)<0) {
1848 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1853 tree.set_root (&get_template());
1856 xml_path += template_name;
1857 xml_path += _template_suffix;
1859 ifstream in(xml_path.c_str());
1862 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1868 if (!tree.write (xml_path)) {
1869 error << _("mix template not saved") << endmsg;
1877 Session::rename_template (string old_name, string new_name)
1879 string old_path = template_dir() + old_name + _template_suffix;
1880 string new_path = template_dir() + new_name + _template_suffix;
1882 return rename (old_path.c_str(), new_path.c_str());
1886 Session::delete_template (string name)
1888 string template_path = template_dir();
1889 template_path += name;
1890 template_path += _template_suffix;
1892 return remove (template_path.c_str());
1896 Session::refresh_disk_space ()
1899 struct statfs statfsbuf;
1900 vector<space_and_path>::iterator i;
1901 LockMonitor lm (space_lock, __LINE__, __FILE__);
1904 /* get freespace on every FS that is part of the session path */
1906 _total_free_4k_blocks = 0;
1908 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1909 statfs ((*i).path.c_str(), &statfsbuf);
1911 scale = statfsbuf.f_bsize/4096.0;
1913 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1914 _total_free_4k_blocks += (*i).blocks;
1920 Session::ensure_sound_dir (string path, string& result)
1925 /* Ensure that the parent directory exists */
1927 if (mkdir (path.c_str(), 0775)) {
1928 if (errno != EEXIST) {
1929 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1934 /* Ensure that the sounds directory exists */
1938 result += sound_dir_name;
1940 if (mkdir (result.c_str(), 0775)) {
1941 if (errno != EEXIST) {
1942 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1949 dead += dead_sound_dir_name;
1951 if (mkdir (dead.c_str(), 0775)) {
1952 if (errno != EEXIST) {
1953 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1960 peak += peak_dir_name;
1962 if (mkdir (peak.c_str(), 0775)) {
1963 if (errno != EEXIST) {
1964 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1969 /* callers expect this to be terminated ... */
1976 Session::discover_best_sound_dir ()
1978 vector<space_and_path>::iterator i;
1981 /* handle common case without system calls */
1983 if (session_dirs.size() == 1) {
1987 /* OK, here's the algorithm we're following here:
1989 We want to select which directory to use for
1990 the next file source to be created. Ideally,
1991 we'd like to use a round-robin process so as to
1992 get maximum performance benefits from splitting
1993 the files across multiple disks.
1995 However, in situations without much diskspace, an
1996 RR approach may end up filling up a filesystem
1997 with new files while others still have space.
1998 Its therefore important to pay some attention to
1999 the freespace in the filesystem holding each
2000 directory as well. However, if we did that by
2001 itself, we'd keep creating new files in the file
2002 system with the most space until it was as full
2003 as all others, thus negating any performance
2004 benefits of this RAID-1 like approach.
2006 So, we use a user-configurable space threshold. If
2007 there are at least 2 filesystems with more than this
2008 much space available, we use RR selection between them.
2009 If not, then we pick the filesystem with the most space.
2011 This gets a good balance between the two
2015 refresh_disk_space ();
2017 int free_enough = 0;
2019 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2020 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2025 if (free_enough >= 2) {
2027 bool found_it = false;
2029 /* use RR selection process, ensuring that the one
2033 i = last_rr_session_dir;
2036 if (++i == session_dirs.end()) {
2037 i = session_dirs.begin();
2040 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2041 if (ensure_sound_dir ((*i).path, result) == 0) {
2042 last_rr_session_dir = i;
2048 } while (i != last_rr_session_dir);
2051 result = sound_dir();
2056 /* pick FS with the most freespace (and that
2057 seems to actually work ...)
2060 vector<space_and_path> sorted;
2061 space_and_path_ascending_cmp cmp;
2063 sorted = session_dirs;
2064 sort (sorted.begin(), sorted.end(), cmp);
2066 for (i = sorted.begin(); i != sorted.end(); ++i) {
2067 if (ensure_sound_dir ((*i).path, result) == 0) {
2068 last_rr_session_dir = i;
2073 /* if the above fails, fall back to the most simplistic solution */
2075 if (i == sorted.end()) {
2084 Session::load_playlists (const XMLNode& node)
2087 XMLNodeConstIterator niter;
2090 nlist = node.children();
2094 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2096 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2097 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2105 Session::load_unused_playlists (const XMLNode& node)
2108 XMLNodeConstIterator niter;
2111 nlist = node.children();
2115 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2117 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2118 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2122 // now manually untrack it
2124 track_playlist (playlist, false);
2132 Session::XMLPlaylistFactory (const XMLNode& node)
2135 return new AudioPlaylist (*this, node);
2138 catch (failed_constructor& err) {
2144 Session::load_named_selections (const XMLNode& node)
2147 XMLNodeConstIterator niter;
2150 nlist = node.children();
2154 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2156 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2157 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2165 Session::XMLNamedSelectionFactory (const XMLNode& node)
2168 return new NamedSelection (*this, node);
2171 catch (failed_constructor& err) {
2177 Session::dead_sound_dir () const
2180 res += dead_sound_dir_name;
2186 Session::sound_dir () const
2189 res += sound_dir_name;
2195 Session::peak_dir () const
2198 res += peak_dir_name;
2204 Session::automation_dir () const
2207 res += "automation/";
2212 Session::template_dir ()
2214 string path = Config->get_user_ardour_path();
2215 path += "templates/";
2221 Session::template_path ()
2225 path += Config->get_user_ardour_path();
2226 if (path[path.length()-1] != ':') {
2229 path += Config->get_system_ardour_path();
2231 vector<string> split_path;
2233 split (path, split_path, ':');
2236 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2238 path += "templates/";
2240 if (distance (i, split_path.end()) != 1) {
2249 Session::load_connections (const XMLNode& node)
2251 XMLNodeList nlist = node.children();
2252 XMLNodeConstIterator niter;
2256 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2257 if ((*niter)->name() == "InputConnection") {
2258 add_connection (new ARDOUR::InputConnection (**niter));
2259 } else if ((*niter)->name() == "OutputConnection") {
2260 add_connection (new ARDOUR::OutputConnection (**niter));
2262 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2271 Session::load_edit_groups (const XMLNode& node)
2273 return load_route_groups (node, true);
2277 Session::load_mix_groups (const XMLNode& node)
2279 return load_route_groups (node, false);
2283 Session::load_route_groups (const XMLNode& node, bool edit)
2285 XMLNodeList nlist = node.children();
2286 XMLNodeConstIterator niter;
2291 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2292 if ((*niter)->name() == "RouteGroup") {
2294 route = add_edit_group ("");
2295 route->set_state (**niter);
2297 route = add_mix_group ("");
2298 route->set_state (**niter);
2307 Session::swap_configuration(Configuration** new_config)
2309 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__); // jlc - WHY?
2310 Configuration* tmp = *new_config;
2311 *new_config = Config;
2317 Session::copy_configuration(Configuration* new_config)
2319 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
2320 new_config = new Configuration(*Config);
2324 state_file_filter (const string &str, void *arg)
2326 return (str.length() > strlen(Session::statefile_suffix()) &&
2327 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2331 bool operator()(const string* a, const string* b) {
2337 remove_end(string* state)
2339 string statename(*state);
2341 string::size_type start,end;
2342 if ((start = statename.find_last_of ('/')) != string::npos) {
2343 statename = statename.substr (start+1);
2346 if ((end = statename.rfind(".ardour")) < 0) {
2347 end = statename.length();
2350 return new string(statename.substr (0, end));
2354 Session::possible_states (string path)
2356 PathScanner scanner;
2357 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2359 transform(states->begin(), states->end(), states->begin(), remove_end);
2362 sort (states->begin(), states->end(), cmp);
2368 Session::possible_states () const
2370 return possible_states(_path);
2374 Session::auto_save()
2376 save_state (_current_snapshot_name);
2380 Session::add_edit_group (string name)
2382 RouteGroup* rg = new RouteGroup (name);
2383 edit_groups.push_back (rg);
2384 edit_group_added (rg); /* EMIT SIGNAL */
2390 Session::add_mix_group (string name)
2392 RouteGroup* rg = new RouteGroup (name, RouteGroup::Relative);
2393 mix_groups.push_back (rg);
2394 mix_group_added (rg); /* EMIT SIGNAL */
2400 Session::mix_group_by_name (string name)
2402 list<RouteGroup *>::iterator i;
2404 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2405 if ((*i)->name() == name) {
2413 Session::edit_group_by_name (string name)
2415 list<RouteGroup *>::iterator i;
2417 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2418 if ((*i)->name() == name) {
2426 Session::set_meter_hold (float val)
2429 MeterHoldChanged(); // emit
2433 Session::set_meter_falloff (float val)
2435 _meter_falloff = val;
2436 MeterFalloffChanged(); // emit
2441 Session::begin_reversible_command (string name, UndoAction* private_undo)
2443 current_cmd.clear ();
2444 current_cmd.set_name (name);
2447 current_cmd.add_undo (*private_undo);
2452 Session::commit_reversible_command (UndoAction* private_redo)
2457 current_cmd.add_redo_no_execute (*private_redo);
2460 gettimeofday (&now, 0);
2461 current_cmd.set_timestamp (now);
2463 history.add (current_cmd);
2466 Session::GlobalRouteBooleanState
2467 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2469 GlobalRouteBooleanState s;
2470 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2472 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2473 if (!(*i)->hidden()) {
2474 RouteBooleanState v;
2477 v.second = ((*i)->*method)();
2486 Session::GlobalRouteMeterState
2487 Session::get_global_route_metering ()
2489 GlobalRouteMeterState s;
2490 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2492 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2493 if (!(*i)->hidden()) {
2497 v.second = (*i)->meter_point();
2507 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2509 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2510 i->first->set_meter_point (i->second, arg);
2515 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2517 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2518 (i->first->*method) (i->second, arg);
2523 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2525 set_global_route_boolean (s, &Route::set_mute, src);
2529 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2531 set_global_route_boolean (s, &Route::set_solo, src);
2535 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2537 set_global_route_boolean (s, &Route::set_record_enable, src);
2541 Session::global_mute_memento (void* src)
2543 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2547 Session::global_metering_memento (void* src)
2549 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2553 Session::global_solo_memento (void* src)
2555 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2559 Session::global_record_enable_memento (void* src)
2561 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2565 template_filter (const string &str, void *arg)
2567 return (str.length() > strlen(Session::template_suffix()) &&
2568 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2572 Session::get_template_list (list<string> &template_names)
2574 vector<string *> *templates;
2575 PathScanner scanner;
2578 path = template_path ();
2580 templates = scanner (path, template_filter, 0, false, true);
2582 vector<string*>::iterator i;
2583 for (i = templates->begin(); i != templates->end(); ++i) {
2584 string fullpath = *(*i);
2587 start = fullpath.find_last_of ('/') + 1;
2588 if ((end = fullpath.find_last_of ('.')) <0) {
2589 end = fullpath.length();
2592 template_names.push_back(fullpath.substr(start, (end-start)));
2597 Session::read_favorite_dirs (FavoriteDirs & favs)
2599 string path = Config->get_user_ardour_path();
2600 path += "/favorite_dirs";
2602 ifstream fav (path.c_str());
2607 if (errno != ENOENT) {
2608 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2619 getline(fav, newfav);
2625 favs.push_back (newfav);
2632 Session::write_favorite_dirs (FavoriteDirs & favs)
2634 string path = Config->get_user_ardour_path();
2635 path += "/favorite_dirs";
2637 ofstream fav (path.c_str());
2643 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2644 fav << (*i) << endl;
2651 accept_all_non_peak_files (const string& path, void *arg)
2653 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2657 accept_all_state_files (const string& path, void *arg)
2659 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2663 Session::find_all_sources (string path, set<string>& result)
2668 if (!tree.read (path)) {
2672 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2677 XMLNodeConstIterator niter;
2679 nlist = node->children();
2683 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2687 if ((prop = (*niter)->property (X_("name"))) == 0) {
2691 if (prop->value()[0] == '/') {
2692 /* external file, ignore */
2696 string path = _path; /* /-terminated */
2697 path += sound_dir_name;
2699 path += prop->value();
2701 result.insert (path);
2708 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2710 PathScanner scanner;
2711 vector<string*>* state_files;
2713 string this_snapshot_path;
2719 if (ripped[ripped.length()-1] == '/') {
2720 ripped = ripped.substr (0, ripped.length() - 1);
2723 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2725 if (state_files == 0) {
2730 this_snapshot_path = _path;
2731 this_snapshot_path += _current_snapshot_name;
2732 this_snapshot_path += _statefile_suffix;
2734 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2736 if (exclude_this_snapshot && **i == this_snapshot_path) {
2740 if (find_all_sources (**i, result) < 0) {
2749 Session::cleanup_sources (Session::cleanup_report& rep)
2751 vector<Source*> dead_sources;
2752 vector<Playlist*> playlists_tbd;
2753 PathScanner scanner;
2755 vector<space_and_path>::iterator i;
2756 vector<space_and_path>::iterator nexti;
2757 vector<string*>* soundfiles;
2758 vector<string> unused;
2759 set<string> all_sources;
2764 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2766 /* step 1: consider deleting all unused playlists */
2768 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2771 status = AskAboutPlaylistDeletion (*x);
2780 playlists_tbd.push_back (*x);
2784 /* leave it alone */
2789 /* now delete any that were marked for deletion */
2791 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2792 PlaylistList::iterator foo;
2794 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2795 unused_playlists.erase (foo);
2800 /* step 2: clear the undo/redo history for all playlists */
2802 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2803 (*x)->drop_all_states ();
2806 /* step 3: find all un-referenced sources */
2811 for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
2813 SourceList::iterator tmp;
2818 /* only remove files that are not in use and have some size
2819 to them. otherwise we remove the current "nascent"
2823 if ((*i).second->use_cnt() == 0 && (*i).second->length() > 0) {
2824 dead_sources.push_back (i->second);
2826 /* remove this source from our own list to avoid us
2827 adding it to the list of all sources below
2836 /* Step 4: get rid of all regions in the region list that use any dead sources
2837 in case the sources themselves don't go away (they might be referenced in
2841 for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2843 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2844 AudioRegionList::iterator tmp;
2852 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2853 if (&ar->source (n) == (*i)) {
2854 /* this region is dead */
2863 /* build a list of all the possible sound directories for the session */
2865 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2870 sound_path += (*i).path;
2871 sound_path += sound_dir_name;
2873 if (nexti != session_dirs.end()) {
2880 /* now do the same thing for the files that ended up in the sounds dir(s)
2881 but are not referenced as sources in any snapshot.
2884 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2886 if (soundfiles == 0) {
2890 /* find all sources, but don't use this snapshot because the
2891 state file on disk still references sources we may have already
2895 find_all_sources_across_snapshots (all_sources, true);
2897 /* add our current source list
2900 for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
2904 if ((fs = dynamic_cast<FileSource*> ((*i).second)) != 0) {
2905 all_sources.insert (fs->path());
2906 } else if ((sfs = dynamic_cast<SndFileSource*> ((*i).second)) != 0) {
2907 all_sources.insert (sfs->path());
2911 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2916 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2926 unused.push_back (spath);
2930 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2932 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2933 struct stat statbuf;
2935 rep.paths.push_back (*x);
2936 if (stat ((*x).c_str(), &statbuf) == 0) {
2937 rep.space += statbuf.st_size;
2942 /* don't move the file across filesystems, just
2943 stick it in the `dead_sound_dir_name' directory
2944 on whichever filesystem it was already on.
2947 newpath = PBD::dirname (*x);
2948 newpath = PBD::dirname (newpath);
2951 newpath += dead_sound_dir_name;
2953 newpath += PBD::basename ((*x));
2955 if (access (newpath.c_str(), F_OK) == 0) {
2957 /* the new path already exists, try versioning */
2959 char buf[PATH_MAX+1];
2963 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2966 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2967 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2971 if (version == 999) {
2972 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2976 newpath = newpath_v;
2981 /* it doesn't exist, or we can't read it or something */
2985 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2986 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2987 (*x), newpath, strerror (errno))
2993 /* see if there an easy to find peakfile for this file, and remove it.
2996 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2997 peakpath += ".peak";
2999 if (access (peakpath.c_str(), W_OK) == 0) {
3000 if (::unlink (peakpath.c_str()) != 0) {
3001 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3002 peakpath, _path, strerror (errno))
3004 /* try to back out */
3005 rename (newpath.c_str(), _path.c_str());
3014 /* dump the history list */
3018 /* save state so we don't end up a session file
3019 referring to non-existent sources.
3025 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3030 Session::cleanup_trash_sources (Session::cleanup_report& rep)
3032 vector<space_and_path>::iterator i;
3033 string dead_sound_dir;
3034 struct dirent* dentry;
3035 struct stat statbuf;
3041 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3043 dead_sound_dir = (*i).path;
3044 dead_sound_dir += dead_sound_dir_name;
3046 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
3050 while ((dentry = readdir (dead)) != 0) {
3052 /* avoid '.' and '..' */
3054 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
3055 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3061 fullpath = dead_sound_dir;
3063 fullpath += dentry->d_name;
3065 if (stat (fullpath.c_str(), &statbuf)) {
3069 if (!S_ISREG (statbuf.st_mode)) {
3073 if (unlink (fullpath.c_str())) {
3074 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3075 fullpath, strerror (errno))
3079 rep.paths.push_back (dentry->d_name);
3080 rep.space += statbuf.st_size;
3091 Session::set_dirty ()
3093 bool was_dirty = dirty();
3095 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3098 DirtyChanged(); /* EMIT SIGNAL */
3104 Session::set_clean ()
3106 bool was_dirty = dirty();
3108 _state_of_the_state = Clean;
3111 DirtyChanged(); /* EMIT SIGNAL */