2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include <sigc++/bind.h>
28 #include <cstdio> /* snprintf(3) ... grrr */
43 #include <sys/mount.h>
44 #include <sys/param.h>
47 #include <midi++/mmc.h>
48 #include <midi++/port.h>
49 #include <pbd/error.h>
50 #include <pbd/dirname.h>
51 #include <pbd/lockmonitor.h>
52 #include <pbd/pathscanner.h>
53 #include <pbd/pthread_utils.h>
54 #include <pbd/basename.h>
55 #include <pbd/strsplit.h>
57 #include <ardour/audioengine.h>
58 #include <ardour/configuration.h>
59 #include <ardour/session.h>
60 #include <ardour/diskstream.h>
61 #include <ardour/utils.h>
62 #include <ardour/audioplaylist.h>
63 #include <ardour/source.h>
64 #include <ardour/filesource.h>
65 #include <ardour/destructive_filesource.h>
66 #include <ardour/sndfilesource.h>
67 #include <ardour/sndfile_helpers.h>
68 #include <ardour/auditioner.h>
69 #include <ardour/export.h>
70 #include <ardour/redirect.h>
71 #include <ardour/send.h>
72 #include <ardour/insert.h>
73 #include <ardour/connection.h>
74 #include <ardour/slave.h>
75 #include <ardour/tempo.h>
76 #include <ardour/audio_track.h>
77 #include <ardour/cycle_timer.h>
78 #include <ardour/utils.h>
79 #include <ardour/named_selection.h>
80 #include <ardour/version.h>
81 #include <ardour/location.h>
82 #include <ardour/audioregion.h>
83 #include <ardour/crossfade.h>
89 using namespace ARDOUR;
92 Session::first_stage_init (string fullpath, string snapshot_name)
94 if (fullpath.length() == 0) {
95 throw failed_constructor();
99 if (!realpath(fullpath.c_str(), buf) && (errno != ENOENT)) {
100 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
101 throw failed_constructor();
105 if (_path[_path.length()-1] != '/') {
109 /* these two are just provisional settings. set_state()
110 will likely override them.
113 _name = _current_snapshot_name = snapshot_name;
114 setup_raid_path (_path);
116 _current_frame_rate = _engine.frame_rate ();
117 _tempo_map = new TempoMap (_current_frame_rate);
118 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
120 atomic_set (&processing_prohibited, 0);
123 _transport_speed = 0;
124 _last_transport_speed = 0;
125 transport_sub_state = 0;
126 _transport_frame = 0;
128 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
129 _end_location_is_free = true;
130 atomic_set (&_record_status, Disabled);
135 seamless_loop = false;
136 loop_changing = false;
138 crossfades_active = false;
141 _last_roll_location = 0;
142 _last_record_location = 0;
143 pending_locate_frame = 0;
144 pending_locate_roll = false;
145 pending_locate_flush = false;
146 dstream_buffer_size = 0;
148 state_was_pending = false;
150 outbound_mtc_smpte_frame = 0;
151 next_quarter_frame_to_send = -1;
152 current_block_size = 0;
153 _solo_latched = true;
154 _solo_model = InverseMute;
155 solo_update_disabled = false;
156 currently_soloing = false;
157 _worst_output_latency = 0;
158 _worst_input_latency = 0;
159 _worst_track_latency = 0;
160 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
163 butler_mixdown_buffer = 0;
164 butler_gain_buffer = 0;
167 midi_feedback = false;
170 post_transport_work = PostTransportWork (0);
171 atomic_set (&butler_should_do_transport_work, 0);
172 atomic_set (&butler_active, 0);
173 atomic_set (&_playback_load, 100);
174 atomic_set (&_capture_load, 100);
175 atomic_set (&_playback_load_min, 100);
176 atomic_set (&_capture_load_min, 100);
177 pending_audition_region = 0;
179 pending_edit_mode = _edit_mode;
183 input_auto_connect = AutoConnectOption (0);
184 output_auto_connect = AutoConnectOption (0);
185 _have_captured = false;
186 waiting_to_start = false;
188 _gain_automation_buffer = 0;
189 _pan_automation_buffer = 0;
191 pending_abort = false;
192 layer_model = MoveAddHigher;
193 xfade_model = ShortCrossfade;
195 /* allocate conversion buffers */
196 _conversion_buffers[ButlerContext] = new char[DiskStream::disk_io_frames() * 4];
197 _conversion_buffers[TransportContext] = new char[DiskStream::disk_io_frames() * 4];
199 /* default short fade = 15ms */
201 Crossfade::set_short_xfade_length ((jack_nframes_t) floor ((15.0 * frame_rate()) / 1000.0));
203 last_mmc_step.tv_sec = 0;
204 last_mmc_step.tv_usec = 0;
207 preroll.type = AnyTime::Frames;
209 postroll.type = AnyTime::Frames;
212 /* click sounds are unset by default, which causes us to internal
213 waveforms for clicks.
218 click_requested = false;
220 click_emphasis_data = 0;
222 click_emphasis_length = 0;
224 process_function = &Session::process_with_events;
228 _smpte_offset_negative = true;
229 last_smpte_valid = false;
231 last_rr_session_dir = session_dirs.begin();
232 refresh_disk_space ();
234 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
236 /* default configuration */
238 do_not_record_plugins = false;
239 over_length_short = 2;
240 over_length_long = 10;
241 send_midi_timecode = false;
242 send_midi_machine_control = false;
243 shuttle_speed_factor = 1.0;
244 shuttle_speed_threshold = 5;
246 _meter_hold = 100; // XXX unknown units: number of calls to meter::set()
247 _meter_falloff = 1.5f; // XXX unknown units: refresh_rate
253 average_slave_delta = 1800;
254 have_first_delta_accumulator = false;
255 delta_accumulator_cnt = 0;
256 slave_state = Stopped;
258 /* default SMPTE type is 30 FPS, non-drop */
260 set_smpte_type (30.0, false);
262 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
264 /* These are all static "per-class" signals */
266 Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
267 Source::SourceCreated.connect (mem_fun (*this, &Session::add_source));
268 Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
269 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
270 DiskStream::DiskStreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
271 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
273 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
275 /* stop IO objects from doing stuff until we're ready for them */
277 IO::disable_panners ();
278 IO::disable_ports ();
279 IO::disable_connecting ();
283 Session::second_stage_init (bool new_session)
285 SndFileSource::set_peak_dir (peak_dir());
288 if (load_state (_current_snapshot_name)) {
291 remove_empty_sounds ();
294 if (start_butler_thread()) {
298 if (start_midi_thread ()) {
302 if (init_feedback ()) {
307 if (set_state (*state_tree->root())) {
312 /* we can't save till after ::when_engine_running() is called,
313 because otherwise we save state with no connections made.
314 therefore, we reset _state_of_the_state because ::set_state()
315 will have cleared it.
317 we also have to include Loading so that any events that get
318 generated between here and the end of ::when_engine_running()
319 will be processed directly rather than queued.
322 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
324 // set_auto_input (true);
325 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
326 _locations.added.connect (mem_fun (this, &Session::locations_added));
327 setup_click_sounds (0);
328 setup_midi_control ();
330 /* Pay attention ... */
332 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
333 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
335 if (_engine.running()) {
336 when_engine_running();
338 first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
341 send_full_time_code ();
342 _engine.transport_locate (0);
343 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
344 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
345 send_all_midi_feedback();
348 _end_location_is_free = true;
350 _end_location_is_free = false;
357 Session::raid_path () const
361 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
366 return path.substr (0, path.length() - 1); // drop final colon
370 Session::set_raid_path (string path)
372 /* public-access to setup_raid_path() */
374 setup_raid_path (path);
378 Session::setup_raid_path (string path)
380 string::size_type colon;
384 string::size_type len = path.length();
389 if (path.length() == 0) {
393 session_dirs.clear ();
395 for (string::size_type n = 0; n < len; ++n) {
396 if (path[n] == ':') {
403 /* no multiple search path, just one directory (common case) */
407 session_dirs.push_back (sp);
409 FileSource::set_search_path (path + sound_dir_name);
416 while ((colon = remaining.find_first_of (':')) != string::npos) {
419 sp.path = remaining.substr (0, colon);
422 if (fspath[fspath.length()-1] != '/') {
425 fspath += sound_dir_name;
428 session_dirs.push_back (sp);
430 remaining = remaining.substr (colon+1);
433 if (remaining.length()) {
439 if (fspath[fspath.length()-1] != '/') {
442 fspath += sound_dir_name;
444 session_dirs.push_back (sp);
447 /* set the FileSource search path */
449 FileSource::set_search_path (fspath);
451 /* reset the round-robin soundfile path thingie */
453 last_rr_session_dir = session_dirs.begin();
457 Session::create (bool& new_session, string* mix_template, jack_nframes_t initial_length)
461 if (mkdir (_path.c_str(), 0755) < 0) {
462 if (errno == EEXIST) {
465 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
474 if (mkdir (dir.c_str(), 0755) < 0) {
475 if (errno != EEXIST) {
476 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
483 if (mkdir (dir.c_str(), 0755) < 0) {
484 if (errno != EEXIST) {
485 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
492 if (mkdir (dir.c_str(), 0755) < 0) {
493 if (errno != EEXIST) {
494 error << string_compose(_("Session: cannot create session tape dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
499 dir = dead_sound_dir ();
501 if (mkdir (dir.c_str(), 0755) < 0) {
502 if (errno != EEXIST) {
503 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
508 dir = automation_dir ();
510 if (mkdir (dir.c_str(), 0755) < 0) {
511 if (errno != EEXIST) {
512 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
518 /* check new_session so we don't overwrite an existing one */
522 std::string in_path = *mix_template;
524 ifstream in(in_path.c_str());
527 string out_path = _path;
529 out_path += _statefile_suffix;
531 ofstream out(out_path.c_str());
536 // okay, session is set up. Treat like normal saved
537 // session from now on.
543 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
549 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
556 warning << _("Session already exists. Not overwriting") << endmsg;
563 /* set an initial end point */
565 end_location->set_end (initial_length);
566 _locations.add (end_location);
568 _state_of_the_state = Clean;
570 if (save_state (_current_snapshot_name)) {
579 Session::load_diskstreams (const XMLNode& node)
582 XMLNodeConstIterator citer;
584 clist = node.children();
586 for (citer = clist.begin(); citer != clist.end(); ++citer) {
591 dstream = new DiskStream (*this, **citer);
592 /* added automatically by DiskStreamCreated handler */
595 catch (failed_constructor& err) {
596 error << _("Session: could not load diskstream via XML state") << endmsg;
605 Session::remove_pending_capture_state ()
610 xml_path += _current_snapshot_name;
611 xml_path += _pending_suffix;
613 unlink (xml_path.c_str());
617 Session::save_state (string snapshot_name, bool pending)
623 if (_state_of_the_state & CannotSave) {
627 tree.set_root (&get_state());
629 if (snapshot_name.empty()) {
630 snapshot_name = _current_snapshot_name;
636 xml_path += snapshot_name;
637 xml_path += _statefile_suffix;
641 // Make backup of state file
643 if ((access (xml_path.c_str(), F_OK) == 0) &&
644 (rename(xml_path.c_str(), bak_path.c_str()))) {
645 error << _("could not backup old state file, current state not saved.") << endmsg;
652 xml_path += snapshot_name;
653 xml_path += _pending_suffix;
657 if (!tree.write (xml_path)) {
658 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
660 /* don't leave a corrupt file lying around if it is
664 if (unlink (xml_path.c_str())) {
665 error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
668 if (rename (bak_path.c_str(), xml_path.c_str())) {
669 error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
679 bool was_dirty = dirty();
681 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
684 DirtyChanged (); /* EMIT SIGNAL */
687 StateSaved (snapshot_name); /* EMIT SIGNAL */
694 Session::restore_state (string snapshot_name)
696 if (load_state (snapshot_name) == 0) {
697 set_state (*state_tree->root());
704 Session::load_state (string snapshot_name)
713 state_was_pending = false;
715 /* check for leftover pending state from a crashed capture attempt */
718 xmlpath += snapshot_name;
719 xmlpath += _pending_suffix;
721 if (!access (xmlpath.c_str(), F_OK)) {
723 /* there is pending state from a crashed capture attempt */
725 if (AskAboutPendingState()) {
726 state_was_pending = true;
730 if (!state_was_pending) {
733 xmlpath += snapshot_name;
734 xmlpath += _statefile_suffix;
737 if (access (xmlpath.c_str(), F_OK)) {
738 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
742 state_tree = new XMLTree;
746 if (state_tree->read (xmlpath)) {
749 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
758 Session::load_options (const XMLNode& node)
762 bool have_fade_msecs = false;
763 bool have_fade_steepness = false;
764 float fade_msecs = 0;
765 float fade_steepness = 0;
766 SlaveSource slave_src = None;
768 LocaleGuard lg (X_("POSIX"));
770 if ((child = find_named_node (node, "input-auto-connect")) != 0) {
771 if ((prop = child->property ("val")) != 0) {
772 sscanf (prop->value().c_str(), "%x", &x);
773 input_auto_connect = AutoConnectOption (x);
777 if ((child = find_named_node (node, "output-auto-connect")) != 0) {
778 if ((prop = child->property ("val")) != 0) {
779 sscanf (prop->value().c_str(), "%x", &x);
780 output_auto_connect = AutoConnectOption (x);
784 if ((child = find_named_node (node, "slave")) != 0) {
785 if ((prop = child->property ("type")) != 0) {
786 if (prop->value() == "none") {
788 } else if (prop->value() == "mtc") {
790 } else if (prop->value() == "jack") {
793 set_slave_source (slave_src, 0);
797 /* we cannot set edit mode if we are loading a session,
798 because it might destroy the playlist's positioning
801 if ((child = find_named_node (node, "edit-mode")) != 0) {
802 if ((prop = child->property ("val")) != 0) {
803 if (prop->value() == "slide") {
804 pending_edit_mode = Slide;
805 } else if (prop->value() == "splice") {
806 pending_edit_mode = Splice;
811 if ((child = find_named_node (node, "send-midi-timecode")) != 0) {
812 if ((prop = child->property ("val")) != 0) {
813 bool x = (prop->value() == "yes");
814 send_mtc = !x; /* force change in value */
818 if ((child = find_named_node (node, "send-midi-machine-control")) != 0) {
819 if ((prop = child->property ("val")) != 0) {
820 bool x = (prop->value() == "yes");
821 send_mmc = !x; /* force change in value */
822 set_send_mmc (prop->value() == "yes");
825 if ((child = find_named_node (node, "max-level")) != 0) {
826 if ((prop = child->property ("val")) != 0) {
827 max_level = atoi (prop->value().c_str());
830 if ((child = find_named_node (node, "min-level")) != 0) {
831 if ((prop = child->property ("val")) != 0) {
832 min_level = atoi (prop->value().c_str());
835 if ((child = find_named_node (node, "meter-hold")) != 0) {
836 if ((prop = child->property ("val")) != 0) {
837 _meter_hold = atof (prop->value().c_str());
840 if ((child = find_named_node (node, "meter-falloff")) != 0) {
841 if ((prop = child->property ("val")) != 0) {
842 _meter_falloff = atof (prop->value().c_str());
845 if ((child = find_named_node (node, "long-over-length")) != 0) {
846 if ((prop = child->property ("val")) != 0) {
847 over_length_long = atoi (prop->value().c_str());
850 if ((child = find_named_node (node, "short-over-length")) != 0) {
851 if ((prop = child->property ("val")) != 0) {
852 over_length_short = atoi (prop->value().c_str());
855 if ((child = find_named_node (node, "shuttle-speed-factor")) != 0) {
856 if ((prop = child->property ("val")) != 0) {
857 shuttle_speed_factor = atof (prop->value().c_str());
860 if ((child = find_named_node (node, "shuttle-speed-threshold")) != 0) {
861 if ((prop = child->property ("val")) != 0) {
862 shuttle_speed_threshold = atof (prop->value().c_str());
865 if ((child = find_named_node (node, "rf-speed")) != 0) {
866 if ((prop = child->property ("val")) != 0) {
867 rf_speed = atof (prop->value().c_str());
870 if ((child = find_named_node (node, "smpte-frames-per-second")) != 0) {
871 if ((prop = child->property ("val")) != 0) {
872 set_smpte_type( atof (prop->value().c_str()), smpte_drop_frames );
875 if ((child = find_named_node (node, "smpte-drop-frames")) != 0) {
876 if ((prop = child->property ("val")) != 0) {
877 set_smpte_type( smpte_frames_per_second, (prop->value() == "yes") );
880 if ((child = find_named_node (node, "smpte-offset")) != 0) {
881 if ((prop = child->property ("val")) != 0) {
882 set_smpte_offset( atoi (prop->value().c_str()) );
885 if ((child = find_named_node (node, "smpte-offset-negative")) != 0) {
886 if ((prop = child->property ("val")) != 0) {
887 set_smpte_offset_negative( (prop->value() == "yes") );
890 if ((child = find_named_node (node, "click-sound")) != 0) {
891 if ((prop = child->property ("val")) != 0) {
892 click_sound = prop->value();
895 if ((child = find_named_node (node, "click-emphasis-sound")) != 0) {
896 if ((prop = child->property ("val")) != 0) {
897 click_emphasis_sound = prop->value();
901 if ((child = find_named_node (node, "solo-model")) != 0) {
902 if ((prop = child->property ("val")) != 0) {
903 if (prop->value() == "SoloBus")
904 _solo_model = SoloBus;
906 _solo_model = InverseMute;
910 /* BOOLEAN OPTIONS */
912 if ((child = find_named_node (node, "auto-play")) != 0) {
913 if ((prop = child->property ("val")) != 0) {
914 set_auto_play (prop->value() == "yes");
917 if ((child = find_named_node (node, "auto-input")) != 0) {
918 if ((prop = child->property ("val")) != 0) {
919 set_auto_input (prop->value() == "yes");
922 if ((child = find_named_node (node, "seamless-loop")) != 0) {
923 if ((prop = child->property ("val")) != 0) {
924 set_seamless_loop (prop->value() == "yes");
927 if ((child = find_named_node (node, "punch-in")) != 0) {
928 if ((prop = child->property ("val")) != 0) {
929 set_punch_in (prop->value() == "yes");
932 if ((child = find_named_node (node, "punch-out")) != 0) {
933 if ((prop = child->property ("val")) != 0) {
934 set_punch_out (prop->value() == "yes");
937 if ((child = find_named_node (node, "auto-return")) != 0) {
938 if ((prop = child->property ("val")) != 0) {
939 set_auto_return (prop->value() == "yes");
942 if ((child = find_named_node (node, "send-mtc")) != 0) {
943 if ((prop = child->property ("val")) != 0) {
944 set_send_mtc (prop->value() == "yes");
947 if ((child = find_named_node (node, "mmc-control")) != 0) {
948 if ((prop = child->property ("val")) != 0) {
949 set_mmc_control (prop->value() == "yes");
952 if ((child = find_named_node (node, "midi-control")) != 0) {
953 if ((prop = child->property ("val")) != 0) {
954 set_midi_control (prop->value() == "yes");
957 if ((child = find_named_node (node, "midi-feedback")) != 0) {
958 if ((prop = child->property ("val")) != 0) {
959 set_midi_feedback (prop->value() == "yes");
962 // Legacy support for <recording-plugins>
963 if ((child = find_named_node (node, "recording-plugins")) != 0) {
964 if ((prop = child->property ("val")) != 0) {
965 set_do_not_record_plugins (prop->value() == "no");
968 if ((child = find_named_node (node, "do-not-record-plugins")) != 0) {
969 if ((prop = child->property ("val")) != 0) {
970 set_do_not_record_plugins (prop->value() == "yes");
973 if ((child = find_named_node (node, "crossfades-active")) != 0) {
974 if ((prop = child->property ("val")) != 0) {
975 set_crossfades_active (prop->value() == "yes");
978 if ((child = find_named_node (node, "audible-click")) != 0) {
979 if ((prop = child->property ("val")) != 0) {
980 set_clicking (prop->value() == "yes");
984 if ((child = find_named_node (node, "layer-model")) != 0) {
985 if ((prop = child->property ("val")) != 0) {
986 if (prop->value() == X_("LaterHigher")) {
987 set_layer_model (LaterHigher);
988 } else if (prop->value() == X_("AddHigher")) {
989 set_layer_model (AddHigher);
991 set_layer_model (MoveAddHigher);
996 if ((child = find_named_node (node, "xfade-model")) != 0) {
997 if ((prop = child->property ("val")) != 0) {
998 if (prop->value() == X_("Short")) {
999 set_xfade_model (ShortCrossfade);
1001 set_xfade_model (FullCrossfade);
1006 if ((child = find_named_node (node, "short-xfade-length")) != 0) {
1007 if ((prop = child->property ("val")) != 0) {
1008 /* value is stored as a fractional seconds */
1009 float secs = atof (prop->value().c_str());
1010 Crossfade::set_short_xfade_length ((jack_nframes_t) floor (secs * frame_rate()));
1014 if ((child = find_named_node (node, "full-xfades-unmuted")) != 0) {
1015 if ((prop = child->property ("val")) != 0) {
1016 crossfades_active = (prop->value() == "yes");
1022 if ((child = find_named_node (node, "default-fade-steepness")) != 0) {
1023 if ((prop = child->property ("val")) != 0) {
1024 fade_steepness = atof (prop->value().c_str());
1025 have_fade_steepness = true;
1028 if ((child = find_named_node (node, "default-fade-msec")) != 0) {
1029 if ((prop = child->property ("val")) != 0) {
1030 fade_msecs = atof (prop->value().c_str());
1031 have_fade_msecs = true;
1035 if (have_fade_steepness || have_fade_msecs) {
1036 // set_default_fade (fade_steepness, fade_msecs);
1043 Session::get_options () const
1048 LocaleGuard lg (X_("POSIX"));
1050 opthead = new XMLNode ("Options");
1052 SlaveSource src = slave_source ();
1056 src_string = "none";
1062 src_string = "jack";
1065 child = opthead->add_child ("slave");
1066 child->add_property ("type", src_string);
1068 child = opthead->add_child ("send-midi-timecode");
1069 child->add_property ("val", send_midi_timecode?"yes":"no");
1071 child = opthead->add_child ("send-midi-machine-control");
1072 child->add_property ("val", send_midi_machine_control?"yes":"no");
1074 snprintf (buf, sizeof(buf)-1, "%x", (int) input_auto_connect);
1075 child = opthead->add_child ("input-auto-connect");
1076 child->add_property ("val", buf);
1078 snprintf (buf, sizeof(buf)-1, "%x", (int) output_auto_connect);
1079 child = opthead->add_child ("output-auto-connect");
1080 child->add_property ("val", buf);
1082 snprintf (buf, sizeof(buf)-1, "%d", max_level);
1083 child = opthead->add_child ("max-level");
1084 child->add_property ("val", buf);
1086 snprintf (buf, sizeof(buf)-1, "%d", min_level);
1087 child = opthead->add_child ("min-level");
1088 child->add_property ("val", buf);
1090 snprintf (buf, sizeof(buf)-1, "%f", _meter_hold);
1091 child = opthead->add_child ("meter-hold");
1092 child->add_property ("val", buf);
1094 snprintf (buf, sizeof(buf)-1, "%f", _meter_falloff);
1095 child = opthead->add_child ("meter-falloff");
1096 child->add_property ("val", buf);
1098 snprintf (buf, sizeof(buf)-1, "%u", over_length_long);
1099 child = opthead->add_child ("long-over-length");
1100 child->add_property ("val", buf);
1102 snprintf (buf, sizeof(buf)-1, "%u", over_length_short);
1103 child = opthead->add_child ("short-over-length");
1104 child->add_property ("val", buf);
1106 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_factor);
1107 child = opthead->add_child ("shuttle-speed-factor");
1108 child->add_property ("val", buf);
1110 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_threshold);
1111 child = opthead->add_child ("shuttle-speed-threshold");
1112 child->add_property ("val", buf);
1114 snprintf (buf, sizeof(buf)-1, "%f", rf_speed);
1115 child = opthead->add_child ("rf-speed");
1116 child->add_property ("val", buf);
1118 snprintf (buf, sizeof(buf)-1, "%.2f", smpte_frames_per_second);
1119 child = opthead->add_child ("smpte-frames-per-second");
1120 child->add_property ("val", buf);
1122 child = opthead->add_child ("smpte-drop-frames");
1123 child->add_property ("val", smpte_drop_frames ? "yes" : "no");
1125 snprintf (buf, sizeof(buf)-1, "%u", smpte_offset ());
1126 child = opthead->add_child ("smpte-offset");
1127 child->add_property ("val", buf);
1129 child = opthead->add_child ("smpte-offset-negative");
1130 child->add_property ("val", smpte_offset_negative () ? "yes" : "no");
1132 child = opthead->add_child ("edit-mode");
1133 switch (_edit_mode) {
1135 child->add_property ("val", "splice");
1139 child->add_property ("val", "slide");
1143 child = opthead->add_child ("auto-play");
1144 child->add_property ("val", get_auto_play () ? "yes" : "no");
1145 child = opthead->add_child ("auto-input");
1146 child->add_property ("val", get_auto_input () ? "yes" : "no");
1147 child = opthead->add_child ("seamless-loop");
1148 child->add_property ("val", get_seamless_loop () ? "yes" : "no");
1149 child = opthead->add_child ("punch-in");
1150 child->add_property ("val", get_punch_in () ? "yes" : "no");
1151 child = opthead->add_child ("punch-out");
1152 child->add_property ("val", get_punch_out () ? "yes" : "no");
1153 child = opthead->add_child ("all-safe");
1154 child->add_property ("val", get_all_safe () ? "yes" : "no");
1155 child = opthead->add_child ("auto-return");
1156 child->add_property ("val", get_auto_return () ? "yes" : "no");
1157 child = opthead->add_child ("mmc-control");
1158 child->add_property ("val", get_mmc_control () ? "yes" : "no");
1159 child = opthead->add_child ("midi-control");
1160 child->add_property ("val", get_midi_control () ? "yes" : "no");
1161 child = opthead->add_child ("midi-feedback");
1162 child->add_property ("val", get_midi_feedback () ? "yes" : "no");
1163 child = opthead->add_child ("do-not-record-plugins");
1164 child->add_property ("val", get_do_not_record_plugins () ? "yes" : "no");
1165 child = opthead->add_child ("auto-crossfade");
1166 child->add_property ("val", get_crossfades_active () ? "yes" : "no");
1167 child = opthead->add_child ("audible-click");
1168 child->add_property ("val", get_clicking () ? "yes" : "no");
1170 if (click_sound.length()) {
1171 child = opthead->add_child ("click-sound");
1172 child->add_property ("val", click_sound);
1175 if (click_emphasis_sound.length()) {
1176 child = opthead->add_child ("click-emphasis-sound");
1177 child->add_property ("val", click_emphasis_sound);
1180 child = opthead->add_child ("solo-model");
1181 child->add_property ("val", _solo_model == SoloBus ? "SoloBus" : "InverseMute");
1183 child = opthead->add_child ("layer-model");
1184 switch (layer_model) {
1186 child->add_property ("val", X_("LaterHigher"));
1189 child->add_property ("val", X_("MoveAddHigher"));
1192 child->add_property ("val", X_("AddHigher"));
1196 child = opthead->add_child ("xfade-model");
1197 switch (xfade_model) {
1199 child->add_property ("val", X_("Full"));
1201 case ShortCrossfade:
1202 child->add_property ("val", X_("Short"));
1205 child = opthead->add_child ("short-xfade-length");
1206 /* store as fractions of a second */
1207 snprintf (buf, sizeof(buf)-1, "%f",
1208 (float) Crossfade::short_xfade_length() / frame_rate());
1209 child->add_property ("val", buf);
1211 child = opthead->add_child ("full-xfades-unmuted");
1212 child->add_property ("val", crossfades_active ? "yes" : "no");
1218 Session::get_state()
1224 Session::get_template()
1226 /* if we don't disable rec-enable, diskstreams
1227 will believe they need to store their capture
1228 sources in their state node.
1233 return state(false);
1237 Session::state(bool full_state)
1239 XMLNode* node = new XMLNode("Session");
1242 // store libardour version, just in case
1244 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
1245 libardour_major_version, libardour_minor_version, libardour_micro_version);
1246 node->add_property("version", string(buf));
1248 /* store configuration settings */
1252 /* store the name */
1253 node->add_property ("name", _name);
1255 if (session_dirs.size() > 1) {
1259 vector<space_and_path>::iterator i = session_dirs.begin();
1260 vector<space_and_path>::iterator next;
1262 ++i; /* skip the first one */
1266 while (i != session_dirs.end()) {
1270 if (next != session_dirs.end()) {
1280 child = node->add_child ("Path");
1281 child->add_content (p);
1285 node->add_child_nocopy (get_options());
1287 child = node->add_child ("Sources");
1290 LockMonitor sl (source_lock, __LINE__, __FILE__);
1292 for (SourceList::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1294 /* Don't save information about FileSources that are empty */
1298 if ((fs = dynamic_cast<FileSource*> ((*siter).second)) != 0) {
1299 if (fs->length() == 0) {
1304 child->add_child_nocopy ((*siter).second->get_state());
1308 child = node->add_child ("Regions");
1311 LockMonitor rl (region_lock, __LINE__, __FILE__);
1313 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1315 /* only store regions not attached to playlists */
1317 if ((*i).second->playlist() == 0) {
1318 child->add_child_nocopy (i->second->state (true));
1323 child = node->add_child ("DiskStreams");
1326 RWLockMonitor dl (diskstream_lock, false, __LINE__, __FILE__);
1327 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1328 if (!(*i)->hidden()) {
1329 child->add_child_nocopy ((*i)->get_state());
1334 node->add_child_nocopy (_locations.get_state());
1336 child = node->add_child ("Connections");
1338 LockMonitor lm (connection_lock, __LINE__, __FILE__);
1339 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1340 if (!(*i)->system_dependent()) {
1341 child->add_child_nocopy ((*i)->get_state());
1346 child = node->add_child ("Routes");
1348 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1350 RoutePublicOrderSorter cmp;
1351 RouteList public_order(routes);
1352 public_order.sort (cmp);
1354 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1355 if (!(*i)->hidden()) {
1357 child->add_child_nocopy ((*i)->get_state());
1359 child->add_child_nocopy ((*i)->get_template());
1366 child = node->add_child ("EditGroups");
1367 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1368 child->add_child_nocopy ((*i)->get_state());
1371 child = node->add_child ("MixGroups");
1372 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1373 child->add_child_nocopy ((*i)->get_state());
1376 child = node->add_child ("Playlists");
1377 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1378 if (!(*i)->hidden()) {
1379 if (!(*i)->empty()) {
1381 child->add_child_nocopy ((*i)->get_state());
1383 child->add_child_nocopy ((*i)->get_template());
1389 child = node->add_child ("UnusedPlaylists");
1390 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_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());
1404 child = node->add_child ("Click");
1405 child->add_child_nocopy (_click_io->state (full_state));
1409 child = node->add_child ("NamedSelections");
1410 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1412 child->add_child_nocopy ((*i)->get_state());
1417 node->add_child_nocopy (_tempo_map->get_state());
1420 node->add_child_copy (*_extra_xml);
1427 Session::set_state (const XMLNode& node)
1431 const XMLProperty* prop;
1434 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1436 if (node.name() != "Session"){
1437 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1441 StateManager::prohibit_save ();
1443 if ((prop = node.property ("name")) != 0) {
1444 _name = prop->value ();
1447 IO::disable_ports ();
1448 IO::disable_connecting ();
1450 /* Object loading order:
1467 if (use_config_midi_ports ()) {
1470 if ((child = find_named_node (node, "Path")) != 0) {
1471 /* XXX this XML content stuff horrible API design */
1472 string raid_path = _path + ':' + child->children().front()->content();
1473 setup_raid_path (raid_path);
1475 /* the path is already set */
1478 if ((child = find_named_node (node, "extra")) != 0) {
1479 _extra_xml = new XMLNode (*child);
1482 if ((child = find_named_node (node, "Options")) == 0) {
1483 error << _("Session: XML state has no options section") << endmsg;
1484 } else if (load_options (*child)) {
1487 if ((child = find_named_node (node, "Sources")) == 0) {
1488 error << _("Session: XML state has no sources section") << endmsg;
1490 } else if (load_sources (*child)) {
1494 if ((child = find_named_node (node, "Regions")) == 0) {
1495 error << _("Session: XML state has no Regions section") << endmsg;
1497 } else if (load_regions (*child)) {
1501 if ((child = find_named_node (node, "Playlists")) == 0) {
1502 error << _("Session: XML state has no playlists section") << endmsg;
1504 } else if (load_playlists (*child)) {
1508 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1510 } else if (load_unused_playlists (*child)) {
1514 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1515 if (load_named_selections (*child)) {
1520 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1521 error << _("Session: XML state has no diskstreams section") << endmsg;
1523 } else if (load_diskstreams (*child)) {
1527 if ((child = find_named_node (node, "Connections")) == 0) {
1528 error << _("Session: XML state has no connections section") << endmsg;
1530 } else if (load_connections (*child)) {
1534 if ((child = find_named_node (node, "Locations")) == 0) {
1535 error << _("Session: XML state has no locations section") << endmsg;
1537 } else if (_locations.set_state (*child)) {
1543 if ((location = _locations.auto_loop_location()) != 0) {
1544 set_auto_loop_location (location);
1547 if ((location = _locations.auto_punch_location()) != 0) {
1548 set_auto_punch_location (location);
1551 if ((location = _locations.end_location()) == 0) {
1552 _locations.add (end_location);
1554 end_location = location;
1557 _locations.save_state (_("initial state"));
1559 if ((child = find_named_node (node, "EditGroups")) == 0) {
1560 error << _("Session: XML state has no edit groups section") << endmsg;
1562 } else if (load_edit_groups (*child)) {
1566 if ((child = find_named_node (node, "MixGroups")) == 0) {
1567 error << _("Session: XML state has no mix groups section") << endmsg;
1569 } else if (load_mix_groups (*child)) {
1573 if ((child = find_named_node (node, "TempoMap")) == 0) {
1574 error << _("Session: XML state has no Tempo Map section") << endmsg;
1576 } else if (_tempo_map->set_state (*child)) {
1580 if ((child = find_named_node (node, "Routes")) == 0) {
1581 error << _("Session: XML state has no routes section") << endmsg;
1583 } else if (load_routes (*child)) {
1587 if ((child = find_named_node (node, "Click")) == 0) {
1588 warning << _("Session: XML state has no click section") << endmsg;
1589 } else if (_click_io) {
1590 _click_io->set_state (*child);
1593 /* OK, now we can set edit mode */
1595 set_edit_mode (pending_edit_mode);
1597 /* here beginneth the second phase ... */
1599 StateReady (); /* EMIT SIGNAL */
1601 _state_of_the_state = Clean;
1603 StateManager::allow_save (_("initial state"), true);
1605 if (state_was_pending) {
1606 save_state (_current_snapshot_name);
1607 remove_pending_capture_state ();
1608 state_was_pending = false;
1614 /* we failed, re-enable state saving but don't actually save internal state */
1615 StateManager::allow_save (X_("ignored"), false);
1620 Session::load_routes (const XMLNode& node)
1623 XMLNodeConstIterator niter;
1626 nlist = node.children();
1630 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1632 if ((route = XMLRouteFactory (**niter)) == 0) {
1633 error << _("Session: cannot create Route from XML description.") << endmsg;
1644 Session::XMLRouteFactory (const XMLNode& node)
1646 if (node.name() != "Route") {
1650 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1651 return new AudioTrack (*this, node);
1653 return new Route (*this, node);
1658 Session::load_regions (const XMLNode& node)
1661 XMLNodeConstIterator niter;
1662 AudioRegion* region;
1664 nlist = node.children();
1668 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1670 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1671 error << _("Session: cannot create Region from XML description.") << endmsg;
1679 Session::XMLRegionFactory (const XMLNode& node, bool full)
1681 const XMLProperty* prop;
1684 AudioRegion::SourceList sources;
1685 uint32_t nchans = 1;
1688 if (node.name() != X_("Region")) {
1692 if ((prop = node.property (X_("channels"))) != 0) {
1693 nchans = atoi (prop->value().c_str());
1697 if ((prop = node.property (X_("source-0"))) == 0) {
1698 if ((prop = node.property ("source")) == 0) {
1699 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1704 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1706 if ((source = get_source (s_id)) == 0) {
1707 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1711 sources.push_back(source);
1713 /* pickup other channels */
1715 for (uint32_t n=1; n < nchans; ++n) {
1716 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1717 if ((prop = node.property (buf)) != 0) {
1718 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1720 if ((source = get_source (s_id)) == 0) {
1721 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1724 sources.push_back(source);
1730 return new AudioRegion (sources, node);
1733 catch (failed_constructor& err) {
1739 Session::get_sources_as_xml ()
1742 XMLNode* node = new XMLNode (X_("Sources"));
1743 LockMonitor lm (source_lock, __LINE__, __FILE__);
1745 for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
1746 node->add_child_nocopy ((*i).second->get_state());
1753 Session::path_from_region_name (string name, string identifier)
1755 char buf[PATH_MAX+1];
1757 string dir = discover_best_sound_dir ();
1759 for (n = 0; n < 999999; ++n) {
1760 if (identifier.length()) {
1761 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1762 identifier.c_str(), n);
1764 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1766 if (access (buf, F_OK) != 0) {
1776 Session::load_sources (const XMLNode& node)
1779 XMLNodeConstIterator niter;
1782 nlist = node.children();
1786 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1788 if ((source = XMLSourceFactory (**niter)) == 0) {
1789 error << _("Session: cannot create Source from XML description.") << endmsg;
1797 Session::XMLSourceFactory (const XMLNode& node)
1801 if (node.name() != "Source") {
1807 if (node.property (X_("destructive")) != 0) {
1808 src = new DestructiveFileSource (node, frame_rate());
1810 src = new FileSource (node, frame_rate());
1814 catch (failed_constructor& err) {
1817 src = new SndFileSource (node);
1820 catch (failed_constructor& err) {
1821 error << _("Found a sound file that cannot be used by Ardour. See the progammers.") << endmsg;
1830 Session::save_template (string template_name)
1833 string xml_path, bak_path, template_path;
1835 if (_state_of_the_state & CannotSave) {
1840 string dir = template_dir();
1842 if ((dp = opendir (dir.c_str()))) {
1845 if (mkdir (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)<0) {
1846 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1851 tree.set_root (&get_template());
1854 xml_path += template_name;
1855 xml_path += _template_suffix;
1857 ifstream in(xml_path.c_str());
1860 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1866 if (!tree.write (xml_path)) {
1867 error << _("mix template not saved") << endmsg;
1875 Session::rename_template (string old_name, string new_name)
1877 string old_path = template_dir() + old_name + _template_suffix;
1878 string new_path = template_dir() + new_name + _template_suffix;
1880 return rename (old_path.c_str(), new_path.c_str());
1884 Session::delete_template (string name)
1886 string template_path = template_dir();
1887 template_path += name;
1888 template_path += _template_suffix;
1890 return remove (template_path.c_str());
1894 Session::refresh_disk_space ()
1897 struct statfs statfsbuf;
1898 vector<space_and_path>::iterator i;
1899 LockMonitor lm (space_lock, __LINE__, __FILE__);
1902 /* get freespace on every FS that is part of the session path */
1904 _total_free_4k_blocks = 0;
1906 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1907 statfs ((*i).path.c_str(), &statfsbuf);
1909 scale = statfsbuf.f_bsize/4096.0;
1911 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1912 _total_free_4k_blocks += (*i).blocks;
1918 Session::ensure_sound_dir (string path, string& result)
1923 /* Ensure that the parent directory exists */
1925 if (mkdir (path.c_str(), 0775)) {
1926 if (errno != EEXIST) {
1927 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1932 /* Ensure that the sounds directory exists */
1936 result += sound_dir_name;
1938 if (mkdir (result.c_str(), 0775)) {
1939 if (errno != EEXIST) {
1940 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1947 dead += dead_sound_dir_name;
1949 if (mkdir (dead.c_str(), 0775)) {
1950 if (errno != EEXIST) {
1951 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1958 peak += peak_dir_name;
1960 if (mkdir (peak.c_str(), 0775)) {
1961 if (errno != EEXIST) {
1962 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1967 /* callers expect this to be terminated ... */
1974 Session::discover_best_sound_dir (bool destructive)
1976 vector<space_and_path>::iterator i;
1979 /* destructive files all go into the same place */
1985 /* handle common case without system calls */
1987 if (session_dirs.size() == 1) {
1991 /* OK, here's the algorithm we're following here:
1993 We want to select which directory to use for
1994 the next file source to be created. Ideally,
1995 we'd like to use a round-robin process so as to
1996 get maximum performance benefits from splitting
1997 the files across multiple disks.
1999 However, in situations without much diskspace, an
2000 RR approach may end up filling up a filesystem
2001 with new files while others still have space.
2002 Its therefore important to pay some attention to
2003 the freespace in the filesystem holding each
2004 directory as well. However, if we did that by
2005 itself, we'd keep creating new files in the file
2006 system with the most space until it was as full
2007 as all others, thus negating any performance
2008 benefits of this RAID-1 like approach.
2010 So, we use a user-configurable space threshold. If
2011 there are at least 2 filesystems with more than this
2012 much space available, we use RR selection between them.
2013 If not, then we pick the filesystem with the most space.
2015 This gets a good balance between the two
2019 refresh_disk_space ();
2021 int free_enough = 0;
2023 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2024 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2029 if (free_enough >= 2) {
2031 bool found_it = false;
2033 /* use RR selection process, ensuring that the one
2037 i = last_rr_session_dir;
2040 if (++i == session_dirs.end()) {
2041 i = session_dirs.begin();
2044 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2045 if (ensure_sound_dir ((*i).path, result) == 0) {
2046 last_rr_session_dir = i;
2052 } while (i != last_rr_session_dir);
2055 result = sound_dir();
2060 /* pick FS with the most freespace (and that
2061 seems to actually work ...)
2064 vector<space_and_path> sorted;
2065 space_and_path_ascending_cmp cmp;
2067 sorted = session_dirs;
2068 sort (sorted.begin(), sorted.end(), cmp);
2070 for (i = sorted.begin(); i != sorted.end(); ++i) {
2071 if (ensure_sound_dir ((*i).path, result) == 0) {
2072 last_rr_session_dir = i;
2077 /* if the above fails, fall back to the most simplistic solution */
2079 if (i == sorted.end()) {
2088 Session::load_playlists (const XMLNode& node)
2091 XMLNodeConstIterator niter;
2094 nlist = node.children();
2098 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2100 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2101 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2109 Session::load_unused_playlists (const XMLNode& node)
2112 XMLNodeConstIterator niter;
2115 nlist = node.children();
2119 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2121 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2122 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2126 // now manually untrack it
2128 track_playlist (playlist, false);
2136 Session::XMLPlaylistFactory (const XMLNode& node)
2139 return new AudioPlaylist (*this, node);
2142 catch (failed_constructor& err) {
2148 Session::load_named_selections (const XMLNode& node)
2151 XMLNodeConstIterator niter;
2154 nlist = node.children();
2158 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2160 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2161 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2169 Session::XMLNamedSelectionFactory (const XMLNode& node)
2172 return new NamedSelection (*this, node);
2175 catch (failed_constructor& err) {
2181 Session::dead_sound_dir () const
2184 res += dead_sound_dir_name;
2190 Session::sound_dir () const
2193 res += sound_dir_name;
2199 Session::tape_dir () const
2201 string res = Config->get_tape_dir();
2208 res += tape_dir_name;
2214 Session::peak_dir () const
2217 res += peak_dir_name;
2223 Session::automation_dir () const
2226 res += "automation/";
2231 Session::template_dir ()
2233 string path = Config->get_user_ardour_path();
2234 path += "templates/";
2240 Session::template_path ()
2244 path += Config->get_user_ardour_path();
2245 if (path[path.length()-1] != ':') {
2248 path += Config->get_system_ardour_path();
2250 vector<string> split_path;
2252 split (path, split_path, ':');
2255 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2257 path += "templates/";
2259 if (distance (i, split_path.end()) != 1) {
2268 Session::load_connections (const XMLNode& node)
2270 XMLNodeList nlist = node.children();
2271 XMLNodeConstIterator niter;
2275 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2276 if ((*niter)->name() == "InputConnection") {
2277 add_connection (new ARDOUR::InputConnection (**niter));
2278 } else if ((*niter)->name() == "OutputConnection") {
2279 add_connection (new ARDOUR::OutputConnection (**niter));
2281 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2290 Session::load_edit_groups (const XMLNode& node)
2292 return load_route_groups (node, true);
2296 Session::load_mix_groups (const XMLNode& node)
2298 return load_route_groups (node, false);
2302 Session::load_route_groups (const XMLNode& node, bool edit)
2304 XMLNodeList nlist = node.children();
2305 XMLNodeConstIterator niter;
2310 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2311 if ((*niter)->name() == "RouteGroup") {
2313 route = add_edit_group ("");
2314 route->set_state (**niter);
2316 route = add_mix_group ("");
2317 route->set_state (**niter);
2326 Session::swap_configuration(Configuration** new_config)
2328 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__); // jlc - WHY?
2329 Configuration* tmp = *new_config;
2330 *new_config = Config;
2336 Session::copy_configuration(Configuration* new_config)
2338 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
2339 new_config = new Configuration(*Config);
2343 state_file_filter (const string &str, void *arg)
2345 return (str.length() > strlen(Session::statefile_suffix()) &&
2346 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2350 bool operator()(const string* a, const string* b) {
2356 remove_end(string* state)
2358 string statename(*state);
2360 string::size_type start,end;
2361 if ((start = statename.find_last_of ('/')) != string::npos) {
2362 statename = statename.substr (start+1);
2365 if ((end = statename.rfind(".ardour")) < 0) {
2366 end = statename.length();
2369 return new string(statename.substr (0, end));
2373 Session::possible_states (string path)
2375 PathScanner scanner;
2376 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2378 transform(states->begin(), states->end(), states->begin(), remove_end);
2381 sort (states->begin(), states->end(), cmp);
2387 Session::possible_states () const
2389 return possible_states(_path);
2393 Session::auto_save()
2395 save_state (_current_snapshot_name);
2399 Session::add_edit_group (string name)
2401 RouteGroup* rg = new RouteGroup (name);
2402 edit_groups.push_back (rg);
2403 edit_group_added (rg); /* EMIT SIGNAL */
2409 Session::add_mix_group (string name)
2411 RouteGroup* rg = new RouteGroup (name, RouteGroup::Relative);
2412 mix_groups.push_back (rg);
2413 mix_group_added (rg); /* EMIT SIGNAL */
2419 Session::remove_edit_group (RouteGroup& rg)
2421 list<RouteGroup*>::iterator i;
2423 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2424 (*i)->apply (&Route::drop_edit_group, this);
2425 edit_groups.erase (i);
2426 edit_group_removed (); /* EMIT SIGNAL */
2433 Session::remove_mix_group (RouteGroup& rg)
2435 list<RouteGroup*>::iterator i;
2437 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2438 (*i)->apply (&Route::drop_mix_group, this);
2439 mix_groups.erase (i);
2440 mix_group_removed (); /* EMIT SIGNAL */
2447 Session::mix_group_by_name (string name)
2449 list<RouteGroup *>::iterator i;
2451 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2452 if ((*i)->name() == name) {
2460 Session::edit_group_by_name (string name)
2462 list<RouteGroup *>::iterator i;
2464 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2465 if ((*i)->name() == name) {
2473 Session::set_meter_hold (float val)
2476 MeterHoldChanged(); // emit
2480 Session::set_meter_falloff (float val)
2482 _meter_falloff = val;
2483 MeterFalloffChanged(); // emit
2488 Session::begin_reversible_command (string name, UndoAction* private_undo)
2490 current_cmd.clear ();
2491 current_cmd.set_name (name);
2494 current_cmd.add_undo (*private_undo);
2499 Session::commit_reversible_command (UndoAction* private_redo)
2504 current_cmd.add_redo_no_execute (*private_redo);
2507 gettimeofday (&now, 0);
2508 current_cmd.set_timestamp (now);
2510 history.add (current_cmd);
2513 Session::GlobalRouteBooleanState
2514 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2516 GlobalRouteBooleanState s;
2517 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2519 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2520 if (!(*i)->hidden()) {
2521 RouteBooleanState v;
2524 v.second = ((*i)->*method)();
2533 Session::GlobalRouteMeterState
2534 Session::get_global_route_metering ()
2536 GlobalRouteMeterState s;
2537 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2539 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2540 if (!(*i)->hidden()) {
2544 v.second = (*i)->meter_point();
2554 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2556 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2557 i->first->set_meter_point (i->second, arg);
2562 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2564 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2565 (i->first->*method) (i->second, arg);
2570 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2572 set_global_route_boolean (s, &Route::set_mute, src);
2576 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2578 set_global_route_boolean (s, &Route::set_solo, src);
2582 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2584 set_global_route_boolean (s, &Route::set_record_enable, src);
2588 Session::global_mute_memento (void* src)
2590 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2594 Session::global_metering_memento (void* src)
2596 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2600 Session::global_solo_memento (void* src)
2602 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2606 Session::global_record_enable_memento (void* src)
2608 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2612 template_filter (const string &str, void *arg)
2614 return (str.length() > strlen(Session::template_suffix()) &&
2615 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2619 Session::get_template_list (list<string> &template_names)
2621 vector<string *> *templates;
2622 PathScanner scanner;
2625 path = template_path ();
2627 templates = scanner (path, template_filter, 0, false, true);
2629 vector<string*>::iterator i;
2630 for (i = templates->begin(); i != templates->end(); ++i) {
2631 string fullpath = *(*i);
2634 start = fullpath.find_last_of ('/') + 1;
2635 if ((end = fullpath.find_last_of ('.')) <0) {
2636 end = fullpath.length();
2639 template_names.push_back(fullpath.substr(start, (end-start)));
2644 Session::read_favorite_dirs (FavoriteDirs & favs)
2646 string path = Config->get_user_ardour_path();
2647 path += "/favorite_dirs";
2649 ifstream fav (path.c_str());
2654 if (errno != ENOENT) {
2655 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2666 getline(fav, newfav);
2672 favs.push_back (newfav);
2679 Session::write_favorite_dirs (FavoriteDirs & favs)
2681 string path = Config->get_user_ardour_path();
2682 path += "/favorite_dirs";
2684 ofstream fav (path.c_str());
2690 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2691 fav << (*i) << endl;
2698 accept_all_non_peak_files (const string& path, void *arg)
2700 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2704 accept_all_state_files (const string& path, void *arg)
2706 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2710 Session::find_all_sources (string path, set<string>& result)
2715 if (!tree.read (path)) {
2719 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2724 XMLNodeConstIterator niter;
2726 nlist = node->children();
2730 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2734 if ((prop = (*niter)->property (X_("name"))) == 0) {
2738 if (prop->value()[0] == '/') {
2739 /* external file, ignore */
2743 string path = _path; /* /-terminated */
2744 path += sound_dir_name;
2746 path += prop->value();
2748 result.insert (path);
2755 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2757 PathScanner scanner;
2758 vector<string*>* state_files;
2760 string this_snapshot_path;
2766 if (ripped[ripped.length()-1] == '/') {
2767 ripped = ripped.substr (0, ripped.length() - 1);
2770 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2772 if (state_files == 0) {
2777 this_snapshot_path = _path;
2778 this_snapshot_path += _current_snapshot_name;
2779 this_snapshot_path += _statefile_suffix;
2781 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2783 if (exclude_this_snapshot && **i == this_snapshot_path) {
2787 if (find_all_sources (**i, result) < 0) {
2796 Session::cleanup_sources (Session::cleanup_report& rep)
2798 vector<Source*> dead_sources;
2799 vector<Playlist*> playlists_tbd;
2800 PathScanner scanner;
2802 vector<space_and_path>::iterator i;
2803 vector<space_and_path>::iterator nexti;
2804 vector<string*>* soundfiles;
2805 vector<string> unused;
2806 set<string> all_sources;
2811 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2813 /* step 1: consider deleting all unused playlists */
2815 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2818 status = AskAboutPlaylistDeletion (*x);
2827 playlists_tbd.push_back (*x);
2831 /* leave it alone */
2836 /* now delete any that were marked for deletion */
2838 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2839 PlaylistList::iterator foo;
2841 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2842 unused_playlists.erase (foo);
2847 /* step 2: clear the undo/redo history for all playlists */
2849 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2850 (*x)->drop_all_states ();
2853 /* step 3: find all un-referenced sources */
2858 for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
2860 SourceList::iterator tmp;
2865 /* only remove files that are not in use and have some size
2866 to them. otherwise we remove the current "nascent"
2870 if ((*i).second->use_cnt() == 0 && (*i).second->length() > 0) {
2871 dead_sources.push_back (i->second);
2873 /* remove this source from our own list to avoid us
2874 adding it to the list of all sources below
2883 /* Step 4: get rid of all regions in the region list that use any dead sources
2884 in case the sources themselves don't go away (they might be referenced in
2888 for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2890 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2891 AudioRegionList::iterator tmp;
2899 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2900 if (&ar->source (n) == (*i)) {
2901 /* this region is dead */
2910 /* build a list of all the possible sound directories for the session */
2912 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2917 sound_path += (*i).path;
2918 sound_path += sound_dir_name;
2920 if (nexti != session_dirs.end()) {
2927 /* now do the same thing for the files that ended up in the sounds dir(s)
2928 but are not referenced as sources in any snapshot.
2931 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2933 if (soundfiles == 0) {
2937 /* find all sources, but don't use this snapshot because the
2938 state file on disk still references sources we may have already
2942 find_all_sources_across_snapshots (all_sources, true);
2944 /* add our current source list
2947 for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
2951 if ((fs = dynamic_cast<FileSource*> ((*i).second)) != 0) {
2952 all_sources.insert (fs->path());
2953 } else if ((sfs = dynamic_cast<SndFileSource*> ((*i).second)) != 0) {
2954 all_sources.insert (sfs->path());
2958 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2963 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2973 unused.push_back (spath);
2977 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2979 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2980 struct stat statbuf;
2982 rep.paths.push_back (*x);
2983 if (stat ((*x).c_str(), &statbuf) == 0) {
2984 rep.space += statbuf.st_size;
2989 /* don't move the file across filesystems, just
2990 stick it in the `dead_sound_dir_name' directory
2991 on whichever filesystem it was already on.
2994 newpath = PBD::dirname (*x);
2995 newpath = PBD::dirname (newpath);
2998 newpath += dead_sound_dir_name;
3000 newpath += PBD::basename ((*x));
3002 if (access (newpath.c_str(), F_OK) == 0) {
3004 /* the new path already exists, try versioning */
3006 char buf[PATH_MAX+1];
3010 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
3013 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
3014 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
3018 if (version == 999) {
3019 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
3023 newpath = newpath_v;
3028 /* it doesn't exist, or we can't read it or something */
3032 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
3033 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
3034 (*x), newpath, strerror (errno))
3040 /* see if there an easy to find peakfile for this file, and remove it.
3043 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
3044 peakpath += ".peak";
3046 if (access (peakpath.c_str(), W_OK) == 0) {
3047 if (::unlink (peakpath.c_str()) != 0) {
3048 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3049 peakpath, _path, strerror (errno))
3051 /* try to back out */
3052 rename (newpath.c_str(), _path.c_str());
3061 /* dump the history list */
3065 /* save state so we don't end up a session file
3066 referring to non-existent sources.
3072 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3077 Session::cleanup_trash_sources (Session::cleanup_report& rep)
3079 vector<space_and_path>::iterator i;
3080 string dead_sound_dir;
3081 struct dirent* dentry;
3082 struct stat statbuf;
3088 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3090 dead_sound_dir = (*i).path;
3091 dead_sound_dir += dead_sound_dir_name;
3093 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
3097 while ((dentry = readdir (dead)) != 0) {
3099 /* avoid '.' and '..' */
3101 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
3102 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3108 fullpath = dead_sound_dir;
3110 fullpath += dentry->d_name;
3112 if (stat (fullpath.c_str(), &statbuf)) {
3116 if (!S_ISREG (statbuf.st_mode)) {
3120 if (unlink (fullpath.c_str())) {
3121 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3122 fullpath, strerror (errno))
3126 rep.paths.push_back (dentry->d_name);
3127 rep.space += statbuf.st_size;
3138 Session::set_dirty ()
3140 bool was_dirty = dirty();
3142 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3145 DirtyChanged(); /* EMIT SIGNAL */
3151 Session::set_clean ()
3153 bool was_dirty = dirty();
3155 _state_of_the_state = Clean;
3158 DirtyChanged(); /* EMIT SIGNAL */