2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include <sigc++/bind.h>
28 #include <cstdio> /* snprintf(3) ... grrr */
43 #include <sys/mount.h>
44 #include <sys/param.h>
47 #include <midi++/mmc.h>
48 #include <midi++/port.h>
49 #include <pbd/error.h>
50 #include <pbd/dirname.h>
51 #include <pbd/lockmonitor.h>
52 #include <pbd/pathscanner.h>
53 #include <pbd/pthread_utils.h>
54 #include <pbd/basename.h>
55 #include <pbd/strsplit.h>
57 #include <ardour/audioengine.h>
58 #include <ardour/configuration.h>
59 #include <ardour/session.h>
60 #include <ardour/diskstream.h>
61 #include <ardour/utils.h>
62 #include <ardour/audioplaylist.h>
63 #include <ardour/source.h>
64 #include <ardour/filesource.h>
65 #include <ardour/sndfilesource.h>
66 #include <ardour/sndfile_helpers.h>
67 #include <ardour/auditioner.h>
68 #include <ardour/export.h>
69 #include <ardour/redirect.h>
70 #include <ardour/send.h>
71 #include <ardour/insert.h>
72 #include <ardour/connection.h>
73 #include <ardour/slave.h>
74 #include <ardour/tempo.h>
75 #include <ardour/audio_track.h>
76 #include <ardour/cycle_timer.h>
77 #include <ardour/utils.h>
78 #include <ardour/named_selection.h>
79 #include <ardour/version.h>
80 #include <ardour/location.h>
81 #include <ardour/audioregion.h>
82 #include <ardour/crossfade.h>
88 using namespace ARDOUR;
91 Session::first_stage_init (string fullpath, string snapshot_name)
93 if (fullpath.length() == 0) {
94 throw failed_constructor();
98 if (!realpath(fullpath.c_str(), buf) && (errno != ENOENT)) {
99 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
100 throw failed_constructor();
104 if (_path[_path.length()-1] != '/') {
108 /* these two are just provisional settings. set_state()
109 will likely override them.
112 _name = _current_snapshot_name = snapshot_name;
113 setup_raid_path (_path);
115 _current_frame_rate = _engine.frame_rate ();
116 _tempo_map = new TempoMap (_current_frame_rate);
117 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
119 atomic_set (&processing_prohibited, 0);
122 _transport_speed = 0;
123 _last_transport_speed = 0;
124 transport_sub_state = 0;
125 _transport_frame = 0;
127 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
128 _end_location_is_free = true;
129 atomic_set (&_record_status, Disabled);
134 seamless_loop = false;
135 loop_changing = false;
137 crossfades_active = false;
140 _last_roll_location = 0;
141 _last_record_location = 0;
142 pending_locate_frame = 0;
143 pending_locate_roll = false;
144 pending_locate_flush = false;
145 dstream_buffer_size = 0;
147 state_was_pending = false;
149 outbound_mtc_smpte_frame = 0;
150 next_quarter_frame_to_send = -1;
151 current_block_size = 0;
152 _solo_latched = true;
153 _solo_model = InverseMute;
154 solo_update_disabled = false;
155 currently_soloing = false;
156 _worst_output_latency = 0;
157 _worst_input_latency = 0;
158 _worst_track_latency = 0;
159 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
162 butler_mixdown_buffer = 0;
163 butler_gain_buffer = 0;
166 midi_feedback = false;
169 post_transport_work = PostTransportWork (0);
170 atomic_set (&butler_should_do_transport_work, 0);
171 atomic_set (&butler_active, 0);
172 atomic_set (&_playback_load, 100);
173 atomic_set (&_capture_load, 100);
174 atomic_set (&_playback_load_min, 100);
175 atomic_set (&_capture_load_min, 100);
176 pending_audition_region = 0;
178 pending_edit_mode = _edit_mode;
182 input_auto_connect = AutoConnectOption (0);
183 output_auto_connect = AutoConnectOption (0);
184 _have_captured = false;
185 waiting_to_start = false;
187 _gain_automation_buffer = 0;
188 _pan_automation_buffer = 0;
190 pending_abort = false;
191 layer_model = MoveAddHigher;
192 xfade_model = ShortCrossfade;
194 /* allocate conversion buffers */
195 _conversion_buffers[ButlerContext] = new char[DiskStream::disk_io_frames() * 4];
196 _conversion_buffers[TransportContext] = new char[DiskStream::disk_io_frames() * 4];
198 /* default short fade = 15ms */
200 Crossfade::set_short_xfade_length ((jack_nframes_t) floor ((15.0 * frame_rate()) / 1000.0));
202 last_mmc_step.tv_sec = 0;
203 last_mmc_step.tv_usec = 0;
206 preroll.type = AnyTime::Frames;
208 postroll.type = AnyTime::Frames;
211 /* click sounds are unset by default, which causes us to internal
212 waveforms for clicks.
217 click_requested = false;
219 click_emphasis_data = 0;
221 click_emphasis_length = 0;
223 process_function = &Session::process_with_events;
227 _smpte_offset_negative = true;
228 last_smpte_valid = false;
230 last_rr_session_dir = session_dirs.begin();
231 refresh_disk_space ();
233 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
235 /* default configuration */
237 do_not_record_plugins = false;
238 over_length_short = 2;
239 over_length_long = 10;
240 send_midi_timecode = false;
241 send_midi_machine_control = false;
242 shuttle_speed_factor = 1.0;
243 shuttle_speed_threshold = 5;
245 _meter_hold = 100; // XXX unknown units: number of calls to meter::set()
246 _meter_falloff = 1.5f; // XXX unknown units: refresh_rate
252 average_slave_delta = 1800;
253 have_first_delta_accumulator = false;
254 delta_accumulator_cnt = 0;
255 slave_state = Stopped;
257 /* default SMPTE type is 30 FPS, non-drop */
259 set_smpte_type (30.0, false);
261 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
263 /* These are all static "per-class" signals */
265 Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
266 Source::SourceCreated.connect (mem_fun (*this, &Session::add_source));
267 Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
268 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
269 DiskStream::DiskStreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
270 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
272 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
274 /* stop IO objects from doing stuff until we're ready for them */
276 IO::disable_panners ();
277 IO::disable_ports ();
278 IO::disable_connecting ();
282 Session::second_stage_init (bool new_session)
284 SndFileSource::set_peak_dir (peak_dir());
287 if (load_state (_current_snapshot_name)) {
290 remove_empty_sounds ();
293 if (start_butler_thread()) {
297 if (start_midi_thread ()) {
301 if (init_feedback ()) {
306 if (set_state (*state_tree->root())) {
311 /* we can't save till after ::when_engine_running() is called,
312 because otherwise we save state with no connections made.
313 therefore, we reset _state_of_the_state because ::set_state()
314 will have cleared it.
316 we also have to include Loading so that any events that get
317 generated between here and the end of ::when_engine_running()
318 will be processed directly rather than queued.
321 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
323 // set_auto_input (true);
324 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
325 _locations.added.connect (mem_fun (this, &Session::locations_added));
326 setup_click_sounds (0);
327 setup_midi_control ();
329 /* Pay attention ... */
331 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
332 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
334 if (_engine.running()) {
335 when_engine_running();
337 first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
340 send_full_time_code ();
341 _engine.transport_locate (0);
342 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
343 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
344 send_all_midi_feedback();
347 _end_location_is_free = true;
349 _end_location_is_free = false;
356 Session::raid_path () const
360 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
365 return path.substr (0, path.length() - 1); // drop final colon
369 Session::set_raid_path (string path)
371 /* public-access to setup_raid_path() */
373 setup_raid_path (path);
377 Session::setup_raid_path (string path)
379 string::size_type colon;
383 string::size_type len = path.length();
388 if (path.length() == 0) {
392 session_dirs.clear ();
394 for (string::size_type n = 0; n < len; ++n) {
395 if (path[n] == ':') {
402 /* no multiple search path, just one directory (common case) */
406 session_dirs.push_back (sp);
408 FileSource::set_search_path (path + sound_dir_name);
415 while ((colon = remaining.find_first_of (':')) != string::npos) {
418 sp.path = remaining.substr (0, colon);
421 if (fspath[fspath.length()-1] != '/') {
424 fspath += sound_dir_name;
427 session_dirs.push_back (sp);
429 remaining = remaining.substr (colon+1);
432 if (remaining.length()) {
438 if (fspath[fspath.length()-1] != '/') {
441 fspath += sound_dir_name;
443 session_dirs.push_back (sp);
446 /* set the FileSource search path */
448 FileSource::set_search_path (fspath);
450 /* reset the round-robin soundfile path thingie */
452 last_rr_session_dir = session_dirs.begin();
456 Session::create (bool& new_session, string* mix_template, jack_nframes_t initial_length)
460 if (mkdir (_path.c_str(), 0755) < 0) {
461 if (errno == EEXIST) {
464 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
473 if (mkdir (dir.c_str(), 0755) < 0) {
474 if (errno != EEXIST) {
475 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
482 if (mkdir (dir.c_str(), 0755) < 0) {
483 if (errno != EEXIST) {
484 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
491 if (mkdir (dir.c_str(), 0755) < 0) {
492 if (errno != EEXIST) {
493 error << string_compose(_("Session: cannot create session tape dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
498 dir = dead_sound_dir ();
500 if (mkdir (dir.c_str(), 0755) < 0) {
501 if (errno != EEXIST) {
502 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
507 dir = automation_dir ();
509 if (mkdir (dir.c_str(), 0755) < 0) {
510 if (errno != EEXIST) {
511 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
517 /* check new_session so we don't overwrite an existing one */
521 std::string in_path = *mix_template;
523 ifstream in(in_path.c_str());
526 string out_path = _path;
528 out_path += _statefile_suffix;
530 ofstream out(out_path.c_str());
535 // okay, session is set up. Treat like normal saved
536 // session from now on.
542 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
548 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
555 warning << _("Session already exists. Not overwriting") << endmsg;
562 /* set an initial end point */
564 end_location->set_end (initial_length);
565 _locations.add (end_location);
567 _state_of_the_state = Clean;
569 if (save_state (_current_snapshot_name)) {
578 Session::load_diskstreams (const XMLNode& node)
581 XMLNodeConstIterator citer;
583 clist = node.children();
585 for (citer = clist.begin(); citer != clist.end(); ++citer) {
590 dstream = new DiskStream (*this, **citer);
591 /* added automatically by DiskStreamCreated handler */
594 catch (failed_constructor& err) {
595 error << _("Session: could not load diskstream via XML state") << endmsg;
604 Session::remove_pending_capture_state ()
609 xml_path += _current_snapshot_name;
610 xml_path += _pending_suffix;
612 unlink (xml_path.c_str());
616 Session::save_state (string snapshot_name, bool pending)
622 if (_state_of_the_state & CannotSave) {
626 tree.set_root (&get_state());
628 if (snapshot_name.empty()) {
629 snapshot_name = _current_snapshot_name;
635 xml_path += snapshot_name;
636 xml_path += _statefile_suffix;
640 // Make backup of state file
642 if ((access (xml_path.c_str(), F_OK) == 0) &&
643 (rename(xml_path.c_str(), bak_path.c_str()))) {
644 error << _("could not backup old state file, current state not saved.") << endmsg;
651 xml_path += snapshot_name;
652 xml_path += _pending_suffix;
656 if (!tree.write (xml_path)) {
657 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
659 /* don't leave a corrupt file lying around if it is
663 if (unlink (xml_path.c_str())) {
664 error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
667 if (rename (bak_path.c_str(), xml_path.c_str())) {
668 error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
678 bool was_dirty = dirty();
680 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
683 DirtyChanged (); /* EMIT SIGNAL */
686 StateSaved (snapshot_name); /* EMIT SIGNAL */
693 Session::restore_state (string snapshot_name)
695 if (load_state (snapshot_name) == 0) {
696 set_state (*state_tree->root());
703 Session::load_state (string snapshot_name)
712 state_was_pending = false;
714 /* check for leftover pending state from a crashed capture attempt */
717 xmlpath += snapshot_name;
718 xmlpath += _pending_suffix;
720 if (!access (xmlpath.c_str(), F_OK)) {
722 /* there is pending state from a crashed capture attempt */
724 if (AskAboutPendingState()) {
725 state_was_pending = true;
729 if (!state_was_pending) {
732 xmlpath += snapshot_name;
733 xmlpath += _statefile_suffix;
736 if (access (xmlpath.c_str(), F_OK)) {
737 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
741 state_tree = new XMLTree;
745 if (state_tree->read (xmlpath)) {
748 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
757 Session::load_options (const XMLNode& node)
761 bool have_fade_msecs = false;
762 bool have_fade_steepness = false;
763 float fade_msecs = 0;
764 float fade_steepness = 0;
765 SlaveSource slave_src = None;
767 LocaleGuard lg (X_("POSIX"));
769 if ((child = find_named_node (node, "input-auto-connect")) != 0) {
770 if ((prop = child->property ("val")) != 0) {
771 sscanf (prop->value().c_str(), "%x", &x);
772 input_auto_connect = AutoConnectOption (x);
776 if ((child = find_named_node (node, "output-auto-connect")) != 0) {
777 if ((prop = child->property ("val")) != 0) {
778 sscanf (prop->value().c_str(), "%x", &x);
779 output_auto_connect = AutoConnectOption (x);
783 if ((child = find_named_node (node, "slave")) != 0) {
784 if ((prop = child->property ("type")) != 0) {
785 if (prop->value() == "none") {
787 } else if (prop->value() == "mtc") {
789 } else if (prop->value() == "jack") {
792 set_slave_source (slave_src, 0);
796 /* we cannot set edit mode if we are loading a session,
797 because it might destroy the playlist's positioning
800 if ((child = find_named_node (node, "edit-mode")) != 0) {
801 if ((prop = child->property ("val")) != 0) {
802 if (prop->value() == "slide") {
803 pending_edit_mode = Slide;
804 } else if (prop->value() == "splice") {
805 pending_edit_mode = Splice;
810 if ((child = find_named_node (node, "send-midi-timecode")) != 0) {
811 if ((prop = child->property ("val")) != 0) {
812 bool x = (prop->value() == "yes");
813 send_mtc = !x; /* force change in value */
817 if ((child = find_named_node (node, "send-midi-machine-control")) != 0) {
818 if ((prop = child->property ("val")) != 0) {
819 bool x = (prop->value() == "yes");
820 send_mmc = !x; /* force change in value */
821 set_send_mmc (prop->value() == "yes");
824 if ((child = find_named_node (node, "max-level")) != 0) {
825 if ((prop = child->property ("val")) != 0) {
826 max_level = atoi (prop->value().c_str());
829 if ((child = find_named_node (node, "min-level")) != 0) {
830 if ((prop = child->property ("val")) != 0) {
831 min_level = atoi (prop->value().c_str());
834 if ((child = find_named_node (node, "meter-hold")) != 0) {
835 if ((prop = child->property ("val")) != 0) {
836 _meter_hold = atof (prop->value().c_str());
839 if ((child = find_named_node (node, "meter-falloff")) != 0) {
840 if ((prop = child->property ("val")) != 0) {
841 _meter_falloff = atof (prop->value().c_str());
844 if ((child = find_named_node (node, "long-over-length")) != 0) {
845 if ((prop = child->property ("val")) != 0) {
846 over_length_long = atoi (prop->value().c_str());
849 if ((child = find_named_node (node, "short-over-length")) != 0) {
850 if ((prop = child->property ("val")) != 0) {
851 over_length_short = atoi (prop->value().c_str());
854 if ((child = find_named_node (node, "shuttle-speed-factor")) != 0) {
855 if ((prop = child->property ("val")) != 0) {
856 shuttle_speed_factor = atof (prop->value().c_str());
859 if ((child = find_named_node (node, "shuttle-speed-threshold")) != 0) {
860 if ((prop = child->property ("val")) != 0) {
861 shuttle_speed_threshold = atof (prop->value().c_str());
864 if ((child = find_named_node (node, "rf-speed")) != 0) {
865 if ((prop = child->property ("val")) != 0) {
866 rf_speed = atof (prop->value().c_str());
869 if ((child = find_named_node (node, "smpte-frames-per-second")) != 0) {
870 if ((prop = child->property ("val")) != 0) {
871 set_smpte_type( atof (prop->value().c_str()), smpte_drop_frames );
874 if ((child = find_named_node (node, "smpte-drop-frames")) != 0) {
875 if ((prop = child->property ("val")) != 0) {
876 set_smpte_type( smpte_frames_per_second, (prop->value() == "yes") );
879 if ((child = find_named_node (node, "smpte-offset")) != 0) {
880 if ((prop = child->property ("val")) != 0) {
881 set_smpte_offset( atoi (prop->value().c_str()) );
884 if ((child = find_named_node (node, "smpte-offset-negative")) != 0) {
885 if ((prop = child->property ("val")) != 0) {
886 set_smpte_offset_negative( (prop->value() == "yes") );
889 if ((child = find_named_node (node, "click-sound")) != 0) {
890 if ((prop = child->property ("val")) != 0) {
891 click_sound = prop->value();
894 if ((child = find_named_node (node, "click-emphasis-sound")) != 0) {
895 if ((prop = child->property ("val")) != 0) {
896 click_emphasis_sound = prop->value();
900 if ((child = find_named_node (node, "solo-model")) != 0) {
901 if ((prop = child->property ("val")) != 0) {
902 if (prop->value() == "SoloBus")
903 _solo_model = SoloBus;
905 _solo_model = InverseMute;
909 /* BOOLEAN OPTIONS */
911 if ((child = find_named_node (node, "auto-play")) != 0) {
912 if ((prop = child->property ("val")) != 0) {
913 set_auto_play (prop->value() == "yes");
916 if ((child = find_named_node (node, "auto-input")) != 0) {
917 if ((prop = child->property ("val")) != 0) {
918 set_auto_input (prop->value() == "yes");
921 if ((child = find_named_node (node, "seamless-loop")) != 0) {
922 if ((prop = child->property ("val")) != 0) {
923 set_seamless_loop (prop->value() == "yes");
926 if ((child = find_named_node (node, "punch-in")) != 0) {
927 if ((prop = child->property ("val")) != 0) {
928 set_punch_in (prop->value() == "yes");
931 if ((child = find_named_node (node, "punch-out")) != 0) {
932 if ((prop = child->property ("val")) != 0) {
933 set_punch_out (prop->value() == "yes");
936 if ((child = find_named_node (node, "auto-return")) != 0) {
937 if ((prop = child->property ("val")) != 0) {
938 set_auto_return (prop->value() == "yes");
941 if ((child = find_named_node (node, "send-mtc")) != 0) {
942 if ((prop = child->property ("val")) != 0) {
943 set_send_mtc (prop->value() == "yes");
946 if ((child = find_named_node (node, "mmc-control")) != 0) {
947 if ((prop = child->property ("val")) != 0) {
948 set_mmc_control (prop->value() == "yes");
951 if ((child = find_named_node (node, "midi-control")) != 0) {
952 if ((prop = child->property ("val")) != 0) {
953 set_midi_control (prop->value() == "yes");
956 if ((child = find_named_node (node, "midi-feedback")) != 0) {
957 if ((prop = child->property ("val")) != 0) {
958 set_midi_feedback (prop->value() == "yes");
961 // Legacy support for <recording-plugins>
962 if ((child = find_named_node (node, "recording-plugins")) != 0) {
963 if ((prop = child->property ("val")) != 0) {
964 set_do_not_record_plugins (prop->value() == "no");
967 if ((child = find_named_node (node, "do-not-record-plugins")) != 0) {
968 if ((prop = child->property ("val")) != 0) {
969 set_do_not_record_plugins (prop->value() == "yes");
972 if ((child = find_named_node (node, "crossfades-active")) != 0) {
973 if ((prop = child->property ("val")) != 0) {
974 set_crossfades_active (prop->value() == "yes");
977 if ((child = find_named_node (node, "audible-click")) != 0) {
978 if ((prop = child->property ("val")) != 0) {
979 set_clicking (prop->value() == "yes");
983 if ((child = find_named_node (node, "layer-model")) != 0) {
984 if ((prop = child->property ("val")) != 0) {
985 if (prop->value() == X_("LaterHigher")) {
986 set_layer_model (LaterHigher);
987 } else if (prop->value() == X_("AddHigher")) {
988 set_layer_model (AddHigher);
990 set_layer_model (MoveAddHigher);
995 if ((child = find_named_node (node, "xfade-model")) != 0) {
996 if ((prop = child->property ("val")) != 0) {
997 if (prop->value() == X_("Short")) {
998 set_xfade_model (ShortCrossfade);
1000 set_xfade_model (FullCrossfade);
1005 if ((child = find_named_node (node, "short-xfade-length")) != 0) {
1006 if ((prop = child->property ("val")) != 0) {
1007 /* value is stored as a fractional seconds */
1008 float secs = atof (prop->value().c_str());
1009 Crossfade::set_short_xfade_length ((jack_nframes_t) floor (secs * frame_rate()));
1013 if ((child = find_named_node (node, "full-xfades-unmuted")) != 0) {
1014 if ((prop = child->property ("val")) != 0) {
1015 crossfades_active = (prop->value() == "yes");
1021 if ((child = find_named_node (node, "default-fade-steepness")) != 0) {
1022 if ((prop = child->property ("val")) != 0) {
1023 fade_steepness = atof (prop->value().c_str());
1024 have_fade_steepness = true;
1027 if ((child = find_named_node (node, "default-fade-msec")) != 0) {
1028 if ((prop = child->property ("val")) != 0) {
1029 fade_msecs = atof (prop->value().c_str());
1030 have_fade_msecs = true;
1034 if (have_fade_steepness || have_fade_msecs) {
1035 // set_default_fade (fade_steepness, fade_msecs);
1042 Session::get_options () const
1047 LocaleGuard lg (X_("POSIX"));
1049 opthead = new XMLNode ("Options");
1051 SlaveSource src = slave_source ();
1055 src_string = "none";
1061 src_string = "jack";
1064 child = opthead->add_child ("slave");
1065 child->add_property ("type", src_string);
1067 child = opthead->add_child ("send-midi-timecode");
1068 child->add_property ("val", send_midi_timecode?"yes":"no");
1070 child = opthead->add_child ("send-midi-machine-control");
1071 child->add_property ("val", send_midi_machine_control?"yes":"no");
1073 snprintf (buf, sizeof(buf)-1, "%x", (int) input_auto_connect);
1074 child = opthead->add_child ("input-auto-connect");
1075 child->add_property ("val", buf);
1077 snprintf (buf, sizeof(buf)-1, "%x", (int) output_auto_connect);
1078 child = opthead->add_child ("output-auto-connect");
1079 child->add_property ("val", buf);
1081 snprintf (buf, sizeof(buf)-1, "%d", max_level);
1082 child = opthead->add_child ("max-level");
1083 child->add_property ("val", buf);
1085 snprintf (buf, sizeof(buf)-1, "%d", min_level);
1086 child = opthead->add_child ("min-level");
1087 child->add_property ("val", buf);
1089 snprintf (buf, sizeof(buf)-1, "%f", _meter_hold);
1090 child = opthead->add_child ("meter-hold");
1091 child->add_property ("val", buf);
1093 snprintf (buf, sizeof(buf)-1, "%f", _meter_falloff);
1094 child = opthead->add_child ("meter-falloff");
1095 child->add_property ("val", buf);
1097 snprintf (buf, sizeof(buf)-1, "%u", over_length_long);
1098 child = opthead->add_child ("long-over-length");
1099 child->add_property ("val", buf);
1101 snprintf (buf, sizeof(buf)-1, "%u", over_length_short);
1102 child = opthead->add_child ("short-over-length");
1103 child->add_property ("val", buf);
1105 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_factor);
1106 child = opthead->add_child ("shuttle-speed-factor");
1107 child->add_property ("val", buf);
1109 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_threshold);
1110 child = opthead->add_child ("shuttle-speed-threshold");
1111 child->add_property ("val", buf);
1113 snprintf (buf, sizeof(buf)-1, "%f", rf_speed);
1114 child = opthead->add_child ("rf-speed");
1115 child->add_property ("val", buf);
1117 snprintf (buf, sizeof(buf)-1, "%.2f", smpte_frames_per_second);
1118 child = opthead->add_child ("smpte-frames-per-second");
1119 child->add_property ("val", buf);
1121 child = opthead->add_child ("smpte-drop-frames");
1122 child->add_property ("val", smpte_drop_frames ? "yes" : "no");
1124 snprintf (buf, sizeof(buf)-1, "%u", smpte_offset ());
1125 child = opthead->add_child ("smpte-offset");
1126 child->add_property ("val", buf);
1128 child = opthead->add_child ("smpte-offset-negative");
1129 child->add_property ("val", smpte_offset_negative () ? "yes" : "no");
1131 child = opthead->add_child ("edit-mode");
1132 switch (_edit_mode) {
1134 child->add_property ("val", "splice");
1138 child->add_property ("val", "slide");
1142 child = opthead->add_child ("auto-play");
1143 child->add_property ("val", get_auto_play () ? "yes" : "no");
1144 child = opthead->add_child ("auto-input");
1145 child->add_property ("val", get_auto_input () ? "yes" : "no");
1146 child = opthead->add_child ("seamless-loop");
1147 child->add_property ("val", get_seamless_loop () ? "yes" : "no");
1148 child = opthead->add_child ("punch-in");
1149 child->add_property ("val", get_punch_in () ? "yes" : "no");
1150 child = opthead->add_child ("punch-out");
1151 child->add_property ("val", get_punch_out () ? "yes" : "no");
1152 child = opthead->add_child ("all-safe");
1153 child->add_property ("val", get_all_safe () ? "yes" : "no");
1154 child = opthead->add_child ("auto-return");
1155 child->add_property ("val", get_auto_return () ? "yes" : "no");
1156 child = opthead->add_child ("mmc-control");
1157 child->add_property ("val", get_mmc_control () ? "yes" : "no");
1158 child = opthead->add_child ("midi-control");
1159 child->add_property ("val", get_midi_control () ? "yes" : "no");
1160 child = opthead->add_child ("midi-feedback");
1161 child->add_property ("val", get_midi_feedback () ? "yes" : "no");
1162 child = opthead->add_child ("do-not-record-plugins");
1163 child->add_property ("val", get_do_not_record_plugins () ? "yes" : "no");
1164 child = opthead->add_child ("auto-crossfade");
1165 child->add_property ("val", get_crossfades_active () ? "yes" : "no");
1166 child = opthead->add_child ("audible-click");
1167 child->add_property ("val", get_clicking () ? "yes" : "no");
1169 if (click_sound.length()) {
1170 child = opthead->add_child ("click-sound");
1171 child->add_property ("val", click_sound);
1174 if (click_emphasis_sound.length()) {
1175 child = opthead->add_child ("click-emphasis-sound");
1176 child->add_property ("val", click_emphasis_sound);
1179 child = opthead->add_child ("solo-model");
1180 child->add_property ("val", _solo_model == SoloBus ? "SoloBus" : "InverseMute");
1182 child = opthead->add_child ("layer-model");
1183 switch (layer_model) {
1185 child->add_property ("val", X_("LaterHigher"));
1188 child->add_property ("val", X_("MoveAddHigher"));
1191 child->add_property ("val", X_("AddHigher"));
1195 child = opthead->add_child ("xfade-model");
1196 switch (xfade_model) {
1198 child->add_property ("val", X_("Full"));
1200 case ShortCrossfade:
1201 child->add_property ("val", X_("Short"));
1204 child = opthead->add_child ("short-xfade-length");
1205 /* store as fractions of a second */
1206 snprintf (buf, sizeof(buf)-1, "%f",
1207 (float) Crossfade::short_xfade_length() / frame_rate());
1208 child->add_property ("val", buf);
1210 child = opthead->add_child ("full-xfades-unmuted");
1211 child->add_property ("val", crossfades_active ? "yes" : "no");
1217 Session::get_state()
1223 Session::get_template()
1225 /* if we don't disable rec-enable, diskstreams
1226 will believe they need to store their capture
1227 sources in their state node.
1232 return state(false);
1236 Session::state(bool full_state)
1238 XMLNode* node = new XMLNode("Session");
1241 // store libardour version, just in case
1243 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
1244 libardour_major_version, libardour_minor_version, libardour_micro_version);
1245 node->add_property("version", string(buf));
1247 /* store configuration settings */
1251 /* store the name */
1252 node->add_property ("name", _name);
1254 if (session_dirs.size() > 1) {
1258 vector<space_and_path>::iterator i = session_dirs.begin();
1259 vector<space_and_path>::iterator next;
1261 ++i; /* skip the first one */
1265 while (i != session_dirs.end()) {
1269 if (next != session_dirs.end()) {
1279 child = node->add_child ("Path");
1280 child->add_content (p);
1284 node->add_child_nocopy (get_options());
1286 child = node->add_child ("Sources");
1289 LockMonitor sl (source_lock, __LINE__, __FILE__);
1291 for (SourceList::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1293 /* Don't save information about FileSources that are empty */
1297 if ((fs = dynamic_cast<FileSource*> ((*siter).second)) != 0) {
1298 if (fs->length() == 0) {
1303 child->add_child_nocopy ((*siter).second->get_state());
1307 child = node->add_child ("Regions");
1310 LockMonitor rl (region_lock, __LINE__, __FILE__);
1312 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1314 /* only store regions not attached to playlists */
1316 if ((*i).second->playlist() == 0) {
1317 child->add_child_nocopy (i->second->state (true));
1322 child = node->add_child ("DiskStreams");
1325 RWLockMonitor dl (diskstream_lock, false, __LINE__, __FILE__);
1326 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1327 if (!(*i)->hidden()) {
1328 child->add_child_nocopy ((*i)->get_state());
1333 node->add_child_nocopy (_locations.get_state());
1335 child = node->add_child ("Connections");
1337 LockMonitor lm (connection_lock, __LINE__, __FILE__);
1338 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1339 if (!(*i)->system_dependent()) {
1340 child->add_child_nocopy ((*i)->get_state());
1345 child = node->add_child ("Routes");
1347 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1349 RoutePublicOrderSorter cmp;
1350 RouteList public_order(routes);
1351 public_order.sort (cmp);
1353 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1354 if (!(*i)->hidden()) {
1356 child->add_child_nocopy ((*i)->get_state());
1358 child->add_child_nocopy ((*i)->get_template());
1365 child = node->add_child ("EditGroups");
1366 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1367 child->add_child_nocopy ((*i)->get_state());
1370 child = node->add_child ("MixGroups");
1371 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1372 child->add_child_nocopy ((*i)->get_state());
1375 child = node->add_child ("Playlists");
1376 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1377 if (!(*i)->hidden()) {
1378 if (!(*i)->empty()) {
1380 child->add_child_nocopy ((*i)->get_state());
1382 child->add_child_nocopy ((*i)->get_template());
1388 child = node->add_child ("UnusedPlaylists");
1389 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1390 if (!(*i)->hidden()) {
1391 if (!(*i)->empty()) {
1393 child->add_child_nocopy ((*i)->get_state());
1395 child->add_child_nocopy ((*i)->get_template());
1403 child = node->add_child ("Click");
1404 child->add_child_nocopy (_click_io->state (full_state));
1408 child = node->add_child ("NamedSelections");
1409 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1411 child->add_child_nocopy ((*i)->get_state());
1416 node->add_child_nocopy (_tempo_map->get_state());
1419 node->add_child_copy (*_extra_xml);
1426 Session::set_state (const XMLNode& node)
1430 const XMLProperty* prop;
1433 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1435 if (node.name() != "Session"){
1436 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1440 StateManager::prohibit_save ();
1442 if ((prop = node.property ("name")) != 0) {
1443 _name = prop->value ();
1446 IO::disable_ports ();
1447 IO::disable_connecting ();
1449 /* Object loading order:
1466 if (use_config_midi_ports ()) {
1469 if ((child = find_named_node (node, "Path")) != 0) {
1470 /* XXX this XML content stuff horrible API design */
1471 string raid_path = _path + ':' + child->children().front()->content();
1472 setup_raid_path (raid_path);
1474 /* the path is already set */
1477 if ((child = find_named_node (node, "extra")) != 0) {
1478 _extra_xml = new XMLNode (*child);
1481 if ((child = find_named_node (node, "Options")) == 0) {
1482 error << _("Session: XML state has no options section") << endmsg;
1483 } else if (load_options (*child)) {
1486 if ((child = find_named_node (node, "Sources")) == 0) {
1487 error << _("Session: XML state has no sources section") << endmsg;
1489 } else if (load_sources (*child)) {
1493 if ((child = find_named_node (node, "Regions")) == 0) {
1494 error << _("Session: XML state has no Regions section") << endmsg;
1496 } else if (load_regions (*child)) {
1500 if ((child = find_named_node (node, "Playlists")) == 0) {
1501 error << _("Session: XML state has no playlists section") << endmsg;
1503 } else if (load_playlists (*child)) {
1507 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1509 } else if (load_unused_playlists (*child)) {
1513 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1514 if (load_named_selections (*child)) {
1519 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1520 error << _("Session: XML state has no diskstreams section") << endmsg;
1522 } else if (load_diskstreams (*child)) {
1526 if ((child = find_named_node (node, "Connections")) == 0) {
1527 error << _("Session: XML state has no connections section") << endmsg;
1529 } else if (load_connections (*child)) {
1533 if ((child = find_named_node (node, "Locations")) == 0) {
1534 error << _("Session: XML state has no locations section") << endmsg;
1536 } else if (_locations.set_state (*child)) {
1542 if ((location = _locations.auto_loop_location()) != 0) {
1543 set_auto_loop_location (location);
1546 if ((location = _locations.auto_punch_location()) != 0) {
1547 set_auto_punch_location (location);
1550 if ((location = _locations.end_location()) == 0) {
1551 _locations.add (end_location);
1553 end_location = location;
1556 _locations.save_state (_("initial state"));
1558 if ((child = find_named_node (node, "EditGroups")) == 0) {
1559 error << _("Session: XML state has no edit groups section") << endmsg;
1561 } else if (load_edit_groups (*child)) {
1565 if ((child = find_named_node (node, "MixGroups")) == 0) {
1566 error << _("Session: XML state has no mix groups section") << endmsg;
1568 } else if (load_mix_groups (*child)) {
1572 if ((child = find_named_node (node, "TempoMap")) == 0) {
1573 error << _("Session: XML state has no Tempo Map section") << endmsg;
1575 } else if (_tempo_map->set_state (*child)) {
1579 if ((child = find_named_node (node, "Routes")) == 0) {
1580 error << _("Session: XML state has no routes section") << endmsg;
1582 } else if (load_routes (*child)) {
1586 if ((child = find_named_node (node, "Click")) == 0) {
1587 warning << _("Session: XML state has no click section") << endmsg;
1588 } else if (_click_io) {
1589 _click_io->set_state (*child);
1592 /* OK, now we can set edit mode */
1594 set_edit_mode (pending_edit_mode);
1596 /* here beginneth the second phase ... */
1598 StateReady (); /* EMIT SIGNAL */
1600 _state_of_the_state = Clean;
1602 StateManager::allow_save (_("initial state"), true);
1604 if (state_was_pending) {
1605 save_state (_current_snapshot_name);
1606 remove_pending_capture_state ();
1607 state_was_pending = false;
1613 /* we failed, re-enable state saving but don't actually save internal state */
1614 StateManager::allow_save (X_("ignored"), false);
1619 Session::load_routes (const XMLNode& node)
1622 XMLNodeConstIterator niter;
1625 nlist = node.children();
1629 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1631 if ((route = XMLRouteFactory (**niter)) == 0) {
1632 error << _("Session: cannot create Route from XML description.") << endmsg;
1643 Session::XMLRouteFactory (const XMLNode& node)
1645 if (node.name() != "Route") {
1649 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1650 return new AudioTrack (*this, node);
1652 return new Route (*this, node);
1657 Session::load_regions (const XMLNode& node)
1660 XMLNodeConstIterator niter;
1661 AudioRegion* region;
1663 nlist = node.children();
1667 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1669 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1670 error << _("Session: cannot create Region from XML description.") << endmsg;
1678 Session::XMLRegionFactory (const XMLNode& node, bool full)
1680 const XMLProperty* prop;
1683 AudioRegion::SourceList sources;
1684 uint32_t nchans = 1;
1687 if (node.name() != X_("Region")) {
1691 if ((prop = node.property (X_("channels"))) != 0) {
1692 nchans = atoi (prop->value().c_str());
1696 if ((prop = node.property (X_("source-0"))) == 0) {
1697 if ((prop = node.property ("source")) == 0) {
1698 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1703 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1705 if ((source = get_source (s_id)) == 0) {
1706 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1710 sources.push_back(source);
1712 /* pickup other channels */
1714 for (uint32_t n=1; n < nchans; ++n) {
1715 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1716 if ((prop = node.property (buf)) != 0) {
1717 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1719 if ((source = get_source (s_id)) == 0) {
1720 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1723 sources.push_back(source);
1729 return new AudioRegion (sources, node);
1732 catch (failed_constructor& err) {
1738 Session::get_sources_as_xml ()
1741 XMLNode* node = new XMLNode (X_("Sources"));
1742 LockMonitor lm (source_lock, __LINE__, __FILE__);
1744 for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
1745 node->add_child_nocopy ((*i).second->get_state());
1752 Session::path_from_region_name (string name, string identifier)
1754 char buf[PATH_MAX+1];
1756 string dir = discover_best_sound_dir ();
1758 for (n = 0; n < 999999; ++n) {
1759 if (identifier.length()) {
1760 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1761 identifier.c_str(), n);
1763 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1765 if (access (buf, F_OK) != 0) {
1775 Session::load_sources (const XMLNode& node)
1778 XMLNodeConstIterator niter;
1781 nlist = node.children();
1785 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1787 if ((source = XMLSourceFactory (**niter)) == 0) {
1788 error << _("Session: cannot create Source from XML description.") << endmsg;
1796 Session::XMLSourceFactory (const XMLNode& node)
1800 if (node.name() != "Source") {
1805 src = new FileSource (node, frame_rate());
1808 catch (failed_constructor& err) {
1811 src = new SndFileSource (node);
1814 catch (failed_constructor& err) {
1815 error << _("Found a sound file that cannot be used by Ardour. See the progammers.") << endmsg;
1824 Session::save_template (string template_name)
1827 string xml_path, bak_path, template_path;
1829 if (_state_of_the_state & CannotSave) {
1834 string dir = template_dir();
1836 if ((dp = opendir (dir.c_str()))) {
1839 if (mkdir (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)<0) {
1840 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1845 tree.set_root (&get_template());
1848 xml_path += template_name;
1849 xml_path += _template_suffix;
1851 ifstream in(xml_path.c_str());
1854 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1860 if (!tree.write (xml_path)) {
1861 error << _("mix template not saved") << endmsg;
1869 Session::rename_template (string old_name, string new_name)
1871 string old_path = template_dir() + old_name + _template_suffix;
1872 string new_path = template_dir() + new_name + _template_suffix;
1874 return rename (old_path.c_str(), new_path.c_str());
1878 Session::delete_template (string name)
1880 string template_path = template_dir();
1881 template_path += name;
1882 template_path += _template_suffix;
1884 return remove (template_path.c_str());
1888 Session::refresh_disk_space ()
1891 struct statfs statfsbuf;
1892 vector<space_and_path>::iterator i;
1893 LockMonitor lm (space_lock, __LINE__, __FILE__);
1896 /* get freespace on every FS that is part of the session path */
1898 _total_free_4k_blocks = 0;
1900 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1901 statfs ((*i).path.c_str(), &statfsbuf);
1903 scale = statfsbuf.f_bsize/4096.0;
1905 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1906 _total_free_4k_blocks += (*i).blocks;
1912 Session::ensure_sound_dir (string path, string& result)
1917 /* Ensure that the parent directory exists */
1919 if (mkdir (path.c_str(), 0775)) {
1920 if (errno != EEXIST) {
1921 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1926 /* Ensure that the sounds directory exists */
1930 result += sound_dir_name;
1932 if (mkdir (result.c_str(), 0775)) {
1933 if (errno != EEXIST) {
1934 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1941 dead += dead_sound_dir_name;
1943 if (mkdir (dead.c_str(), 0775)) {
1944 if (errno != EEXIST) {
1945 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1952 peak += peak_dir_name;
1954 if (mkdir (peak.c_str(), 0775)) {
1955 if (errno != EEXIST) {
1956 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1961 /* callers expect this to be terminated ... */
1968 Session::discover_best_sound_dir (bool destructive)
1970 vector<space_and_path>::iterator i;
1973 /* destructive files all go into the same place */
1979 /* handle common case without system calls */
1981 if (session_dirs.size() == 1) {
1985 /* OK, here's the algorithm we're following here:
1987 We want to select which directory to use for
1988 the next file source to be created. Ideally,
1989 we'd like to use a round-robin process so as to
1990 get maximum performance benefits from splitting
1991 the files across multiple disks.
1993 However, in situations without much diskspace, an
1994 RR approach may end up filling up a filesystem
1995 with new files while others still have space.
1996 Its therefore important to pay some attention to
1997 the freespace in the filesystem holding each
1998 directory as well. However, if we did that by
1999 itself, we'd keep creating new files in the file
2000 system with the most space until it was as full
2001 as all others, thus negating any performance
2002 benefits of this RAID-1 like approach.
2004 So, we use a user-configurable space threshold. If
2005 there are at least 2 filesystems with more than this
2006 much space available, we use RR selection between them.
2007 If not, then we pick the filesystem with the most space.
2009 This gets a good balance between the two
2013 refresh_disk_space ();
2015 int free_enough = 0;
2017 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2018 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2023 if (free_enough >= 2) {
2025 bool found_it = false;
2027 /* use RR selection process, ensuring that the one
2031 i = last_rr_session_dir;
2034 if (++i == session_dirs.end()) {
2035 i = session_dirs.begin();
2038 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2039 if (ensure_sound_dir ((*i).path, result) == 0) {
2040 last_rr_session_dir = i;
2046 } while (i != last_rr_session_dir);
2049 result = sound_dir();
2054 /* pick FS with the most freespace (and that
2055 seems to actually work ...)
2058 vector<space_and_path> sorted;
2059 space_and_path_ascending_cmp cmp;
2061 sorted = session_dirs;
2062 sort (sorted.begin(), sorted.end(), cmp);
2064 for (i = sorted.begin(); i != sorted.end(); ++i) {
2065 if (ensure_sound_dir ((*i).path, result) == 0) {
2066 last_rr_session_dir = i;
2071 /* if the above fails, fall back to the most simplistic solution */
2073 if (i == sorted.end()) {
2082 Session::load_playlists (const XMLNode& node)
2085 XMLNodeConstIterator niter;
2088 nlist = node.children();
2092 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2094 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2095 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2103 Session::load_unused_playlists (const XMLNode& node)
2106 XMLNodeConstIterator niter;
2109 nlist = node.children();
2113 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2115 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2116 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2120 // now manually untrack it
2122 track_playlist (playlist, false);
2130 Session::XMLPlaylistFactory (const XMLNode& node)
2133 return new AudioPlaylist (*this, node);
2136 catch (failed_constructor& err) {
2142 Session::load_named_selections (const XMLNode& node)
2145 XMLNodeConstIterator niter;
2148 nlist = node.children();
2152 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2154 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2155 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2163 Session::XMLNamedSelectionFactory (const XMLNode& node)
2166 return new NamedSelection (*this, node);
2169 catch (failed_constructor& err) {
2175 Session::dead_sound_dir () const
2178 res += dead_sound_dir_name;
2184 Session::sound_dir () const
2187 res += sound_dir_name;
2193 Session::tape_dir () const
2195 string res = Config->get_tape_dir();
2202 res += tape_dir_name;
2208 Session::peak_dir () const
2211 res += peak_dir_name;
2217 Session::automation_dir () const
2220 res += "automation/";
2225 Session::template_dir ()
2227 string path = Config->get_user_ardour_path();
2228 path += "templates/";
2234 Session::template_path ()
2238 path += Config->get_user_ardour_path();
2239 if (path[path.length()-1] != ':') {
2242 path += Config->get_system_ardour_path();
2244 vector<string> split_path;
2246 split (path, split_path, ':');
2249 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2251 path += "templates/";
2253 if (distance (i, split_path.end()) != 1) {
2262 Session::load_connections (const XMLNode& node)
2264 XMLNodeList nlist = node.children();
2265 XMLNodeConstIterator niter;
2269 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2270 if ((*niter)->name() == "InputConnection") {
2271 add_connection (new ARDOUR::InputConnection (**niter));
2272 } else if ((*niter)->name() == "OutputConnection") {
2273 add_connection (new ARDOUR::OutputConnection (**niter));
2275 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2284 Session::load_edit_groups (const XMLNode& node)
2286 return load_route_groups (node, true);
2290 Session::load_mix_groups (const XMLNode& node)
2292 return load_route_groups (node, false);
2296 Session::load_route_groups (const XMLNode& node, bool edit)
2298 XMLNodeList nlist = node.children();
2299 XMLNodeConstIterator niter;
2304 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2305 if ((*niter)->name() == "RouteGroup") {
2307 route = add_edit_group ("");
2308 route->set_state (**niter);
2310 route = add_mix_group ("");
2311 route->set_state (**niter);
2320 Session::swap_configuration(Configuration** new_config)
2322 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__); // jlc - WHY?
2323 Configuration* tmp = *new_config;
2324 *new_config = Config;
2330 Session::copy_configuration(Configuration* new_config)
2332 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
2333 new_config = new Configuration(*Config);
2337 state_file_filter (const string &str, void *arg)
2339 return (str.length() > strlen(Session::statefile_suffix()) &&
2340 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2344 bool operator()(const string* a, const string* b) {
2350 remove_end(string* state)
2352 string statename(*state);
2354 string::size_type start,end;
2355 if ((start = statename.find_last_of ('/')) != string::npos) {
2356 statename = statename.substr (start+1);
2359 if ((end = statename.rfind(".ardour")) < 0) {
2360 end = statename.length();
2363 return new string(statename.substr (0, end));
2367 Session::possible_states (string path)
2369 PathScanner scanner;
2370 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2372 transform(states->begin(), states->end(), states->begin(), remove_end);
2375 sort (states->begin(), states->end(), cmp);
2381 Session::possible_states () const
2383 return possible_states(_path);
2387 Session::auto_save()
2389 save_state (_current_snapshot_name);
2393 Session::add_edit_group (string name)
2395 RouteGroup* rg = new RouteGroup (name);
2396 edit_groups.push_back (rg);
2397 edit_group_added (rg); /* EMIT SIGNAL */
2403 Session::add_mix_group (string name)
2405 RouteGroup* rg = new RouteGroup (name, RouteGroup::Relative);
2406 mix_groups.push_back (rg);
2407 mix_group_added (rg); /* EMIT SIGNAL */
2413 Session::mix_group_by_name (string name)
2415 list<RouteGroup *>::iterator i;
2417 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2418 if ((*i)->name() == name) {
2426 Session::edit_group_by_name (string name)
2428 list<RouteGroup *>::iterator i;
2430 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2431 if ((*i)->name() == name) {
2439 Session::set_meter_hold (float val)
2442 MeterHoldChanged(); // emit
2446 Session::set_meter_falloff (float val)
2448 _meter_falloff = val;
2449 MeterFalloffChanged(); // emit
2454 Session::begin_reversible_command (string name, UndoAction* private_undo)
2456 current_cmd.clear ();
2457 current_cmd.set_name (name);
2460 current_cmd.add_undo (*private_undo);
2465 Session::commit_reversible_command (UndoAction* private_redo)
2470 current_cmd.add_redo_no_execute (*private_redo);
2473 gettimeofday (&now, 0);
2474 current_cmd.set_timestamp (now);
2476 history.add (current_cmd);
2479 Session::GlobalRouteBooleanState
2480 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2482 GlobalRouteBooleanState s;
2483 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2485 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2486 if (!(*i)->hidden()) {
2487 RouteBooleanState v;
2490 v.second = ((*i)->*method)();
2499 Session::GlobalRouteMeterState
2500 Session::get_global_route_metering ()
2502 GlobalRouteMeterState s;
2503 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2505 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2506 if (!(*i)->hidden()) {
2510 v.second = (*i)->meter_point();
2520 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2522 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2523 i->first->set_meter_point (i->second, arg);
2528 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2530 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2531 (i->first->*method) (i->second, arg);
2536 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2538 set_global_route_boolean (s, &Route::set_mute, src);
2542 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2544 set_global_route_boolean (s, &Route::set_solo, src);
2548 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2550 set_global_route_boolean (s, &Route::set_record_enable, src);
2554 Session::global_mute_memento (void* src)
2556 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2560 Session::global_metering_memento (void* src)
2562 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2566 Session::global_solo_memento (void* src)
2568 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2572 Session::global_record_enable_memento (void* src)
2574 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2578 template_filter (const string &str, void *arg)
2580 return (str.length() > strlen(Session::template_suffix()) &&
2581 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2585 Session::get_template_list (list<string> &template_names)
2587 vector<string *> *templates;
2588 PathScanner scanner;
2591 path = template_path ();
2593 templates = scanner (path, template_filter, 0, false, true);
2595 vector<string*>::iterator i;
2596 for (i = templates->begin(); i != templates->end(); ++i) {
2597 string fullpath = *(*i);
2600 start = fullpath.find_last_of ('/') + 1;
2601 if ((end = fullpath.find_last_of ('.')) <0) {
2602 end = fullpath.length();
2605 template_names.push_back(fullpath.substr(start, (end-start)));
2610 Session::read_favorite_dirs (FavoriteDirs & favs)
2612 string path = Config->get_user_ardour_path();
2613 path += "/favorite_dirs";
2615 ifstream fav (path.c_str());
2620 if (errno != ENOENT) {
2621 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2632 getline(fav, newfav);
2638 favs.push_back (newfav);
2645 Session::write_favorite_dirs (FavoriteDirs & favs)
2647 string path = Config->get_user_ardour_path();
2648 path += "/favorite_dirs";
2650 ofstream fav (path.c_str());
2656 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2657 fav << (*i) << endl;
2664 accept_all_non_peak_files (const string& path, void *arg)
2666 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2670 accept_all_state_files (const string& path, void *arg)
2672 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2676 Session::find_all_sources (string path, set<string>& result)
2681 if (!tree.read (path)) {
2685 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2690 XMLNodeConstIterator niter;
2692 nlist = node->children();
2696 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2700 if ((prop = (*niter)->property (X_("name"))) == 0) {
2704 if (prop->value()[0] == '/') {
2705 /* external file, ignore */
2709 string path = _path; /* /-terminated */
2710 path += sound_dir_name;
2712 path += prop->value();
2714 result.insert (path);
2721 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2723 PathScanner scanner;
2724 vector<string*>* state_files;
2726 string this_snapshot_path;
2732 if (ripped[ripped.length()-1] == '/') {
2733 ripped = ripped.substr (0, ripped.length() - 1);
2736 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2738 if (state_files == 0) {
2743 this_snapshot_path = _path;
2744 this_snapshot_path += _current_snapshot_name;
2745 this_snapshot_path += _statefile_suffix;
2747 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2749 if (exclude_this_snapshot && **i == this_snapshot_path) {
2753 if (find_all_sources (**i, result) < 0) {
2762 Session::cleanup_sources (Session::cleanup_report& rep)
2764 vector<Source*> dead_sources;
2765 vector<Playlist*> playlists_tbd;
2766 PathScanner scanner;
2768 vector<space_and_path>::iterator i;
2769 vector<space_and_path>::iterator nexti;
2770 vector<string*>* soundfiles;
2771 vector<string> unused;
2772 set<string> all_sources;
2777 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2779 /* step 1: consider deleting all unused playlists */
2781 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2784 status = AskAboutPlaylistDeletion (*x);
2793 playlists_tbd.push_back (*x);
2797 /* leave it alone */
2802 /* now delete any that were marked for deletion */
2804 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2805 PlaylistList::iterator foo;
2807 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2808 unused_playlists.erase (foo);
2813 /* step 2: clear the undo/redo history for all playlists */
2815 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2816 (*x)->drop_all_states ();
2819 /* step 3: find all un-referenced sources */
2824 for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
2826 SourceList::iterator tmp;
2831 /* only remove files that are not in use and have some size
2832 to them. otherwise we remove the current "nascent"
2836 if ((*i).second->use_cnt() == 0 && (*i).second->length() > 0) {
2837 dead_sources.push_back (i->second);
2839 /* remove this source from our own list to avoid us
2840 adding it to the list of all sources below
2849 /* Step 4: get rid of all regions in the region list that use any dead sources
2850 in case the sources themselves don't go away (they might be referenced in
2854 for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2856 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2857 AudioRegionList::iterator tmp;
2865 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2866 if (&ar->source (n) == (*i)) {
2867 /* this region is dead */
2876 /* build a list of all the possible sound directories for the session */
2878 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2883 sound_path += (*i).path;
2884 sound_path += sound_dir_name;
2886 if (nexti != session_dirs.end()) {
2893 /* now do the same thing for the files that ended up in the sounds dir(s)
2894 but are not referenced as sources in any snapshot.
2897 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2899 if (soundfiles == 0) {
2903 /* find all sources, but don't use this snapshot because the
2904 state file on disk still references sources we may have already
2908 find_all_sources_across_snapshots (all_sources, true);
2910 /* add our current source list
2913 for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
2917 if ((fs = dynamic_cast<FileSource*> ((*i).second)) != 0) {
2918 all_sources.insert (fs->path());
2919 } else if ((sfs = dynamic_cast<SndFileSource*> ((*i).second)) != 0) {
2920 all_sources.insert (sfs->path());
2924 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2929 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2939 unused.push_back (spath);
2943 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2945 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2946 struct stat statbuf;
2948 rep.paths.push_back (*x);
2949 if (stat ((*x).c_str(), &statbuf) == 0) {
2950 rep.space += statbuf.st_size;
2955 /* don't move the file across filesystems, just
2956 stick it in the `dead_sound_dir_name' directory
2957 on whichever filesystem it was already on.
2960 newpath = PBD::dirname (*x);
2961 newpath = PBD::dirname (newpath);
2964 newpath += dead_sound_dir_name;
2966 newpath += PBD::basename ((*x));
2968 if (access (newpath.c_str(), F_OK) == 0) {
2970 /* the new path already exists, try versioning */
2972 char buf[PATH_MAX+1];
2976 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2979 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2980 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2984 if (version == 999) {
2985 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2989 newpath = newpath_v;
2994 /* it doesn't exist, or we can't read it or something */
2998 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2999 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
3000 (*x), newpath, strerror (errno))
3006 /* see if there an easy to find peakfile for this file, and remove it.
3009 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
3010 peakpath += ".peak";
3012 if (access (peakpath.c_str(), W_OK) == 0) {
3013 if (::unlink (peakpath.c_str()) != 0) {
3014 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3015 peakpath, _path, strerror (errno))
3017 /* try to back out */
3018 rename (newpath.c_str(), _path.c_str());
3027 /* dump the history list */
3031 /* save state so we don't end up a session file
3032 referring to non-existent sources.
3038 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3043 Session::cleanup_trash_sources (Session::cleanup_report& rep)
3045 vector<space_and_path>::iterator i;
3046 string dead_sound_dir;
3047 struct dirent* dentry;
3048 struct stat statbuf;
3054 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3056 dead_sound_dir = (*i).path;
3057 dead_sound_dir += dead_sound_dir_name;
3059 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
3063 while ((dentry = readdir (dead)) != 0) {
3065 /* avoid '.' and '..' */
3067 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
3068 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3074 fullpath = dead_sound_dir;
3076 fullpath += dentry->d_name;
3078 if (stat (fullpath.c_str(), &statbuf)) {
3082 if (!S_ISREG (statbuf.st_mode)) {
3086 if (unlink (fullpath.c_str())) {
3087 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3088 fullpath, strerror (errno))
3092 rep.paths.push_back (dentry->d_name);
3093 rep.space += statbuf.st_size;
3104 Session::set_dirty ()
3106 bool was_dirty = dirty();
3108 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3111 DirtyChanged(); /* EMIT SIGNAL */
3117 Session::set_clean ()
3119 bool was_dirty = dirty();
3121 _state_of_the_state = Clean;
3124 DirtyChanged(); /* EMIT SIGNAL */