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::mix_group_by_name (string name)
2421 list<RouteGroup *>::iterator i;
2423 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2424 if ((*i)->name() == name) {
2432 Session::edit_group_by_name (string name)
2434 list<RouteGroup *>::iterator i;
2436 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2437 if ((*i)->name() == name) {
2445 Session::set_meter_hold (float val)
2448 MeterHoldChanged(); // emit
2452 Session::set_meter_falloff (float val)
2454 _meter_falloff = val;
2455 MeterFalloffChanged(); // emit
2460 Session::begin_reversible_command (string name, UndoAction* private_undo)
2462 current_cmd.clear ();
2463 current_cmd.set_name (name);
2466 current_cmd.add_undo (*private_undo);
2471 Session::commit_reversible_command (UndoAction* private_redo)
2476 current_cmd.add_redo_no_execute (*private_redo);
2479 gettimeofday (&now, 0);
2480 current_cmd.set_timestamp (now);
2482 history.add (current_cmd);
2485 Session::GlobalRouteBooleanState
2486 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2488 GlobalRouteBooleanState s;
2489 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2491 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2492 if (!(*i)->hidden()) {
2493 RouteBooleanState v;
2496 v.second = ((*i)->*method)();
2505 Session::GlobalRouteMeterState
2506 Session::get_global_route_metering ()
2508 GlobalRouteMeterState s;
2509 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2511 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2512 if (!(*i)->hidden()) {
2516 v.second = (*i)->meter_point();
2526 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2528 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2529 i->first->set_meter_point (i->second, arg);
2534 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2536 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2537 (i->first->*method) (i->second, arg);
2542 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2544 set_global_route_boolean (s, &Route::set_mute, src);
2548 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2550 set_global_route_boolean (s, &Route::set_solo, src);
2554 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2556 set_global_route_boolean (s, &Route::set_record_enable, src);
2560 Session::global_mute_memento (void* src)
2562 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2566 Session::global_metering_memento (void* src)
2568 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2572 Session::global_solo_memento (void* src)
2574 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2578 Session::global_record_enable_memento (void* src)
2580 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2584 template_filter (const string &str, void *arg)
2586 return (str.length() > strlen(Session::template_suffix()) &&
2587 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2591 Session::get_template_list (list<string> &template_names)
2593 vector<string *> *templates;
2594 PathScanner scanner;
2597 path = template_path ();
2599 templates = scanner (path, template_filter, 0, false, true);
2601 vector<string*>::iterator i;
2602 for (i = templates->begin(); i != templates->end(); ++i) {
2603 string fullpath = *(*i);
2606 start = fullpath.find_last_of ('/') + 1;
2607 if ((end = fullpath.find_last_of ('.')) <0) {
2608 end = fullpath.length();
2611 template_names.push_back(fullpath.substr(start, (end-start)));
2616 Session::read_favorite_dirs (FavoriteDirs & favs)
2618 string path = Config->get_user_ardour_path();
2619 path += "/favorite_dirs";
2621 ifstream fav (path.c_str());
2626 if (errno != ENOENT) {
2627 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2638 getline(fav, newfav);
2644 favs.push_back (newfav);
2651 Session::write_favorite_dirs (FavoriteDirs & favs)
2653 string path = Config->get_user_ardour_path();
2654 path += "/favorite_dirs";
2656 ofstream fav (path.c_str());
2662 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2663 fav << (*i) << endl;
2670 accept_all_non_peak_files (const string& path, void *arg)
2672 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2676 accept_all_state_files (const string& path, void *arg)
2678 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2682 Session::find_all_sources (string path, set<string>& result)
2687 if (!tree.read (path)) {
2691 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2696 XMLNodeConstIterator niter;
2698 nlist = node->children();
2702 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2706 if ((prop = (*niter)->property (X_("name"))) == 0) {
2710 if (prop->value()[0] == '/') {
2711 /* external file, ignore */
2715 string path = _path; /* /-terminated */
2716 path += sound_dir_name;
2718 path += prop->value();
2720 result.insert (path);
2727 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2729 PathScanner scanner;
2730 vector<string*>* state_files;
2732 string this_snapshot_path;
2738 if (ripped[ripped.length()-1] == '/') {
2739 ripped = ripped.substr (0, ripped.length() - 1);
2742 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2744 if (state_files == 0) {
2749 this_snapshot_path = _path;
2750 this_snapshot_path += _current_snapshot_name;
2751 this_snapshot_path += _statefile_suffix;
2753 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2755 if (exclude_this_snapshot && **i == this_snapshot_path) {
2759 if (find_all_sources (**i, result) < 0) {
2768 Session::cleanup_sources (Session::cleanup_report& rep)
2770 vector<Source*> dead_sources;
2771 vector<Playlist*> playlists_tbd;
2772 PathScanner scanner;
2774 vector<space_and_path>::iterator i;
2775 vector<space_and_path>::iterator nexti;
2776 vector<string*>* soundfiles;
2777 vector<string> unused;
2778 set<string> all_sources;
2783 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2785 /* step 1: consider deleting all unused playlists */
2787 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2790 status = AskAboutPlaylistDeletion (*x);
2799 playlists_tbd.push_back (*x);
2803 /* leave it alone */
2808 /* now delete any that were marked for deletion */
2810 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2811 PlaylistList::iterator foo;
2813 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2814 unused_playlists.erase (foo);
2819 /* step 2: clear the undo/redo history for all playlists */
2821 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2822 (*x)->drop_all_states ();
2825 /* step 3: find all un-referenced sources */
2830 for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
2832 SourceList::iterator tmp;
2837 /* only remove files that are not in use and have some size
2838 to them. otherwise we remove the current "nascent"
2842 if ((*i).second->use_cnt() == 0 && (*i).second->length() > 0) {
2843 dead_sources.push_back (i->second);
2845 /* remove this source from our own list to avoid us
2846 adding it to the list of all sources below
2855 /* Step 4: get rid of all regions in the region list that use any dead sources
2856 in case the sources themselves don't go away (they might be referenced in
2860 for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2862 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2863 AudioRegionList::iterator tmp;
2871 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2872 if (&ar->source (n) == (*i)) {
2873 /* this region is dead */
2882 /* build a list of all the possible sound directories for the session */
2884 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2889 sound_path += (*i).path;
2890 sound_path += sound_dir_name;
2892 if (nexti != session_dirs.end()) {
2899 /* now do the same thing for the files that ended up in the sounds dir(s)
2900 but are not referenced as sources in any snapshot.
2903 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2905 if (soundfiles == 0) {
2909 /* find all sources, but don't use this snapshot because the
2910 state file on disk still references sources we may have already
2914 find_all_sources_across_snapshots (all_sources, true);
2916 /* add our current source list
2919 for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
2923 if ((fs = dynamic_cast<FileSource*> ((*i).second)) != 0) {
2924 all_sources.insert (fs->path());
2925 } else if ((sfs = dynamic_cast<SndFileSource*> ((*i).second)) != 0) {
2926 all_sources.insert (sfs->path());
2930 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2935 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2945 unused.push_back (spath);
2949 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2951 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2952 struct stat statbuf;
2954 rep.paths.push_back (*x);
2955 if (stat ((*x).c_str(), &statbuf) == 0) {
2956 rep.space += statbuf.st_size;
2961 /* don't move the file across filesystems, just
2962 stick it in the `dead_sound_dir_name' directory
2963 on whichever filesystem it was already on.
2966 newpath = PBD::dirname (*x);
2967 newpath = PBD::dirname (newpath);
2970 newpath += dead_sound_dir_name;
2972 newpath += PBD::basename ((*x));
2974 if (access (newpath.c_str(), F_OK) == 0) {
2976 /* the new path already exists, try versioning */
2978 char buf[PATH_MAX+1];
2982 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2985 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2986 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2990 if (version == 999) {
2991 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2995 newpath = newpath_v;
3000 /* it doesn't exist, or we can't read it or something */
3004 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
3005 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
3006 (*x), newpath, strerror (errno))
3012 /* see if there an easy to find peakfile for this file, and remove it.
3015 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
3016 peakpath += ".peak";
3018 if (access (peakpath.c_str(), W_OK) == 0) {
3019 if (::unlink (peakpath.c_str()) != 0) {
3020 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3021 peakpath, _path, strerror (errno))
3023 /* try to back out */
3024 rename (newpath.c_str(), _path.c_str());
3033 /* dump the history list */
3037 /* save state so we don't end up a session file
3038 referring to non-existent sources.
3044 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3049 Session::cleanup_trash_sources (Session::cleanup_report& rep)
3051 vector<space_and_path>::iterator i;
3052 string dead_sound_dir;
3053 struct dirent* dentry;
3054 struct stat statbuf;
3060 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3062 dead_sound_dir = (*i).path;
3063 dead_sound_dir += dead_sound_dir_name;
3065 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
3069 while ((dentry = readdir (dead)) != 0) {
3071 /* avoid '.' and '..' */
3073 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
3074 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3080 fullpath = dead_sound_dir;
3082 fullpath += dentry->d_name;
3084 if (stat (fullpath.c_str(), &statbuf)) {
3088 if (!S_ISREG (statbuf.st_mode)) {
3092 if (unlink (fullpath.c_str())) {
3093 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3094 fullpath, strerror (errno))
3098 rep.paths.push_back (dentry->d_name);
3099 rep.space += statbuf.st_size;
3110 Session::set_dirty ()
3112 bool was_dirty = dirty();
3114 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3117 DirtyChanged(); /* EMIT SIGNAL */
3123 Session::set_clean ()
3125 bool was_dirty = dirty();
3127 _state_of_the_state = Clean;
3130 DirtyChanged(); /* EMIT SIGNAL */