2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include <sigc++/bind.h>
28 #include <cstdio> /* snprintf(3) ... grrr */
43 #include <sys/mount.h>
44 #include <sys/param.h>
47 #include <midi++/mmc.h>
48 #include <midi++/port.h>
49 #include <pbd/error.h>
50 #include <pbd/dirname.h>
51 #include <pbd/lockmonitor.h>
52 #include <pbd/pathscanner.h>
53 #include <pbd/pthread_utils.h>
54 #include <pbd/basename.h>
55 #include <pbd/strsplit.h>
57 #include <ardour/audioengine.h>
58 #include <ardour/configuration.h>
59 #include <ardour/session.h>
60 #include <ardour/diskstream.h>
61 #include <ardour/utils.h>
62 #include <ardour/audioplaylist.h>
63 #include <ardour/source.h>
64 #include <ardour/filesource.h>
65 #include <ardour/sndfilesource.h>
66 #include <ardour/sndfile_helpers.h>
67 #include <ardour/auditioner.h>
68 #include <ardour/export.h>
69 #include <ardour/redirect.h>
70 #include <ardour/send.h>
71 #include <ardour/insert.h>
72 #include <ardour/connection.h>
73 #include <ardour/slave.h>
74 #include <ardour/tempo.h>
75 #include <ardour/audio_track.h>
76 #include <ardour/cycle_timer.h>
77 #include <ardour/utils.h>
78 #include <ardour/named_selection.h>
79 #include <ardour/version.h>
80 #include <ardour/location.h>
81 #include <ardour/audioregion.h>
82 #include <ardour/crossfade.h>
88 using namespace ARDOUR;
91 Session::first_stage_init (string fullpath, string snapshot_name)
93 if (fullpath.length() == 0) {
94 throw failed_constructor();
98 if (!realpath(fullpath.c_str(), buf) && (errno != ENOENT)) {
99 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
100 throw failed_constructor();
104 if (_path[_path.length()-1] != '/') {
108 /* these two are just provisional settings. set_state()
109 will likely override them.
112 _name = _current_snapshot_name = snapshot_name;
113 setup_raid_path (_path);
115 _current_frame_rate = _engine.frame_rate ();
116 _tempo_map = new TempoMap (_current_frame_rate);
117 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
119 atomic_set (&processing_prohibited, 0);
122 _transport_speed = 0;
123 _last_transport_speed = 0;
124 transport_sub_state = 0;
125 _transport_frame = 0;
127 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
128 _end_location_is_free = true;
129 atomic_set (&_record_status, Disabled);
134 seamless_loop = false;
135 loop_changing = false;
137 crossfades_active = false;
140 _last_roll_location = 0;
141 _last_record_location = 0;
142 pending_locate_frame = 0;
143 pending_locate_roll = false;
144 pending_locate_flush = false;
145 dstream_buffer_size = 0;
147 state_was_pending = false;
149 outbound_mtc_smpte_frame = 0;
150 next_quarter_frame_to_send = -1;
151 current_block_size = 0;
152 _solo_latched = true;
153 _solo_model = InverseMute;
154 solo_update_disabled = false;
155 currently_soloing = false;
156 _worst_output_latency = 0;
157 _worst_input_latency = 0;
158 _worst_track_latency = 0;
159 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
162 butler_mixdown_buffer = 0;
163 butler_gain_buffer = 0;
166 midi_feedback = false;
169 post_transport_work = PostTransportWork (0);
170 atomic_set (&butler_should_do_transport_work, 0);
171 atomic_set (&butler_active, 0);
172 atomic_set (&_playback_load, 100);
173 atomic_set (&_capture_load, 100);
174 atomic_set (&_playback_load_min, 100);
175 atomic_set (&_capture_load_min, 100);
176 pending_audition_region = 0;
178 pending_edit_mode = _edit_mode;
180 align_style = ExistingMaterial;
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 /* default short fade = 15ms */
197 Crossfade::set_short_xfade_length ((jack_nframes_t) floor ((15.0 * frame_rate()) / 1000.0));
199 last_mmc_step.tv_sec = 0;
200 last_mmc_step.tv_usec = 0;
203 preroll.type = AnyTime::Frames;
205 postroll.type = AnyTime::Frames;
208 /* click sounds are unset by default, which causes us to internal
209 waveforms for clicks.
214 click_requested = false;
216 click_emphasis_data = 0;
218 click_emphasis_length = 0;
220 process_function = &Session::process_with_events;
224 _smpte_offset_negative = true;
225 last_smpte_valid = false;
227 last_rr_session_dir = session_dirs.begin();
228 refresh_disk_space ();
230 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
232 /* default configuration */
234 recording_plugins = false;
235 over_length_short = 2;
236 over_length_long = 10;
237 send_midi_timecode = false;
238 send_midi_machine_control = false;
239 shuttle_speed_factor = 1.0;
240 shuttle_speed_threshold = 5;
242 _meter_hold = 100; // XXX unknown units: number of calls to meter::set()
243 _meter_falloff = 1.5f; // XXX unknown units: refresh_rate
249 average_slave_delta = 1800;
250 have_first_delta_accumulator = false;
251 delta_accumulator_cnt = 0;
252 slave_state = Stopped;
254 /* default SMPTE type is 30 FPS, non-drop */
256 set_smpte_type (30.0, false);
258 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
260 /* These are all static "per-class" signals */
262 Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
263 Source::SourceCreated.connect (mem_fun (*this, &Session::add_source));
264 Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
265 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
266 DiskStream::DiskStreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
267 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
269 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
271 /* stop IO objects from doing stuff until we're ready for them */
273 IO::disable_panners ();
274 IO::disable_ports ();
275 IO::disable_connecting ();
279 Session::second_stage_init (bool new_session)
281 SndFileSource::set_peak_dir (peak_dir());
284 if (load_state (_current_snapshot_name)) {
287 remove_empty_sounds ();
290 if (start_butler_thread()) {
294 if (start_midi_thread ()) {
298 if (init_feedback ()) {
303 if (set_state (*state_tree->root())) {
308 /* we can't save till after ::when_engine_running() is called,
309 because otherwise we save state with no connections made.
310 therefore, we reset _state_of_the_state because ::set_state()
311 will have cleared it.
313 we also have to include Loading so that any events that get
314 generated between here and the end of ::when_engine_running()
315 will be processed directly rather than queued.
318 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
320 // set_auto_input (true);
321 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
322 _locations.added.connect (mem_fun (this, &Session::locations_added));
323 setup_click_sounds (0);
324 setup_midi_control ();
326 /* Pay attention ... */
328 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
329 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
331 if (_engine.running()) {
332 when_engine_running();
334 first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
337 send_full_time_code ();
338 _engine.transport_locate (0);
339 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
340 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
341 send_all_midi_feedback();
344 _end_location_is_free = true;
346 _end_location_is_free = false;
353 Session::raid_path () const
357 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
362 return path.substr (0, path.length() - 1); // drop final colon
366 Session::set_raid_path (string path)
368 /* public-access to setup_raid_path() */
370 setup_raid_path (path);
374 Session::setup_raid_path (string path)
376 string::size_type colon;
380 string::size_type len = path.length();
385 if (path.length() == 0) {
389 session_dirs.clear ();
391 for (string::size_type n = 0; n < len; ++n) {
392 if (path[n] == ':') {
399 /* no multiple search path, just one directory (common case) */
403 session_dirs.push_back (sp);
405 FileSource::set_search_path (path + sound_dir_name);
412 while ((colon = remaining.find_first_of (':')) != string::npos) {
415 sp.path = remaining.substr (0, colon);
418 if (fspath[fspath.length()-1] != '/') {
421 fspath += sound_dir_name;
424 session_dirs.push_back (sp);
426 remaining = remaining.substr (colon+1);
429 if (remaining.length()) {
435 if (fspath[fspath.length()-1] != '/') {
438 fspath += sound_dir_name;
440 session_dirs.push_back (sp);
443 /* set the FileSource search path */
445 FileSource::set_search_path (fspath);
447 /* reset the round-robin soundfile path thingie */
449 last_rr_session_dir = session_dirs.begin();
453 Session::create (bool& new_session, string* mix_template, jack_nframes_t initial_length)
457 if (mkdir (_path.c_str(), 0755) < 0) {
458 if (errno == EEXIST) {
461 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
470 if (mkdir (dir.c_str(), 0755) < 0) {
471 if (errno != EEXIST) {
472 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
479 if (mkdir (dir.c_str(), 0755) < 0) {
480 if (errno != EEXIST) {
481 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
486 dir = dead_sound_dir ();
488 if (mkdir (dir.c_str(), 0755) < 0) {
489 if (errno != EEXIST) {
490 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
495 dir = automation_dir ();
497 if (mkdir (dir.c_str(), 0755) < 0) {
498 if (errno != EEXIST) {
499 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
505 /* check new_session so we don't overwrite an existing one */
510 string lookfor = "^";
511 lookfor += *mix_template;
512 lookfor += _template_suffix;
516 string tpath = template_path();
520 vector<string*>* result= scanner (tpath, lookfor, false, true);
523 error << string_compose (_("Could not find a template called %1 in %2"), *mix_template, tpath)
528 if (result->size() == 0) {
530 error << string_compose (_("Could not find a template called %1 in %2"), *mix_template, tpath)
535 in_path = *(result->front());
537 ifstream in(in_path.c_str());
540 string out_path = _path;
542 out_path += _statefile_suffix;
544 ofstream out(out_path.c_str());
549 // okay, session is set up. Treat like normal saved
550 // session from now on.
556 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
562 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
569 warning << _("Session already exists. Not overwriting") << endmsg;
576 /* set an initial end point */
578 end_location->set_end (initial_length);
579 _locations.add (end_location);
581 _state_of_the_state = Clean;
583 if (save_state (_current_snapshot_name)) {
592 Session::load_diskstreams (const XMLNode& node)
595 XMLNodeConstIterator citer;
597 clist = node.children();
599 for (citer = clist.begin(); citer != clist.end(); ++citer) {
604 dstream = new DiskStream (*this, **citer);
605 /* added automatically by DiskStreamCreated handler */
608 catch (failed_constructor& err) {
609 error << _("Session: could not load diskstream via XML state") << endmsg;
618 Session::remove_pending_capture_state ()
623 xml_path += _current_snapshot_name;
624 xml_path += _pending_suffix;
626 unlink (xml_path.c_str());
630 Session::save_state (string snapshot_name, bool pending)
636 if (_state_of_the_state & CannotSave) {
640 tree.set_root (&get_state());
642 if (snapshot_name.empty()) {
643 snapshot_name = _current_snapshot_name;
649 xml_path += snapshot_name;
650 xml_path += _statefile_suffix;
654 // Make backup of state file
656 if ((access (xml_path.c_str(), F_OK) == 0) &&
657 (rename(xml_path.c_str(), bak_path.c_str()))) {
658 error << _("could not backup old state file, current state not saved.") << endmsg;
665 xml_path += snapshot_name;
666 xml_path += _pending_suffix;
670 if (!tree.write (xml_path)) {
671 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
673 /* don't leave a corrupt file lying around if it is
677 if (unlink (xml_path.c_str())) {
678 error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
681 if (rename (bak_path.c_str(), xml_path.c_str())) {
682 error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
692 bool was_dirty = dirty();
694 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
697 DirtyChanged (); /* EMIT SIGNAL */
700 StateSaved (snapshot_name); /* EMIT SIGNAL */
707 Session::restore_state (string snapshot_name)
709 if (load_state (snapshot_name) == 0) {
710 set_state (*state_tree->root());
717 Session::load_state (string snapshot_name)
726 state_was_pending = false;
728 /* check for leftover pending state from a crashed capture attempt */
731 xmlpath += snapshot_name;
732 xmlpath += _pending_suffix;
734 if (!access (xmlpath.c_str(), F_OK)) {
736 /* there is pending state from a crashed capture attempt */
738 if (AskAboutPendingState()) {
739 state_was_pending = true;
743 if (!state_was_pending) {
746 xmlpath += snapshot_name;
747 xmlpath += _statefile_suffix;
750 if (access (xmlpath.c_str(), F_OK)) {
751 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
755 state_tree = new XMLTree;
759 if (state_tree->read (xmlpath)) {
762 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
771 Session::load_options (const XMLNode& node)
775 bool have_fade_msecs = false;
776 bool have_fade_steepness = false;
777 float fade_msecs = 0;
778 float fade_steepness = 0;
779 SlaveSource slave_src = None;
781 LocaleGuard lg (X_("POSIX"));
783 if ((child = find_named_node (node, "input-auto-connect")) != 0) {
784 if ((prop = child->property ("val")) != 0) {
785 sscanf (prop->value().c_str(), "%x", &x);
786 input_auto_connect = AutoConnectOption (x);
790 if ((child = find_named_node (node, "output-auto-connect")) != 0) {
791 if ((prop = child->property ("val")) != 0) {
792 sscanf (prop->value().c_str(), "%x", &x);
793 output_auto_connect = AutoConnectOption (x);
797 if ((child = find_named_node (node, "slave")) != 0) {
798 if ((prop = child->property ("type")) != 0) {
799 if (prop->value() == "none") {
801 } else if (prop->value() == "mtc") {
803 } else if (prop->value() == "jack") {
806 set_slave_source (slave_src, 0);
810 /* we cannot set edit mode if we are loading a session,
811 because it might destroy the playlist's positioning
814 if ((child = find_named_node (node, "edit-mode")) != 0) {
815 if ((prop = child->property ("val")) != 0) {
816 if (prop->value() == "slide") {
817 pending_edit_mode = Slide;
818 } else if (prop->value() == "splice") {
819 pending_edit_mode = Splice;
824 if ((child = find_named_node (node, "send-midi-timecode")) != 0) {
825 if ((prop = child->property ("val")) != 0) {
826 bool x = (prop->value() == "yes");
827 send_mtc = !x; /* force change in value */
831 if ((child = find_named_node (node, "send-midi-machine-control")) != 0) {
832 if ((prop = child->property ("val")) != 0) {
833 bool x = (prop->value() == "yes");
834 send_mmc = !x; /* force change in value */
835 set_send_mmc (prop->value() == "yes");
838 if ((child = find_named_node (node, "max-level")) != 0) {
839 if ((prop = child->property ("val")) != 0) {
840 max_level = atoi (prop->value().c_str());
843 if ((child = find_named_node (node, "min-level")) != 0) {
844 if ((prop = child->property ("val")) != 0) {
845 min_level = atoi (prop->value().c_str());
848 if ((child = find_named_node (node, "meter-hold")) != 0) {
849 if ((prop = child->property ("val")) != 0) {
850 _meter_hold = atof (prop->value().c_str());
853 if ((child = find_named_node (node, "meter-falloff")) != 0) {
854 if ((prop = child->property ("val")) != 0) {
855 _meter_falloff = atof (prop->value().c_str());
858 if ((child = find_named_node (node, "long-over-length")) != 0) {
859 if ((prop = child->property ("val")) != 0) {
860 over_length_long = atoi (prop->value().c_str());
863 if ((child = find_named_node (node, "short-over-length")) != 0) {
864 if ((prop = child->property ("val")) != 0) {
865 over_length_short = atoi (prop->value().c_str());
868 if ((child = find_named_node (node, "shuttle-speed-factor")) != 0) {
869 if ((prop = child->property ("val")) != 0) {
870 shuttle_speed_factor = atof (prop->value().c_str());
873 if ((child = find_named_node (node, "shuttle-speed-threshold")) != 0) {
874 if ((prop = child->property ("val")) != 0) {
875 shuttle_speed_threshold = atof (prop->value().c_str());
878 if ((child = find_named_node (node, "rf-speed")) != 0) {
879 if ((prop = child->property ("val")) != 0) {
880 rf_speed = atof (prop->value().c_str());
883 if ((child = find_named_node (node, "smpte-frames-per-second")) != 0) {
884 if ((prop = child->property ("val")) != 0) {
885 set_smpte_type( atof (prop->value().c_str()), smpte_drop_frames );
888 if ((child = find_named_node (node, "smpte-drop-frames")) != 0) {
889 if ((prop = child->property ("val")) != 0) {
890 set_smpte_type( smpte_frames_per_second, (prop->value() == "yes") );
893 if ((child = find_named_node (node, "smpte-offset")) != 0) {
894 if ((prop = child->property ("val")) != 0) {
895 set_smpte_offset( atoi (prop->value().c_str()) );
898 if ((child = find_named_node (node, "smpte-offset-negative")) != 0) {
899 if ((prop = child->property ("val")) != 0) {
900 set_smpte_offset_negative( (prop->value() == "yes") );
903 if ((child = find_named_node (node, "click-sound")) != 0) {
904 if ((prop = child->property ("val")) != 0) {
905 click_sound = prop->value();
908 if ((child = find_named_node (node, "click-emphasis-sound")) != 0) {
909 if ((prop = child->property ("val")) != 0) {
910 click_emphasis_sound = prop->value();
914 if ((child = find_named_node (node, "solo-model")) != 0) {
915 if ((prop = child->property ("val")) != 0) {
916 if (prop->value() == "SoloBus")
917 _solo_model = SoloBus;
919 _solo_model = InverseMute;
923 /* BOOLEAN OPTIONS */
925 if ((child = find_named_node (node, "auto-play")) != 0) {
926 if ((prop = child->property ("val")) != 0) {
927 set_auto_play (prop->value() == "yes");
930 if ((child = find_named_node (node, "auto-input")) != 0) {
931 if ((prop = child->property ("val")) != 0) {
932 set_auto_input (prop->value() == "yes");
935 if ((child = find_named_node (node, "seamless-loop")) != 0) {
936 if ((prop = child->property ("val")) != 0) {
937 set_seamless_loop (prop->value() == "yes");
940 if ((child = find_named_node (node, "punch-in")) != 0) {
941 if ((prop = child->property ("val")) != 0) {
942 set_punch_in (prop->value() == "yes");
945 if ((child = find_named_node (node, "punch-out")) != 0) {
946 if ((prop = child->property ("val")) != 0) {
947 set_punch_out (prop->value() == "yes");
950 if ((child = find_named_node (node, "auto-return")) != 0) {
951 if ((prop = child->property ("val")) != 0) {
952 set_auto_return (prop->value() == "yes");
955 if ((child = find_named_node (node, "send-mtc")) != 0) {
956 if ((prop = child->property ("val")) != 0) {
957 set_send_mtc (prop->value() == "yes");
960 if ((child = find_named_node (node, "mmc-control")) != 0) {
961 if ((prop = child->property ("val")) != 0) {
962 set_mmc_control (prop->value() == "yes");
965 if ((child = find_named_node (node, "midi-control")) != 0) {
966 if ((prop = child->property ("val")) != 0) {
967 set_midi_control (prop->value() == "yes");
970 if ((child = find_named_node (node, "midi-feedback")) != 0) {
971 if ((prop = child->property ("val")) != 0) {
972 set_midi_feedback (prop->value() == "yes");
975 if ((child = find_named_node (node, "recording-plugins")) != 0) {
976 if ((prop = child->property ("val")) != 0) {
977 set_recording_plugins (prop->value() == "yes");
980 if ((child = find_named_node (node, "crossfades-active")) != 0) {
981 if ((prop = child->property ("val")) != 0) {
982 set_crossfades_active (prop->value() == "yes");
985 if ((child = find_named_node (node, "audible-click")) != 0) {
986 if ((prop = child->property ("val")) != 0) {
987 set_clicking (prop->value() == "yes");
991 if ((child = find_named_node (node, "align-style")) != 0) {
992 if ((prop = child->property ("val")) != 0) {
993 if (prop->value() == "capture") {
994 set_align_style (CaptureTime);
996 set_align_style (ExistingMaterial);
1001 if ((child = find_named_node (node, "layer-model")) != 0) {
1002 if ((prop = child->property ("val")) != 0) {
1003 if (prop->value() == X_("LaterHigher")) {
1004 set_layer_model (LaterHigher);
1005 } else if (prop->value() == X_("AddHigher")) {
1006 set_layer_model (AddHigher);
1008 set_layer_model (MoveAddHigher);
1013 if ((child = find_named_node (node, "xfade-model")) != 0) {
1014 if ((prop = child->property ("val")) != 0) {
1015 if (prop->value() == X_("Short")) {
1016 set_xfade_model (ShortCrossfade);
1018 set_xfade_model (FullCrossfade);
1023 if ((child = find_named_node (node, "short-xfade-length")) != 0) {
1024 if ((prop = child->property ("val")) != 0) {
1025 /* value is stored as a fractional seconds */
1026 float secs = atof (prop->value().c_str());
1027 Crossfade::set_short_xfade_length ((jack_nframes_t) floor (secs * frame_rate()));
1031 if ((child = find_named_node (node, "full-xfades-unmuted")) != 0) {
1032 if ((prop = child->property ("val")) != 0) {
1033 crossfades_active = (prop->value() == "yes");
1039 if ((child = find_named_node (node, "default-fade-steepness")) != 0) {
1040 if ((prop = child->property ("val")) != 0) {
1041 fade_steepness = atof (prop->value().c_str());
1042 have_fade_steepness = true;
1045 if ((child = find_named_node (node, "default-fade-msec")) != 0) {
1046 if ((prop = child->property ("val")) != 0) {
1047 fade_msecs = atof (prop->value().c_str());
1048 have_fade_msecs = true;
1052 if (have_fade_steepness || have_fade_msecs) {
1053 // set_default_fade (fade_steepness, fade_msecs);
1060 Session::get_options () const
1065 LocaleGuard lg (X_("POSIX"));
1067 opthead = new XMLNode ("Options");
1069 SlaveSource src = slave_source ();
1073 src_string = "none";
1079 src_string = "jack";
1082 child = opthead->add_child ("slave");
1083 child->add_property ("type", src_string);
1085 child = opthead->add_child ("send-midi-timecode");
1086 child->add_property ("val", send_midi_timecode?"yes":"no");
1088 child = opthead->add_child ("send-midi-machine-control");
1089 child->add_property ("val", send_midi_machine_control?"yes":"no");
1091 snprintf (buf, sizeof(buf)-1, "%x", (int) input_auto_connect);
1092 child = opthead->add_child ("input-auto-connect");
1093 child->add_property ("val", buf);
1095 snprintf (buf, sizeof(buf)-1, "%x", (int) output_auto_connect);
1096 child = opthead->add_child ("output-auto-connect");
1097 child->add_property ("val", buf);
1099 snprintf (buf, sizeof(buf)-1, "%d", max_level);
1100 child = opthead->add_child ("max-level");
1101 child->add_property ("val", buf);
1103 snprintf (buf, sizeof(buf)-1, "%d", min_level);
1104 child = opthead->add_child ("min-level");
1105 child->add_property ("val", buf);
1107 snprintf (buf, sizeof(buf)-1, "%f", _meter_hold);
1108 child = opthead->add_child ("meter-hold");
1109 child->add_property ("val", buf);
1111 snprintf (buf, sizeof(buf)-1, "%f", _meter_falloff);
1112 child = opthead->add_child ("meter-falloff");
1113 child->add_property ("val", buf);
1115 snprintf (buf, sizeof(buf)-1, "%u", over_length_long);
1116 child = opthead->add_child ("long-over-length");
1117 child->add_property ("val", buf);
1119 snprintf (buf, sizeof(buf)-1, "%u", over_length_short);
1120 child = opthead->add_child ("short-over-length");
1121 child->add_property ("val", buf);
1123 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_factor);
1124 child = opthead->add_child ("shuttle-speed-factor");
1125 child->add_property ("val", buf);
1127 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_threshold);
1128 child = opthead->add_child ("shuttle-speed-threshold");
1129 child->add_property ("val", buf);
1131 snprintf (buf, sizeof(buf)-1, "%f", rf_speed);
1132 child = opthead->add_child ("rf-speed");
1133 child->add_property ("val", buf);
1135 snprintf (buf, sizeof(buf)-1, "%.2f", smpte_frames_per_second);
1136 child = opthead->add_child ("smpte-frames-per-second");
1137 child->add_property ("val", buf);
1139 child = opthead->add_child ("smpte-drop-frames");
1140 child->add_property ("val", smpte_drop_frames ? "yes" : "no");
1142 snprintf (buf, sizeof(buf)-1, "%u", smpte_offset ());
1143 child = opthead->add_child ("smpte-offset");
1144 child->add_property ("val", buf);
1146 child = opthead->add_child ("smpte-offset-negative");
1147 child->add_property ("val", smpte_offset_negative () ? "yes" : "no");
1149 child = opthead->add_child ("edit-mode");
1150 switch (_edit_mode) {
1152 child->add_property ("val", "splice");
1156 child->add_property ("val", "slide");
1160 child = opthead->add_child ("auto-play");
1161 child->add_property ("val", get_auto_play () ? "yes" : "no");
1162 child = opthead->add_child ("auto-input");
1163 child->add_property ("val", get_auto_input () ? "yes" : "no");
1164 child = opthead->add_child ("seamless-loop");
1165 child->add_property ("val", get_seamless_loop () ? "yes" : "no");
1166 child = opthead->add_child ("punch-in");
1167 child->add_property ("val", get_punch_in () ? "yes" : "no");
1168 child = opthead->add_child ("punch-out");
1169 child->add_property ("val", get_punch_out () ? "yes" : "no");
1170 child = opthead->add_child ("all-safe");
1171 child->add_property ("val", get_all_safe () ? "yes" : "no");
1172 child = opthead->add_child ("auto-return");
1173 child->add_property ("val", get_auto_return () ? "yes" : "no");
1174 child = opthead->add_child ("mmc-control");
1175 child->add_property ("val", get_mmc_control () ? "yes" : "no");
1176 child = opthead->add_child ("midi-control");
1177 child->add_property ("val", get_midi_control () ? "yes" : "no");
1178 child = opthead->add_child ("midi-feedback");
1179 child->add_property ("val", get_midi_feedback () ? "yes" : "no");
1180 child = opthead->add_child ("recording-plugins");
1181 child->add_property ("val", get_recording_plugins () ? "yes" : "no");
1182 child = opthead->add_child ("auto-crossfade");
1183 child->add_property ("val", get_crossfades_active () ? "yes" : "no");
1184 child = opthead->add_child ("audible-click");
1185 child->add_property ("val", get_clicking () ? "yes" : "no");
1187 if (click_sound.length()) {
1188 child = opthead->add_child ("click-sound");
1189 child->add_property ("val", click_sound);
1192 if (click_emphasis_sound.length()) {
1193 child = opthead->add_child ("click-emphasis-sound");
1194 child->add_property ("val", click_emphasis_sound);
1197 child = opthead->add_child ("solo-model");
1198 child->add_property ("val", _solo_model == SoloBus ? "SoloBus" : "InverseMute");
1200 child = opthead->add_child ("align-style");
1201 child->add_property ("val", (align_style == ExistingMaterial ? "existing" : "capture"));
1203 child = opthead->add_child ("layer-model");
1204 switch (layer_model) {
1206 child->add_property ("val", X_("LaterHigher"));
1209 child->add_property ("val", X_("MoveAddHigher"));
1212 child->add_property ("val", X_("AddHigher"));
1216 child = opthead->add_child ("xfade-model");
1217 switch (xfade_model) {
1219 child->add_property ("val", X_("Full"));
1221 case ShortCrossfade:
1222 child->add_property ("val", X_("Short"));
1225 child = opthead->add_child ("short-xfade-length");
1226 /* store as fractions of a second */
1227 snprintf (buf, sizeof(buf)-1, "%f",
1228 (float) Crossfade::short_xfade_length() / frame_rate());
1229 child->add_property ("val", buf);
1231 child = opthead->add_child ("full-xfades-unmuted");
1232 child->add_property ("val", crossfades_active ? "yes" : "no");
1238 Session::get_state()
1244 Session::get_template()
1246 /* if we don't disable rec-enable, diskstreams
1247 will believe they need to store their capture
1248 sources in their state node.
1253 cerr << "STart get template\n";
1254 return state(false);
1258 Session::state(bool full_state)
1260 XMLNode* node = new XMLNode("Session");
1263 // store libardour version, just in case
1265 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
1266 libardour_major_version, libardour_minor_version, libardour_micro_version);
1267 node->add_property("version", string(buf));
1269 /* store configuration settings */
1273 /* store the name */
1274 node->add_property ("name", _name);
1276 if (session_dirs.size() > 1) {
1280 vector<space_and_path>::iterator i = session_dirs.begin();
1281 vector<space_and_path>::iterator next;
1283 ++i; /* skip the first one */
1287 while (i != session_dirs.end()) {
1291 if (next != session_dirs.end()) {
1301 child = node->add_child ("Path");
1302 child->add_content (p);
1306 node->add_child_nocopy (get_options());
1308 child = node->add_child ("Sources");
1311 LockMonitor sl (source_lock, __LINE__, __FILE__);
1313 for (SourceList::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1315 /* Don't save information about FileSources that are empty */
1319 if ((fs = dynamic_cast<FileSource*> ((*siter).second)) != 0) {
1320 if (fs->length() == 0) {
1325 child->add_child_nocopy ((*siter).second->get_state());
1329 child = node->add_child ("Regions");
1332 LockMonitor rl (region_lock, __LINE__, __FILE__);
1334 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1336 /* only store regions not attached to playlists */
1338 if ((*i).second->playlist() == 0) {
1339 child->add_child_nocopy (i->second->state (true));
1344 child = node->add_child ("DiskStreams");
1347 LockMonitor dl (diskstream_lock, __LINE__, __FILE__);
1348 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1349 if (!(*i)->hidden()) {
1350 child->add_child_nocopy ((*i)->get_state());
1355 node->add_child_nocopy (_locations.get_state());
1357 child = node->add_child ("Connections");
1359 LockMonitor lm (connection_lock, __LINE__, __FILE__);
1360 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1361 if (!(*i)->system_dependent()) {
1362 child->add_child_nocopy ((*i)->get_state());
1367 child = node->add_child ("Routes");
1369 LockMonitor lm (route_lock, __LINE__, __FILE__);
1371 RoutePublicOrderSorter cmp;
1372 RouteList public_order(routes);
1373 public_order.sort (cmp);
1375 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1376 if (!(*i)->hidden()) {
1378 child->add_child_nocopy ((*i)->get_state());
1380 child->add_child_nocopy ((*i)->get_template());
1387 child = node->add_child ("EditGroups");
1388 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1389 child->add_child_nocopy ((*i)->get_state());
1392 child = node->add_child ("MixGroups");
1393 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1394 child->add_child_nocopy ((*i)->get_state());
1397 child = node->add_child ("Playlists");
1398 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1399 if (!(*i)->hidden()) {
1400 if (!(*i)->empty()) {
1402 child->add_child_nocopy ((*i)->get_state());
1404 child->add_child_nocopy ((*i)->get_template());
1410 child = node->add_child ("UnusedPlaylists");
1411 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1412 if (!(*i)->hidden()) {
1413 if (!(*i)->empty()) {
1415 child->add_child_nocopy ((*i)->get_state());
1417 child->add_child_nocopy ((*i)->get_template());
1425 child = node->add_child ("Click");
1426 child->add_child_nocopy (_click_io->state (full_state));
1430 child = node->add_child ("NamedSelections");
1431 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1433 child->add_child_nocopy ((*i)->get_state());
1438 node->add_child_nocopy (_tempo_map->get_state());
1441 node->add_child_copy (*_extra_xml);
1448 Session::set_state (const XMLNode& node)
1452 const XMLProperty* prop;
1454 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1456 if (node.name() != "Session"){
1457 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1461 if ((prop = node.property ("name")) != 0) {
1462 _name = prop->value ();
1465 IO::disable_ports ();
1466 IO::disable_connecting ();
1468 /* Object loading order:
1485 if (use_config_midi_ports ()) {
1489 if ((child = find_named_node (node, "Path")) != 0) {
1490 /* XXX this XML content stuff horrible API design */
1491 string raid_path = _path + ':' + child->children().front()->content();
1492 setup_raid_path (raid_path);
1494 /* the path is already set */
1497 if ((child = find_named_node (node, "extra")) != 0) {
1498 _extra_xml = new XMLNode (*child);
1501 if ((child = find_named_node (node, "Options")) == 0) {
1502 error << _("Session: XML state has no options section") << endmsg;
1504 } else if (load_options (*child)) {
1508 if ((child = find_named_node (node, "Sources")) == 0) {
1509 error << _("Session: XML state has no sources section") << endmsg;
1511 } else if (load_sources (*child)) {
1515 if ((child = find_named_node (node, "Regions")) == 0) {
1516 error << _("Session: XML state has no Regions section") << endmsg;
1518 } else if (load_regions (*child)) {
1522 if ((child = find_named_node (node, "Playlists")) == 0) {
1523 error << _("Session: XML state has no playlists section") << endmsg;
1525 } else if (load_playlists (*child)) {
1529 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1531 } else if (load_unused_playlists (*child)) {
1535 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1536 if (load_named_selections (*child)) {
1541 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1542 error << _("Session: XML state has no diskstreams section") << endmsg;
1544 } else if (load_diskstreams (*child)) {
1548 if ((child = find_named_node (node, "Connections")) == 0) {
1549 error << _("Session: XML state has no connections section") << endmsg;
1551 } else if (load_connections (*child)) {
1555 if ((child = find_named_node (node, "Locations")) == 0) {
1556 error << _("Session: XML state has no locations section") << endmsg;
1558 } else if (_locations.set_state (*child)) {
1564 if ((location = _locations.auto_loop_location()) != 0) {
1565 set_auto_loop_location (location);
1568 if ((location = _locations.auto_punch_location()) != 0) {
1569 set_auto_punch_location (location);
1572 if ((location = _locations.end_location()) == 0) {
1573 _locations.add (end_location);
1575 end_location = location;
1578 _locations.save_state (_("initial state"));
1580 if ((child = find_named_node (node, "EditGroups")) == 0) {
1581 error << _("Session: XML state has no edit groups section") << endmsg;
1583 } else if (load_edit_groups (*child)) {
1587 if ((child = find_named_node (node, "MixGroups")) == 0) {
1588 error << _("Session: XML state has no mix groups section") << endmsg;
1590 } else if (load_mix_groups (*child)) {
1594 if ((child = find_named_node (node, "TempoMap")) == 0) {
1595 error << _("Session: XML state has no Tempo Map section") << endmsg;
1597 } else if (_tempo_map->set_state (*child)) {
1601 if ((child = find_named_node (node, "Routes")) == 0) {
1602 error << _("Session: XML state has no routes section") << endmsg;
1604 } else if (load_routes (*child)) {
1608 if ((child = find_named_node (node, "Click")) == 0) {
1609 warning << _("Session: XML state has no click section") << endmsg;
1610 } else if (_click_io) {
1611 _click_io->set_state (*child);
1614 /* OK, now we can set edit mode */
1616 set_edit_mode (pending_edit_mode);
1618 /* here beginneth the second phase ... */
1620 StateReady (); /* EMIT SIGNAL */
1622 _state_of_the_state = Clean;
1624 if (state_was_pending) {
1625 save_state (_current_snapshot_name);
1626 remove_pending_capture_state ();
1627 state_was_pending = false;
1634 Session::load_routes (const XMLNode& node)
1637 XMLNodeConstIterator niter;
1640 nlist = node.children();
1644 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1646 if ((route = XMLRouteFactory (**niter)) == 0) {
1647 error << _("Session: cannot create Route from XML description.") << endmsg;
1658 Session::XMLRouteFactory (const XMLNode& node)
1660 if (node.name() != "Route") {
1664 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1665 return new AudioTrack (*this, node);
1667 return new Route (*this, node);
1672 Session::load_regions (const XMLNode& node)
1675 XMLNodeConstIterator niter;
1676 AudioRegion* region;
1678 nlist = node.children();
1682 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1684 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1685 error << _("Session: cannot create Region from XML description.") << endmsg;
1693 Session::XMLRegionFactory (const XMLNode& node, bool full)
1695 const XMLProperty* prop;
1698 AudioRegion::SourceList sources;
1699 uint32_t nchans = 1;
1702 if (node.name() != X_("Region")) {
1706 if ((prop = node.property (X_("channels"))) != 0) {
1707 nchans = atoi (prop->value().c_str());
1711 if ((prop = node.property (X_("source-0"))) == 0) {
1712 if ((prop = node.property ("source")) == 0) {
1713 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
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;
1725 sources.push_back(source);
1727 /* pickup other channels */
1729 for (uint32_t n=1; n < nchans; ++n) {
1730 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1731 if ((prop = node.property (buf)) != 0) {
1732 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1734 if ((source = get_source (s_id)) == 0) {
1735 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1738 sources.push_back(source);
1744 return new AudioRegion (sources, node);
1747 catch (failed_constructor& err) {
1753 Session::get_sources_as_xml ()
1756 XMLNode* node = new XMLNode (X_("Sources"));
1757 LockMonitor lm (source_lock, __LINE__, __FILE__);
1759 for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
1760 node->add_child_nocopy ((*i).second->get_state());
1767 Session::path_from_region_name (string name, string identifier)
1769 char buf[PATH_MAX+1];
1771 string dir = discover_best_sound_dir ();
1773 for (n = 0; n < 999999; ++n) {
1774 if (identifier.length()) {
1775 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1776 identifier.c_str(), n);
1778 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1780 if (access (buf, F_OK) != 0) {
1790 Session::load_sources (const XMLNode& node)
1793 XMLNodeConstIterator niter;
1796 nlist = node.children();
1800 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1802 if ((source = XMLSourceFactory (**niter)) == 0) {
1803 error << _("Session: cannot create Source from XML description.") << endmsg;
1811 Session::XMLSourceFactory (const XMLNode& node)
1815 if (node.name() != "Source") {
1820 src = new FileSource (node, frame_rate());
1823 catch (failed_constructor& err) {
1826 src = new SndFileSource (node);
1829 catch (failed_constructor& err) {
1830 error << _("Found a sound file that cannot be used by Ardour. See the progammers.") << endmsg;
1839 Session::save_template (string template_name)
1842 string xml_path, bak_path, template_path;
1844 if (_state_of_the_state & CannotSave) {
1849 string dir = template_dir();
1851 if ((dp = opendir (dir.c_str()))) {
1854 if (mkdir (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)<0) {
1855 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1860 tree.set_root (&get_template());
1863 xml_path += template_name;
1864 xml_path += _template_suffix;
1866 ifstream in(xml_path.c_str());
1869 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1875 if (!tree.write (xml_path)) {
1876 error << _("mix template not saved") << endmsg;
1884 Session::rename_template (string old_name, string new_name)
1886 string old_path = template_dir() + old_name + _template_suffix;
1887 string new_path = template_dir() + new_name + _template_suffix;
1889 return rename (old_path.c_str(), new_path.c_str());
1893 Session::delete_template (string name)
1895 string template_path = template_dir();
1896 template_path += name;
1897 template_path += _template_suffix;
1899 return remove (template_path.c_str());
1903 Session::refresh_disk_space ()
1906 struct statfs statfsbuf;
1907 vector<space_and_path>::iterator i;
1908 LockMonitor lm (space_lock, __LINE__, __FILE__);
1911 /* get freespace on every FS that is part of the session path */
1913 _total_free_4k_blocks = 0;
1915 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1916 statfs ((*i).path.c_str(), &statfsbuf);
1918 scale = statfsbuf.f_bsize/4096.0;
1920 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1921 _total_free_4k_blocks += (*i).blocks;
1927 Session::ensure_sound_dir (string path, string& result)
1932 /* Ensure that the parent directory exists */
1934 if (mkdir (path.c_str(), 0775)) {
1935 if (errno != EEXIST) {
1936 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1941 /* Ensure that the sounds directory exists */
1945 result += sound_dir_name;
1947 if (mkdir (result.c_str(), 0775)) {
1948 if (errno != EEXIST) {
1949 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1956 dead += dead_sound_dir_name;
1958 if (mkdir (dead.c_str(), 0775)) {
1959 if (errno != EEXIST) {
1960 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1967 peak += peak_dir_name;
1969 if (mkdir (peak.c_str(), 0775)) {
1970 if (errno != EEXIST) {
1971 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1976 /* callers expect this to be terminated ... */
1983 Session::discover_best_sound_dir ()
1985 vector<space_and_path>::iterator i;
1988 /* handle common case without system calls */
1990 if (session_dirs.size() == 1) {
1994 /* OK, here's the algorithm we're following here:
1996 We want to select which directory to use for
1997 the next file source to be created. Ideally,
1998 we'd like to use a round-robin process so as to
1999 get maximum performance benefits from splitting
2000 the files across multiple disks.
2002 However, in situations without much diskspace, an
2003 RR approach may end up filling up a filesystem
2004 with new files while others still have space.
2005 Its therefore important to pay some attention to
2006 the freespace in the filesystem holding each
2007 directory as well. However, if we did that by
2008 itself, we'd keep creating new files in the file
2009 system with the most space until it was as full
2010 as all others, thus negating any performance
2011 benefits of this RAID-1 like approach.
2013 So, we use a user-configurable space threshold. If
2014 there are at least 2 filesystems with more than this
2015 much space available, we use RR selection between them.
2016 If not, then we pick the filesystem with the most space.
2018 This gets a good balance between the two
2022 refresh_disk_space ();
2024 int free_enough = 0;
2026 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2027 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2032 if (free_enough >= 2) {
2034 bool found_it = false;
2036 /* use RR selection process, ensuring that the one
2040 i = last_rr_session_dir;
2043 if (++i == session_dirs.end()) {
2044 i = session_dirs.begin();
2047 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2048 if (ensure_sound_dir ((*i).path, result) == 0) {
2049 last_rr_session_dir = i;
2055 } while (i != last_rr_session_dir);
2058 result = sound_dir();
2063 /* pick FS with the most freespace (and that
2064 seems to actually work ...)
2067 vector<space_and_path> sorted;
2068 space_and_path_ascending_cmp cmp;
2070 sorted = session_dirs;
2071 sort (sorted.begin(), sorted.end(), cmp);
2073 for (i = sorted.begin(); i != sorted.end(); ++i) {
2074 if (ensure_sound_dir ((*i).path, result) == 0) {
2075 last_rr_session_dir = i;
2080 /* if the above fails, fall back to the most simplistic solution */
2082 if (i == sorted.end()) {
2091 Session::load_playlists (const XMLNode& node)
2094 XMLNodeConstIterator niter;
2097 nlist = node.children();
2101 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2103 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2104 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2112 Session::load_unused_playlists (const XMLNode& node)
2115 XMLNodeConstIterator niter;
2118 nlist = node.children();
2122 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2124 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2125 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2129 // now manually untrack it
2131 track_playlist (playlist, false);
2139 Session::XMLPlaylistFactory (const XMLNode& node)
2142 return new AudioPlaylist (*this, node);
2145 catch (failed_constructor& err) {
2151 Session::load_named_selections (const XMLNode& node)
2154 XMLNodeConstIterator niter;
2157 nlist = node.children();
2161 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2163 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2164 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2172 Session::XMLNamedSelectionFactory (const XMLNode& node)
2175 return new NamedSelection (*this, node);
2178 catch (failed_constructor& err) {
2184 Session::dead_sound_dir () const
2187 res += dead_sound_dir_name;
2193 Session::sound_dir () const
2196 res += sound_dir_name;
2202 Session::peak_dir () const
2205 res += peak_dir_name;
2211 Session::automation_dir () const
2214 res += "automation/";
2219 Session::template_dir ()
2221 string path = Config->get_user_ardour_path();
2222 path += "templates/";
2228 Session::template_path ()
2232 path += Config->get_user_ardour_path();
2233 if (path[path.length()-1] != ':') {
2236 path += Config->get_system_ardour_path();
2238 vector<string> split_path;
2240 split (path, split_path, ':');
2243 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2245 path += "templates/";
2247 if (distance (i, split_path.end()) != 1) {
2256 Session::load_connections (const XMLNode& node)
2258 XMLNodeList nlist = node.children();
2259 XMLNodeConstIterator niter;
2263 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2264 if ((*niter)->name() == "InputConnection") {
2265 add_connection (new ARDOUR::InputConnection (**niter));
2266 } else if ((*niter)->name() == "OutputConnection") {
2267 add_connection (new ARDOUR::OutputConnection (**niter));
2269 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2278 Session::load_edit_groups (const XMLNode& node)
2280 return load_route_groups (node, true);
2284 Session::load_mix_groups (const XMLNode& node)
2286 return load_route_groups (node, false);
2290 Session::load_route_groups (const XMLNode& node, bool edit)
2292 XMLNodeList nlist = node.children();
2293 XMLNodeConstIterator niter;
2298 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2299 if ((*niter)->name() == "RouteGroup") {
2301 route = add_edit_group ("");
2302 route->set_state (**niter);
2304 route = add_mix_group ("");
2305 route->set_state (**niter);
2314 Session::swap_configuration(Configuration** new_config)
2316 LockMonitor lm (route_lock, __LINE__, __FILE__);
2317 Configuration* tmp = *new_config;
2318 *new_config = Config;
2324 Session::copy_configuration(Configuration* new_config)
2326 LockMonitor lm (route_lock, __LINE__, __FILE__);
2327 new_config = new Configuration(*Config);
2331 state_file_filter (const string &str, void *arg)
2333 return (str.length() > strlen(Session::statefile_suffix()) &&
2334 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2338 bool operator()(const string* a, const string* b) {
2344 remove_end(string* state)
2346 string statename(*state);
2348 string::size_type start,end;
2349 if ((start = statename.find_last_of ('/')) != string::npos) {
2350 statename = statename.substr (start+1);
2353 if ((end = statename.rfind(".ardour")) < 0) {
2354 end = statename.length();
2357 return new string(statename.substr (0, end));
2361 Session::possible_states (string path)
2363 PathScanner scanner;
2364 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2366 transform(states->begin(), states->end(), states->begin(), remove_end);
2369 sort (states->begin(), states->end(), cmp);
2375 Session::possible_states () const
2377 return possible_states(_path);
2381 Session::auto_save()
2383 save_state (_current_snapshot_name);
2387 Session::add_edit_group (string name)
2389 RouteGroup* rg = new RouteGroup (name);
2390 edit_groups.push_back (rg);
2391 edit_group_added (rg); /* EMIT SIGNAL */
2397 Session::add_mix_group (string name)
2399 RouteGroup* rg = new RouteGroup (name, RouteGroup::Relative);
2400 mix_groups.push_back (rg);
2401 mix_group_added (rg); /* EMIT SIGNAL */
2407 Session::mix_group_by_name (string name)
2409 list<RouteGroup *>::iterator i;
2411 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2412 if ((*i)->name() == name) {
2420 Session::edit_group_by_name (string name)
2422 list<RouteGroup *>::iterator i;
2424 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2425 if ((*i)->name() == name) {
2433 Session::set_meter_hold (float val)
2436 MeterHoldChanged(); // emit
2440 Session::set_meter_falloff (float val)
2442 _meter_falloff = val;
2443 MeterFalloffChanged(); // emit
2448 Session::begin_reversible_command (string name, UndoAction* private_undo)
2450 current_cmd.clear ();
2451 current_cmd.set_name (name);
2454 current_cmd.add_undo (*private_undo);
2459 Session::commit_reversible_command (UndoAction* private_redo)
2464 current_cmd.add_redo_no_execute (*private_redo);
2467 gettimeofday (&now, 0);
2468 current_cmd.set_timestamp (now);
2470 history.add (current_cmd);
2473 Session::GlobalRouteBooleanState
2474 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2476 GlobalRouteBooleanState s;
2477 LockMonitor lm (route_lock, __LINE__, __FILE__);
2479 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2480 if (!(*i)->hidden()) {
2481 RouteBooleanState v;
2484 v.second = ((*i)->*method)();
2493 Session::GlobalRouteMeterState
2494 Session::get_global_route_metering ()
2496 GlobalRouteMeterState s;
2497 LockMonitor lm (route_lock, __LINE__, __FILE__);
2499 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2500 if (!(*i)->hidden()) {
2504 v.second = (*i)->meter_point();
2514 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2516 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2517 i->first->set_meter_point (i->second, arg);
2522 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2524 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2525 (i->first->*method) (i->second, arg);
2530 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2532 set_global_route_boolean (s, &Route::set_mute, src);
2536 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2538 set_global_route_boolean (s, &Route::set_solo, src);
2542 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2544 set_global_route_boolean (s, &Route::set_record_enable, src);
2548 Session::global_mute_memento (void* src)
2550 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2554 Session::global_metering_memento (void* src)
2556 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2560 Session::global_solo_memento (void* src)
2562 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2566 Session::global_record_enable_memento (void* src)
2568 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2572 template_filter (const string &str, void *arg)
2574 return (str.length() > strlen(Session::template_suffix()) &&
2575 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2579 Session::get_template_list (list<string> &template_names)
2581 vector<string *> *templates;
2582 PathScanner scanner;
2585 path = template_path ();
2587 templates = scanner (path, template_filter, 0, false, true);
2589 vector<string*>::iterator i;
2590 for (i = templates->begin(); i != templates->end(); ++i) {
2591 string fullpath = *(*i);
2594 start = fullpath.find_last_of ('/') + 1;
2595 if ((end = fullpath.find_last_of ('.')) <0) {
2596 end = fullpath.length();
2599 template_names.push_back(fullpath.substr(start, (end-start)));
2604 Session::read_favorite_dirs (FavoriteDirs & favs)
2606 string path = Config->get_user_ardour_path();
2607 path += "/favorite_dirs";
2609 ifstream fav (path.c_str());
2614 if (errno != ENOENT) {
2615 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2626 getline(fav, newfav);
2632 favs.push_back (newfav);
2639 Session::write_favorite_dirs (FavoriteDirs & favs)
2641 string path = Config->get_user_ardour_path();
2642 path += "/favorite_dirs";
2644 ofstream fav (path.c_str());
2650 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2651 fav << (*i) << endl;
2658 accept_all_non_peak_files (const string& path, void *arg)
2660 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2664 accept_all_state_files (const string& path, void *arg)
2666 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2670 Session::find_all_sources (string path, set<string>& result)
2675 if (!tree.read (path)) {
2679 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2684 XMLNodeConstIterator niter;
2686 nlist = node->children();
2690 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2694 if ((prop = (*niter)->property (X_("name"))) == 0) {
2698 if (prop->value()[0] == '/') {
2699 /* external file, ignore */
2703 string path = _path; /* /-terminated */
2704 path += sound_dir_name;
2706 path += prop->value();
2708 result.insert (path);
2715 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2717 PathScanner scanner;
2718 vector<string*>* state_files;
2720 string this_snapshot_path;
2726 if (ripped[ripped.length()-1] == '/') {
2727 ripped = ripped.substr (0, ripped.length() - 1);
2730 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2732 if (state_files == 0) {
2737 this_snapshot_path = _path;
2738 this_snapshot_path += _current_snapshot_name;
2739 this_snapshot_path += _statefile_suffix;
2741 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2743 if (exclude_this_snapshot && **i == this_snapshot_path) {
2747 if (find_all_sources (**i, result) < 0) {
2756 Session::cleanup_sources (Session::cleanup_report& rep)
2758 vector<Source*> dead_sources;
2759 vector<Playlist*> playlists_tbd;
2760 PathScanner scanner;
2762 vector<space_and_path>::iterator i;
2763 vector<space_and_path>::iterator nexti;
2764 vector<string*>* soundfiles;
2765 vector<string> unused;
2766 set<string> all_sources;
2771 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2773 /* step 1: consider deleting all unused playlists */
2775 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2778 status = AskAboutPlaylistDeletion (*x);
2787 playlists_tbd.push_back (*x);
2791 /* leave it alone */
2796 /* now delete any that were marked for deletion */
2798 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2799 PlaylistList::iterator foo;
2801 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2802 unused_playlists.erase (foo);
2807 /* step 2: clear the undo/redo history for all playlists */
2809 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2810 (*x)->drop_all_states ();
2813 /* step 3: find all un-referenced sources */
2818 for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
2820 SourceList::iterator tmp;
2825 /* only remove files that are not in use and have some size
2826 to them. otherwise we remove the current "nascent"
2830 if ((*i).second->use_cnt() == 0 && (*i).second->length() > 0) {
2831 dead_sources.push_back (i->second);
2833 /* remove this source from our own list to avoid us
2834 adding it to the list of all sources below
2843 /* Step 4: get rid of all regions in the region list that use any dead sources
2844 in case the sources themselves don't go away (they might be referenced in
2848 for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2850 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2851 AudioRegionList::iterator tmp;
2859 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2860 if (&ar->source (n) == (*i)) {
2861 /* this region is dead */
2870 /* build a list of all the possible sound directories for the session */
2872 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2877 sound_path += (*i).path;
2878 sound_path += sound_dir_name;
2880 if (nexti != session_dirs.end()) {
2887 /* now do the same thing for the files that ended up in the sounds dir(s)
2888 but are not referenced as sources in any snapshot.
2891 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2893 if (soundfiles == 0) {
2897 /* find all sources, but don't use this snapshot because the
2898 state file on disk still references sources we may have already
2902 find_all_sources_across_snapshots (all_sources, true);
2904 /* add our current source list
2907 for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
2911 if ((fs = dynamic_cast<FileSource*> ((*i).second)) != 0) {
2912 all_sources.insert (fs->path());
2913 } else if ((sfs = dynamic_cast<SndFileSource*> ((*i).second)) != 0) {
2914 all_sources.insert (sfs->path());
2918 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2923 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2933 unused.push_back (spath);
2937 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2939 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2940 struct stat statbuf;
2942 rep.paths.push_back (*x);
2943 if (stat ((*x).c_str(), &statbuf) == 0) {
2944 rep.space += statbuf.st_size;
2949 /* don't move the file across filesystems, just
2950 stick it in the `dead_sound_dir_name' directory
2951 on whichever filesystem it was already on.
2954 newpath = PBD::dirname (*x);
2955 newpath = PBD::dirname (newpath);
2958 newpath += dead_sound_dir_name;
2960 newpath += PBD::basename ((*x));
2962 if (access (newpath.c_str(), F_OK) == 0) {
2964 /* the new path already exists, try versioning */
2966 char buf[PATH_MAX+1];
2970 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2973 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2974 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2978 if (version == 999) {
2979 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2983 newpath = newpath_v;
2988 /* it doesn't exist, or we can't read it or something */
2992 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2993 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2994 (*x), newpath, strerror (errno))
3000 /* see if there an easy to find peakfile for this file, and remove it.
3003 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
3004 peakpath += ".peak";
3006 if (access (peakpath.c_str(), W_OK) == 0) {
3007 if (::unlink (peakpath.c_str()) != 0) {
3008 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3009 peakpath, _path, strerror (errno))
3011 /* try to back out */
3012 rename (newpath.c_str(), _path.c_str());
3021 /* dump the history list */
3025 /* save state so we don't end up a session file
3026 referring to non-existent sources.
3032 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3037 Session::cleanup_trash_sources (Session::cleanup_report& rep)
3039 vector<space_and_path>::iterator i;
3040 string dead_sound_dir;
3041 struct dirent* dentry;
3042 struct stat statbuf;
3048 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3050 dead_sound_dir = (*i).path;
3051 dead_sound_dir += dead_sound_dir_name;
3053 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
3057 while ((dentry = readdir (dead)) != 0) {
3059 /* avoid '.' and '..' */
3061 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
3062 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3068 fullpath = dead_sound_dir;
3070 fullpath += dentry->d_name;
3072 if (stat (fullpath.c_str(), &statbuf)) {
3076 if (!S_ISREG (statbuf.st_mode)) {
3080 if (unlink (fullpath.c_str())) {
3081 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3082 fullpath, strerror (errno))
3086 rep.paths.push_back (dentry->d_name);
3087 rep.space += statbuf.st_size;
3098 Session::set_dirty ()
3100 bool was_dirty = dirty();
3102 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3105 DirtyChanged(); /* EMIT SIGNAL */
3111 Session::set_clean ()
3113 bool was_dirty = dirty();
3115 _state_of_the_state = Clean;
3118 DirtyChanged(); /* EMIT SIGNAL */