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>
49 #include <midi++/mmc.h>
50 #include <midi++/port.h>
51 #include <pbd/error.h>
53 #include <glibmm/thread.h>
54 #include <pbd/pathscanner.h>
55 #include <pbd/pthread_utils.h>
56 #include <pbd/strsplit.h>
58 #include <ardour/audioengine.h>
59 #include <ardour/configuration.h>
60 #include <ardour/session.h>
61 #include <ardour/audio_diskstream.h>
62 #include <ardour/utils.h>
63 #include <ardour/audioplaylist.h>
64 #include <ardour/audiofilesource.h>
65 #include <ardour/destructive_filesource.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>
83 #include <ardour/control_protocol_manager.h>
89 using namespace ARDOUR;
92 Session::first_stage_init (string fullpath, string snapshot_name)
94 if (fullpath.length() == 0) {
95 throw failed_constructor();
99 if (!realpath(fullpath.c_str(), buf) && (errno != ENOENT)) {
100 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
101 throw failed_constructor();
105 if (_path[_path.length()-1] != '/') {
109 /* these two are just provisional settings. set_state()
110 will likely override them.
113 _name = _current_snapshot_name = snapshot_name;
114 setup_raid_path (_path);
116 _current_frame_rate = _engine.frame_rate ();
117 _tempo_map = new TempoMap (_current_frame_rate);
118 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
120 g_atomic_int_set (&processing_prohibited, 0);
123 _transport_speed = 0;
124 _last_transport_speed = 0;
125 transport_sub_state = 0;
126 _transport_frame = 0;
128 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
129 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
130 _end_location_is_free = true;
131 g_atomic_int_set (&_record_status, Disabled);
136 seamless_loop = false;
137 loop_changing = false;
139 crossfades_active = false;
142 _last_roll_location = 0;
143 _last_record_location = 0;
144 pending_locate_frame = 0;
145 pending_locate_roll = false;
146 pending_locate_flush = false;
147 dstream_buffer_size = 0;
149 state_was_pending = false;
151 outbound_mtc_smpte_frame = 0;
152 next_quarter_frame_to_send = -1;
153 current_block_size = 0;
154 _solo_latched = true;
155 _solo_model = InverseMute;
156 solo_update_disabled = false;
157 currently_soloing = false;
158 _have_captured = false;
159 _worst_output_latency = 0;
160 _worst_input_latency = 0;
161 _worst_track_latency = 0;
162 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
165 butler_mixdown_buffer = 0;
166 butler_gain_buffer = 0;
171 post_transport_work = PostTransportWork (0);
172 g_atomic_int_set (&butler_should_do_transport_work, 0);
173 g_atomic_int_set (&butler_active, 0);
174 g_atomic_int_set (&_playback_load, 100);
175 g_atomic_int_set (&_capture_load, 100);
176 g_atomic_int_set (&_playback_load_min, 100);
177 g_atomic_int_set (&_capture_load_min, 100);
178 pending_audition_region = 0;
180 pending_edit_mode = _edit_mode;
184 input_auto_connect = AutoConnectOption (0);
185 output_auto_connect = AutoConnectOption (0);
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;
194 destructive_index = 0;
196 /* allocate conversion buffers */
197 _conversion_buffers[ButlerContext] = new char[AudioDiskstream::disk_io_frames() * 4];
198 _conversion_buffers[TransportContext] = new char[AudioDiskstream::disk_io_frames() * 4];
200 /* default short fade = 15ms */
202 Crossfade::set_short_xfade_length ((jack_nframes_t) floor ((15.0 * frame_rate()) / 1000.0));
203 DestructiveFileSource::setup_standard_crossfades (frame_rate());
205 last_mmc_step.tv_sec = 0;
206 last_mmc_step.tv_usec = 0;
209 preroll.type = AnyTime::Frames;
211 postroll.type = AnyTime::Frames;
214 /* click sounds are unset by default, which causes us to internal
215 waveforms for clicks.
220 click_requested = false;
222 click_emphasis_data = 0;
224 click_emphasis_length = 0;
226 process_function = &Session::process_with_events;
230 _smpte_offset_negative = true;
231 last_smpte_valid = false;
233 last_rr_session_dir = session_dirs.begin();
234 refresh_disk_space ();
236 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
238 /* default configuration */
240 do_not_record_plugins = false;
241 over_length_short = 2;
242 over_length_long = 10;
243 send_midi_timecode = false;
244 send_midi_machine_control = false;
245 shuttle_speed_factor = 1.0;
246 shuttle_speed_threshold = 5;
248 _meter_hold = 100; // XXX unknown units: number of calls to meter::set()
249 _meter_falloff = 1.5f; // XXX unknown units: refresh_rate
255 average_slave_delta = 1800;
256 have_first_delta_accumulator = false;
257 delta_accumulator_cnt = 0;
258 slave_state = Stopped;
260 /* default SMPTE type is 30 FPS, non-drop */
262 set_smpte_type (30.0, false);
264 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
266 /* These are all static "per-class" signals */
268 Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
269 AudioSource::AudioSourceCreated.connect (mem_fun (*this, &Session::add_audio_source));
270 Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
271 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
272 AudioDiskstream::AudioDiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
273 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
275 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
277 /* stop IO objects from doing stuff until we're ready for them */
279 IO::disable_panners ();
280 IO::disable_ports ();
281 IO::disable_connecting ();
285 Session::second_stage_init (bool new_session)
287 AudioFileSource::set_peak_dir (peak_dir());
290 if (load_state (_current_snapshot_name)) {
293 remove_empty_sounds ();
296 if (start_butler_thread()) {
300 /*if (start_midi_thread ()) {
305 if (set_state (*state_tree->root())) {
310 /* we can't save till after ::when_engine_running() is called,
311 because otherwise we save state with no connections made.
312 therefore, we reset _state_of_the_state because ::set_state()
313 will have cleared it.
315 we also have to include Loading so that any events that get
316 generated between here and the end of ::when_engine_running()
317 will be processed directly rather than queued.
320 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
322 // set_auto_input (true);
323 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
324 _locations.added.connect (mem_fun (this, &Session::locations_added));
325 setup_click_sounds (0);
326 setup_midi_control ();
328 /* Pay attention ... */
330 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
331 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
333 if (_engine.running()) {
334 when_engine_running();
336 first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
339 //send_full_time_code ();
340 _engine.transport_locate (0);
341 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
342 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
344 ControlProtocolManager::instance().set_session (*this);
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 location (common case) */
406 session_dirs.push_back (sp);
413 if (fspath[fspath.length()-1] != '/') {
416 fspath += sound_dir_name;
422 if (fspath[fspath.length()-1] != '/') {
425 fspath += tape_dir_name;
427 AudioFileSource::set_search_path (fspath);
434 while ((colon = remaining.find_first_of (':')) != string::npos) {
437 sp.path = remaining.substr (0, colon);
438 session_dirs.push_back (sp);
440 /* add sounds to file search path */
443 if (fspath[fspath.length()-1] != '/') {
446 fspath += sound_dir_name;
449 /* add tape dir to file search path */
452 if (fspath[fspath.length()-1] != '/') {
455 fspath += tape_dir_name;
458 remaining = remaining.substr (colon+1);
461 if (remaining.length()) {
468 if (fspath[fspath.length()-1] != '/') {
471 fspath += sound_dir_name;
475 if (fspath[fspath.length()-1] != '/') {
478 fspath += tape_dir_name;
480 session_dirs.push_back (sp);
483 /* set the AudioFileSource search path */
485 AudioFileSource::set_search_path (fspath);
487 /* reset the round-robin soundfile path thingie */
489 last_rr_session_dir = session_dirs.begin();
493 Session::create (bool& new_session, string* mix_template, jack_nframes_t initial_length)
497 if (mkdir (_path.c_str(), 0755) < 0) {
498 if (errno == EEXIST) {
501 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
510 if (mkdir (dir.c_str(), 0755) < 0) {
511 if (errno != EEXIST) {
512 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
519 if (mkdir (dir.c_str(), 0755) < 0) {
520 if (errno != EEXIST) {
521 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
528 if (mkdir (dir.c_str(), 0755) < 0) {
529 if (errno != EEXIST) {
530 error << string_compose(_("Session: cannot create session tape dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
535 dir = dead_sound_dir ();
537 if (mkdir (dir.c_str(), 0755) < 0) {
538 if (errno != EEXIST) {
539 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
544 dir = automation_dir ();
546 if (mkdir (dir.c_str(), 0755) < 0) {
547 if (errno != EEXIST) {
548 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
554 /* check new_session so we don't overwrite an existing one */
558 std::string in_path = *mix_template;
560 ifstream in(in_path.c_str());
563 string out_path = _path;
565 out_path += _statefile_suffix;
567 ofstream out(out_path.c_str());
572 // okay, session is set up. Treat like normal saved
573 // session from now on.
579 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
585 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
592 warning << _("Session already exists. Not overwriting") << endmsg;
599 /* set initial start + end point */
601 start_location->set_end (0);
602 _locations.add (start_location);
604 end_location->set_end (initial_length);
605 _locations.add (end_location);
607 _state_of_the_state = Clean;
609 if (save_state (_current_snapshot_name)) {
618 Session::load_diskstreams (const XMLNode& node)
621 XMLNodeConstIterator citer;
623 clist = node.children();
625 for (citer = clist.begin(); citer != clist.end(); ++citer) {
627 AudioDiskstream* dstream;
630 dstream = new AudioDiskstream (*this, **citer);
631 /* added automatically by AudioDiskstreamCreated handler */
634 catch (failed_constructor& err) {
635 error << _("Session: could not load diskstream via XML state") << endmsg;
644 Session::remove_pending_capture_state ()
649 xml_path += _current_snapshot_name;
650 xml_path += _pending_suffix;
652 unlink (xml_path.c_str());
656 Session::save_state (string snapshot_name, bool pending)
662 if (_state_of_the_state & CannotSave) {
666 tree.set_root (&get_state());
668 if (snapshot_name.empty()) {
669 snapshot_name = _current_snapshot_name;
675 xml_path += snapshot_name;
676 xml_path += _statefile_suffix;
680 // Make backup of state file
682 if ((access (xml_path.c_str(), F_OK) == 0) &&
683 (rename(xml_path.c_str(), bak_path.c_str()))) {
684 error << _("could not backup old state file, current state not saved.") << endmsg;
691 xml_path += snapshot_name;
692 xml_path += _pending_suffix;
696 if (!tree.write (xml_path)) {
697 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
699 /* don't leave a corrupt file lying around if it is
703 if (unlink (xml_path.c_str())) {
704 error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
707 if (rename (bak_path.c_str(), xml_path.c_str())) {
708 error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
718 bool was_dirty = dirty();
720 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
723 DirtyChanged (); /* EMIT SIGNAL */
726 StateSaved (snapshot_name); /* EMIT SIGNAL */
733 Session::restore_state (string snapshot_name)
735 if (load_state (snapshot_name) == 0) {
736 set_state (*state_tree->root());
743 Session::load_state (string snapshot_name)
752 state_was_pending = false;
754 /* check for leftover pending state from a crashed capture attempt */
757 xmlpath += snapshot_name;
758 xmlpath += _pending_suffix;
760 if (!access (xmlpath.c_str(), F_OK)) {
762 /* there is pending state from a crashed capture attempt */
764 if (AskAboutPendingState()) {
765 state_was_pending = true;
769 if (!state_was_pending) {
772 xmlpath += snapshot_name;
773 xmlpath += _statefile_suffix;
776 if (access (xmlpath.c_str(), F_OK)) {
777 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
781 state_tree = new XMLTree;
785 if (state_tree->read (xmlpath)) {
788 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
797 Session::load_options (const XMLNode& node)
801 bool have_fade_msecs = false;
802 bool have_fade_steepness = false;
803 float fade_msecs = 0;
804 float fade_steepness = 0;
805 SlaveSource slave_src = None;
807 LocaleGuard lg (X_("POSIX"));
809 if ((child = find_named_node (node, "input-auto-connect")) != 0) {
810 if ((prop = child->property ("val")) != 0) {
811 sscanf (prop->value().c_str(), "%x", &x);
812 input_auto_connect = AutoConnectOption (x);
816 if ((child = find_named_node (node, "output-auto-connect")) != 0) {
817 if ((prop = child->property ("val")) != 0) {
818 sscanf (prop->value().c_str(), "%x", &x);
819 output_auto_connect = AutoConnectOption (x);
823 if ((child = find_named_node (node, "slave")) != 0) {
824 if ((prop = child->property ("type")) != 0) {
825 if (prop->value() == "none") {
827 } else if (prop->value() == "mtc") {
829 } else if (prop->value() == "jack") {
832 set_slave_source (slave_src, 0);
836 /* we cannot set edit mode if we are loading a session,
837 because it might destroy the playlist's positioning
840 if ((child = find_named_node (node, "edit-mode")) != 0) {
841 if ((prop = child->property ("val")) != 0) {
842 if (prop->value() == "slide") {
843 pending_edit_mode = Slide;
844 } else if (prop->value() == "splice") {
845 pending_edit_mode = Splice;
850 if ((child = find_named_node (node, "send-midi-timecode")) != 0) {
851 if ((prop = child->property ("val")) != 0) {
852 bool x = (prop->value() == "yes");
853 send_mtc = !x; /* force change in value */
857 if ((child = find_named_node (node, "send-midi-machine-control")) != 0) {
858 if ((prop = child->property ("val")) != 0) {
859 bool x = (prop->value() == "yes");
860 send_mmc = !x; /* force change in value */
861 set_send_mmc (prop->value() == "yes");
864 if ((child = find_named_node (node, "max-level")) != 0) {
865 if ((prop = child->property ("val")) != 0) {
866 max_level = atoi (prop->value().c_str());
869 if ((child = find_named_node (node, "min-level")) != 0) {
870 if ((prop = child->property ("val")) != 0) {
871 min_level = atoi (prop->value().c_str());
874 if ((child = find_named_node (node, "meter-hold")) != 0) {
875 if ((prop = child->property ("val")) != 0) {
876 _meter_hold = atof (prop->value().c_str());
879 if ((child = find_named_node (node, "meter-falloff")) != 0) {
880 if ((prop = child->property ("val")) != 0) {
881 _meter_falloff = atof (prop->value().c_str());
884 if ((child = find_named_node (node, "long-over-length")) != 0) {
885 if ((prop = child->property ("val")) != 0) {
886 over_length_long = atoi (prop->value().c_str());
889 if ((child = find_named_node (node, "short-over-length")) != 0) {
890 if ((prop = child->property ("val")) != 0) {
891 over_length_short = atoi (prop->value().c_str());
894 if ((child = find_named_node (node, "shuttle-speed-factor")) != 0) {
895 if ((prop = child->property ("val")) != 0) {
896 shuttle_speed_factor = atof (prop->value().c_str());
899 if ((child = find_named_node (node, "shuttle-speed-threshold")) != 0) {
900 if ((prop = child->property ("val")) != 0) {
901 shuttle_speed_threshold = atof (prop->value().c_str());
904 if ((child = find_named_node (node, "rf-speed")) != 0) {
905 if ((prop = child->property ("val")) != 0) {
906 rf_speed = atof (prop->value().c_str());
909 if ((child = find_named_node (node, "smpte-frames-per-second")) != 0) {
910 if ((prop = child->property ("val")) != 0) {
911 set_smpte_type( atof (prop->value().c_str()), smpte_drop_frames );
914 if ((child = find_named_node (node, "smpte-drop-frames")) != 0) {
915 if ((prop = child->property ("val")) != 0) {
916 set_smpte_type( smpte_frames_per_second, (prop->value() == "yes") );
919 if ((child = find_named_node (node, "smpte-offset")) != 0) {
920 if ((prop = child->property ("val")) != 0) {
921 set_smpte_offset( atoi (prop->value().c_str()) );
924 if ((child = find_named_node (node, "smpte-offset-negative")) != 0) {
925 if ((prop = child->property ("val")) != 0) {
926 set_smpte_offset_negative( (prop->value() == "yes") );
929 if ((child = find_named_node (node, "click-sound")) != 0) {
930 if ((prop = child->property ("val")) != 0) {
931 click_sound = prop->value();
934 if ((child = find_named_node (node, "click-emphasis-sound")) != 0) {
935 if ((prop = child->property ("val")) != 0) {
936 click_emphasis_sound = prop->value();
940 if ((child = find_named_node (node, "solo-model")) != 0) {
941 if ((prop = child->property ("val")) != 0) {
942 if (prop->value() == "SoloBus")
943 _solo_model = SoloBus;
945 _solo_model = InverseMute;
949 /* BOOLEAN OPTIONS */
951 if ((child = find_named_node (node, "auto-play")) != 0) {
952 if ((prop = child->property ("val")) != 0) {
953 set_auto_play (prop->value() == "yes");
956 if ((child = find_named_node (node, "auto-input")) != 0) {
957 if ((prop = child->property ("val")) != 0) {
958 set_auto_input (prop->value() == "yes");
961 if ((child = find_named_node (node, "seamless-loop")) != 0) {
962 if ((prop = child->property ("val")) != 0) {
963 set_seamless_loop (prop->value() == "yes");
966 if ((child = find_named_node (node, "punch-in")) != 0) {
967 if ((prop = child->property ("val")) != 0) {
968 set_punch_in (prop->value() == "yes");
971 if ((child = find_named_node (node, "punch-out")) != 0) {
972 if ((prop = child->property ("val")) != 0) {
973 set_punch_out (prop->value() == "yes");
976 if ((child = find_named_node (node, "auto-return")) != 0) {
977 if ((prop = child->property ("val")) != 0) {
978 set_auto_return (prop->value() == "yes");
981 if ((child = find_named_node (node, "send-mtc")) != 0) {
982 if ((prop = child->property ("val")) != 0) {
983 set_send_mtc (prop->value() == "yes");
986 if ((child = find_named_node (node, "mmc-control")) != 0) {
987 if ((prop = child->property ("val")) != 0) {
988 set_mmc_control (prop->value() == "yes");
991 if ((child = find_named_node (node, "midi-control")) != 0) {
992 if ((prop = child->property ("val")) != 0) {
993 set_midi_control (prop->value() == "yes");
996 if ((child = find_named_node (node, "midi-feedback")) != 0) {
997 if ((prop = child->property ("val")) != 0) {
998 set_midi_feedback (prop->value() == "yes");
1001 // Legacy support for <recording-plugins>
1002 if ((child = find_named_node (node, "recording-plugins")) != 0) {
1003 if ((prop = child->property ("val")) != 0) {
1004 set_do_not_record_plugins (prop->value() == "no");
1007 if ((child = find_named_node (node, "do-not-record-plugins")) != 0) {
1008 if ((prop = child->property ("val")) != 0) {
1009 set_do_not_record_plugins (prop->value() == "yes");
1012 if ((child = find_named_node (node, "crossfades-active")) != 0) {
1013 if ((prop = child->property ("val")) != 0) {
1014 set_crossfades_active (prop->value() == "yes");
1017 if ((child = find_named_node (node, "audible-click")) != 0) {
1018 if ((prop = child->property ("val")) != 0) {
1019 set_clicking (prop->value() == "yes");
1023 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
1024 if ((prop = child->property ("val")) != 0) {
1025 _end_location_is_free = (prop->value() == "yes");
1029 if ((child = find_named_node (node, "layer-model")) != 0) {
1030 if ((prop = child->property ("val")) != 0) {
1031 if (prop->value() == X_("LaterHigher")) {
1032 set_layer_model (LaterHigher);
1033 } else if (prop->value() == X_("AddHigher")) {
1034 set_layer_model (AddHigher);
1036 set_layer_model (MoveAddHigher);
1041 if ((child = find_named_node (node, "xfade-model")) != 0) {
1042 if ((prop = child->property ("val")) != 0) {
1043 if (prop->value() == X_("Short")) {
1044 set_xfade_model (ShortCrossfade);
1046 set_xfade_model (FullCrossfade);
1051 if ((child = find_named_node (node, "short-xfade-length")) != 0) {
1052 if ((prop = child->property ("val")) != 0) {
1053 /* value is stored as a fractional seconds */
1054 float secs = atof (prop->value().c_str());
1055 Crossfade::set_short_xfade_length ((jack_nframes_t) floor (secs * frame_rate()));
1059 if ((child = find_named_node (node, "full-xfades-unmuted")) != 0) {
1060 if ((prop = child->property ("val")) != 0) {
1061 crossfades_active = (prop->value() == "yes");
1067 if ((child = find_named_node (node, "default-fade-steepness")) != 0) {
1068 if ((prop = child->property ("val")) != 0) {
1069 fade_steepness = atof (prop->value().c_str());
1070 have_fade_steepness = true;
1073 if ((child = find_named_node (node, "default-fade-msec")) != 0) {
1074 if ((prop = child->property ("val")) != 0) {
1075 fade_msecs = atof (prop->value().c_str());
1076 have_fade_msecs = true;
1080 if (have_fade_steepness || have_fade_msecs) {
1081 // set_default_fade (fade_steepness, fade_msecs);
1088 Session::get_options () const
1093 LocaleGuard lg (X_("POSIX"));
1095 opthead = new XMLNode ("Options");
1097 SlaveSource src = slave_source ();
1101 src_string = "none";
1107 src_string = "jack";
1110 child = opthead->add_child ("slave");
1111 child->add_property ("type", src_string);
1113 child = opthead->add_child ("send-midi-timecode");
1114 child->add_property ("val", send_midi_timecode?"yes":"no");
1116 child = opthead->add_child ("send-midi-machine-control");
1117 child->add_property ("val", send_midi_machine_control?"yes":"no");
1119 snprintf (buf, sizeof(buf)-1, "%x", (int) input_auto_connect);
1120 child = opthead->add_child ("input-auto-connect");
1121 child->add_property ("val", buf);
1123 snprintf (buf, sizeof(buf)-1, "%x", (int) output_auto_connect);
1124 child = opthead->add_child ("output-auto-connect");
1125 child->add_property ("val", buf);
1127 snprintf (buf, sizeof(buf)-1, "%d", max_level);
1128 child = opthead->add_child ("max-level");
1129 child->add_property ("val", buf);
1131 snprintf (buf, sizeof(buf)-1, "%d", min_level);
1132 child = opthead->add_child ("min-level");
1133 child->add_property ("val", buf);
1135 snprintf (buf, sizeof(buf)-1, "%f", _meter_hold);
1136 child = opthead->add_child ("meter-hold");
1137 child->add_property ("val", buf);
1139 snprintf (buf, sizeof(buf)-1, "%f", _meter_falloff);
1140 child = opthead->add_child ("meter-falloff");
1141 child->add_property ("val", buf);
1143 snprintf (buf, sizeof(buf)-1, "%u", over_length_long);
1144 child = opthead->add_child ("long-over-length");
1145 child->add_property ("val", buf);
1147 snprintf (buf, sizeof(buf)-1, "%u", over_length_short);
1148 child = opthead->add_child ("short-over-length");
1149 child->add_property ("val", buf);
1151 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_factor);
1152 child = opthead->add_child ("shuttle-speed-factor");
1153 child->add_property ("val", buf);
1155 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_threshold);
1156 child = opthead->add_child ("shuttle-speed-threshold");
1157 child->add_property ("val", buf);
1159 snprintf (buf, sizeof(buf)-1, "%f", rf_speed);
1160 child = opthead->add_child ("rf-speed");
1161 child->add_property ("val", buf);
1163 snprintf (buf, sizeof(buf)-1, "%.2f", smpte_frames_per_second);
1164 child = opthead->add_child ("smpte-frames-per-second");
1165 child->add_property ("val", buf);
1167 child = opthead->add_child ("smpte-drop-frames");
1168 child->add_property ("val", smpte_drop_frames ? "yes" : "no");
1170 snprintf (buf, sizeof(buf)-1, "%u", smpte_offset ());
1171 child = opthead->add_child ("smpte-offset");
1172 child->add_property ("val", buf);
1174 child = opthead->add_child ("smpte-offset-negative");
1175 child->add_property ("val", smpte_offset_negative () ? "yes" : "no");
1177 child = opthead->add_child ("edit-mode");
1178 switch (_edit_mode) {
1180 child->add_property ("val", "splice");
1184 child->add_property ("val", "slide");
1188 child = opthead->add_child ("auto-play");
1189 child->add_property ("val", get_auto_play () ? "yes" : "no");
1190 child = opthead->add_child ("auto-input");
1191 child->add_property ("val", get_auto_input () ? "yes" : "no");
1192 child = opthead->add_child ("seamless-loop");
1193 child->add_property ("val", get_seamless_loop () ? "yes" : "no");
1194 child = opthead->add_child ("punch-in");
1195 child->add_property ("val", get_punch_in () ? "yes" : "no");
1196 child = opthead->add_child ("punch-out");
1197 child->add_property ("val", get_punch_out () ? "yes" : "no");
1198 child = opthead->add_child ("all-safe");
1199 child->add_property ("val", get_all_safe () ? "yes" : "no");
1200 child = opthead->add_child ("auto-return");
1201 child->add_property ("val", get_auto_return () ? "yes" : "no");
1202 child = opthead->add_child ("mmc-control");
1203 child->add_property ("val", get_mmc_control () ? "yes" : "no");
1204 child = opthead->add_child ("midi-control");
1205 child->add_property ("val", get_midi_control () ? "yes" : "no");
1206 child = opthead->add_child ("midi-feedback");
1207 child->add_property ("val", get_midi_feedback () ? "yes" : "no");
1208 child = opthead->add_child ("do-not-record-plugins");
1209 child->add_property ("val", get_do_not_record_plugins () ? "yes" : "no");
1210 child = opthead->add_child ("auto-crossfade");
1211 child->add_property ("val", get_crossfades_active () ? "yes" : "no");
1212 child = opthead->add_child ("audible-click");
1213 child->add_property ("val", get_clicking () ? "yes" : "no");
1214 child = opthead->add_child ("end-marker-is-free");
1215 child->add_property ("val", _end_location_is_free ? "yes" : "no");
1217 if (click_sound.length()) {
1218 child = opthead->add_child ("click-sound");
1219 child->add_property ("val", click_sound);
1222 if (click_emphasis_sound.length()) {
1223 child = opthead->add_child ("click-emphasis-sound");
1224 child->add_property ("val", click_emphasis_sound);
1227 child = opthead->add_child ("solo-model");
1228 child->add_property ("val", _solo_model == SoloBus ? "SoloBus" : "InverseMute");
1230 child = opthead->add_child ("layer-model");
1231 switch (layer_model) {
1233 child->add_property ("val", X_("LaterHigher"));
1236 child->add_property ("val", X_("MoveAddHigher"));
1239 child->add_property ("val", X_("AddHigher"));
1243 child = opthead->add_child ("xfade-model");
1244 switch (xfade_model) {
1246 child->add_property ("val", X_("Full"));
1248 case ShortCrossfade:
1249 child->add_property ("val", X_("Short"));
1252 child = opthead->add_child ("short-xfade-length");
1253 /* store as fractions of a second */
1254 snprintf (buf, sizeof(buf)-1, "%f",
1255 (float) Crossfade::short_xfade_length() / frame_rate());
1256 child->add_property ("val", buf);
1258 child = opthead->add_child ("full-xfades-unmuted");
1259 child->add_property ("val", crossfades_active ? "yes" : "no");
1265 Session::get_state()
1271 Session::get_template()
1273 /* if we don't disable rec-enable, diskstreams
1274 will believe they need to store their capture
1275 sources in their state node.
1278 disable_record (false);
1280 return state(false);
1284 Session::state(bool full_state)
1286 XMLNode* node = new XMLNode("Session");
1289 // store libardour version, just in case
1291 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
1292 libardour_major_version, libardour_minor_version, libardour_micro_version);
1293 node->add_property("version", string(buf));
1295 /* store configuration settings */
1299 /* store the name */
1300 node->add_property ("name", _name);
1302 if (session_dirs.size() > 1) {
1306 vector<space_and_path>::iterator i = session_dirs.begin();
1307 vector<space_and_path>::iterator next;
1309 ++i; /* skip the first one */
1313 while (i != session_dirs.end()) {
1317 if (next != session_dirs.end()) {
1327 child = node->add_child ("Path");
1328 child->add_content (p);
1332 node->add_child_nocopy (get_options());
1334 child = node->add_child ("Sources");
1337 Glib::Mutex::Lock sl (audio_source_lock);
1339 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
1341 /* Don't save information about AudioFileSources that are empty */
1343 AudioFileSource* fs;
1345 if ((fs = dynamic_cast<AudioFileSource*> ((*siter).second)) != 0) {
1346 DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
1348 /* destructive file sources are OK if they are empty, because
1349 we will re-use them every time.
1353 if (fs->length() == 0) {
1359 child->add_child_nocopy ((*siter).second->get_state());
1363 child = node->add_child ("Regions");
1366 Glib::Mutex::Lock rl (region_lock);
1368 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1370 /* only store regions not attached to playlists */
1372 if ((*i).second->playlist() == 0) {
1373 child->add_child_nocopy (i->second->state (true));
1378 child = node->add_child ("DiskStreams");
1381 Glib::RWLock::ReaderLock dl (diskstream_lock);
1382 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
1383 if (!(*i)->hidden()) {
1384 child->add_child_nocopy ((*i)->get_state());
1389 node->add_child_nocopy (_locations.get_state());
1391 child = node->add_child ("Connections");
1393 Glib::Mutex::Lock lm (connection_lock);
1394 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1395 if (!(*i)->system_dependent()) {
1396 child->add_child_nocopy ((*i)->get_state());
1401 child = node->add_child ("Routes");
1403 Glib::RWLock::ReaderLock lm (route_lock);
1405 RoutePublicOrderSorter cmp;
1406 RouteList public_order(routes);
1407 public_order.sort (cmp);
1409 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1410 if (!(*i)->hidden()) {
1412 child->add_child_nocopy ((*i)->get_state());
1414 child->add_child_nocopy ((*i)->get_template());
1421 child = node->add_child ("EditGroups");
1422 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1423 child->add_child_nocopy ((*i)->get_state());
1426 child = node->add_child ("MixGroups");
1427 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1428 child->add_child_nocopy ((*i)->get_state());
1431 child = node->add_child ("Playlists");
1432 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1433 if (!(*i)->hidden()) {
1434 if (!(*i)->empty()) {
1436 child->add_child_nocopy ((*i)->get_state());
1438 child->add_child_nocopy ((*i)->get_template());
1444 child = node->add_child ("UnusedPlaylists");
1445 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1446 if (!(*i)->hidden()) {
1447 if (!(*i)->empty()) {
1449 child->add_child_nocopy ((*i)->get_state());
1451 child->add_child_nocopy ((*i)->get_template());
1459 child = node->add_child ("Click");
1460 child->add_child_nocopy (_click_io->state (full_state));
1464 child = node->add_child ("NamedSelections");
1465 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1467 child->add_child_nocopy ((*i)->get_state());
1472 node->add_child_nocopy (_tempo_map->get_state());
1475 node->add_child_copy (*_extra_xml);
1482 Session::set_state (const XMLNode& node)
1486 const XMLProperty* prop;
1489 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1491 if (node.name() != "Session"){
1492 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1496 StateManager::prohibit_save ();
1498 if ((prop = node.property ("name")) != 0) {
1499 _name = prop->value ();
1502 IO::disable_ports ();
1503 IO::disable_connecting ();
1505 /* Object loading order:
1522 if (use_config_midi_ports ()) {
1525 if ((child = find_named_node (node, "Path")) != 0) {
1526 /* XXX this XML content stuff horrible API design */
1527 string raid_path = _path + ':' + child->children().front()->content();
1528 setup_raid_path (raid_path);
1530 /* the path is already set */
1533 if ((child = find_named_node (node, "extra")) != 0) {
1534 _extra_xml = new XMLNode (*child);
1537 if ((child = find_named_node (node, "Options")) == 0) {
1538 error << _("Session: XML state has no options section") << endmsg;
1539 } else if (load_options (*child)) {
1542 if ((child = find_named_node (node, "Sources")) == 0) {
1543 error << _("Session: XML state has no sources section") << endmsg;
1545 } else if (load_sources (*child)) {
1549 if ((child = find_named_node (node, "Regions")) == 0) {
1550 error << _("Session: XML state has no Regions section") << endmsg;
1552 } else if (load_regions (*child)) {
1556 if ((child = find_named_node (node, "Playlists")) == 0) {
1557 error << _("Session: XML state has no playlists section") << endmsg;
1559 } else if (load_playlists (*child)) {
1563 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1565 } else if (load_unused_playlists (*child)) {
1569 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1570 if (load_named_selections (*child)) {
1575 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1576 error << _("Session: XML state has no diskstreams section") << endmsg;
1578 } else if (load_diskstreams (*child)) {
1582 if ((child = find_named_node (node, "Connections")) == 0) {
1583 error << _("Session: XML state has no connections section") << endmsg;
1585 } else if (load_connections (*child)) {
1589 if ((child = find_named_node (node, "Locations")) == 0) {
1590 error << _("Session: XML state has no locations section") << endmsg;
1592 } else if (_locations.set_state (*child)) {
1598 if ((location = _locations.auto_loop_location()) != 0) {
1599 set_auto_loop_location (location);
1602 if ((location = _locations.auto_punch_location()) != 0) {
1603 set_auto_punch_location (location);
1606 if ((location = _locations.end_location()) == 0) {
1607 _locations.add (end_location);
1609 delete end_location;
1610 end_location = location;
1613 if ((location = _locations.start_location()) == 0) {
1614 _locations.add (start_location);
1616 delete start_location;
1617 start_location = location;
1620 _locations.save_state (_("initial state"));
1622 if ((child = find_named_node (node, "EditGroups")) == 0) {
1623 error << _("Session: XML state has no edit groups section") << endmsg;
1625 } else if (load_edit_groups (*child)) {
1629 if ((child = find_named_node (node, "MixGroups")) == 0) {
1630 error << _("Session: XML state has no mix groups section") << endmsg;
1632 } else if (load_mix_groups (*child)) {
1636 if ((child = find_named_node (node, "TempoMap")) == 0) {
1637 error << _("Session: XML state has no Tempo Map section") << endmsg;
1639 } else if (_tempo_map->set_state (*child)) {
1643 if ((child = find_named_node (node, "Routes")) == 0) {
1644 error << _("Session: XML state has no routes section") << endmsg;
1646 } else if (load_routes (*child)) {
1650 if ((child = find_named_node (node, "Click")) == 0) {
1651 warning << _("Session: XML state has no click section") << endmsg;
1652 } else if (_click_io) {
1653 _click_io->set_state (*child);
1656 /* OK, now we can set edit mode */
1658 set_edit_mode (pending_edit_mode);
1660 /* here beginneth the second phase ... */
1662 StateReady (); /* EMIT SIGNAL */
1664 _state_of_the_state = Clean;
1666 StateManager::allow_save (_("initial state"), true);
1668 if (state_was_pending) {
1669 save_state (_current_snapshot_name);
1670 remove_pending_capture_state ();
1671 state_was_pending = false;
1677 /* we failed, re-enable state saving but don't actually save internal state */
1678 StateManager::allow_save (X_("ignored"), false);
1683 Session::load_routes (const XMLNode& node)
1686 XMLNodeConstIterator niter;
1689 nlist = node.children();
1693 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1695 if ((route = XMLRouteFactory (**niter)) == 0) {
1696 error << _("Session: cannot create Route from XML description.") << endmsg;
1707 Session::XMLRouteFactory (const XMLNode& node)
1709 if (node.name() != "Route") {
1713 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1714 return new AudioTrack (*this, node);
1716 return new Route (*this, node);
1721 Session::load_regions (const XMLNode& node)
1724 XMLNodeConstIterator niter;
1725 AudioRegion* region;
1727 nlist = node.children();
1731 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1733 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1734 error << _("Session: cannot create Region from XML description.") << endmsg;
1742 Session::XMLRegionFactory (const XMLNode& node, bool full)
1744 const XMLProperty* prop;
1748 AudioRegion::SourceList sources;
1749 uint32_t nchans = 1;
1752 if (node.name() != X_("Region")) {
1756 if ((prop = node.property (X_("channels"))) != 0) {
1757 nchans = atoi (prop->value().c_str());
1761 if ((prop = node.property (X_("source-0"))) == 0) {
1762 if ((prop = node.property ("source")) == 0) {
1763 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1768 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1770 if ((source = get_source (s_id)) == 0) {
1771 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1775 as = dynamic_cast<AudioSource*>(source);
1777 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1781 sources.push_back (as);
1783 /* pickup other channels */
1785 for (uint32_t n=1; n < nchans; ++n) {
1786 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1787 if ((prop = node.property (buf)) != 0) {
1788 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1790 if ((source = get_source (s_id)) == 0) {
1791 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1795 as = dynamic_cast<AudioSource*>(source);
1797 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1800 sources.push_back (as);
1806 return new AudioRegion (sources, node);
1809 catch (failed_constructor& err) {
1815 Session::get_sources_as_xml ()
1818 XMLNode* node = new XMLNode (X_("Sources"));
1819 Glib::Mutex::Lock lm (audio_source_lock);
1821 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1822 node->add_child_nocopy ((*i).second->get_state());
1825 /* XXX get MIDI and other sources here */
1831 Session::path_from_region_name (string name, string identifier)
1833 char buf[PATH_MAX+1];
1835 string dir = discover_best_sound_dir ();
1837 for (n = 0; n < 999999; ++n) {
1838 if (identifier.length()) {
1839 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1840 identifier.c_str(), n);
1842 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1844 if (access (buf, F_OK) != 0) {
1854 Session::load_sources (const XMLNode& node)
1857 XMLNodeConstIterator niter;
1860 nlist = node.children();
1864 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1866 if ((source = XMLSourceFactory (**niter)) == 0) {
1867 error << _("Session: cannot create Source from XML description.") << endmsg;
1875 Session::XMLSourceFactory (const XMLNode& node)
1879 if (node.name() != "Source") {
1884 src = AudioFileSource::create (node);
1887 catch (failed_constructor& err) {
1888 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1896 Session::save_template (string template_name)
1899 string xml_path, bak_path, template_path;
1901 if (_state_of_the_state & CannotSave) {
1906 string dir = template_dir();
1908 if ((dp = opendir (dir.c_str()))) {
1911 if (mkdir (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)<0) {
1912 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1917 tree.set_root (&get_template());
1920 xml_path += template_name;
1921 xml_path += _template_suffix;
1923 ifstream in(xml_path.c_str());
1926 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1932 if (!tree.write (xml_path)) {
1933 error << _("mix template not saved") << endmsg;
1941 Session::rename_template (string old_name, string new_name)
1943 string old_path = template_dir() + old_name + _template_suffix;
1944 string new_path = template_dir() + new_name + _template_suffix;
1946 return rename (old_path.c_str(), new_path.c_str());
1950 Session::delete_template (string name)
1952 string template_path = template_dir();
1953 template_path += name;
1954 template_path += _template_suffix;
1956 return remove (template_path.c_str());
1960 Session::refresh_disk_space ()
1963 struct statfs statfsbuf;
1964 vector<space_and_path>::iterator i;
1965 Glib::Mutex::Lock lm (space_lock);
1968 /* get freespace on every FS that is part of the session path */
1970 _total_free_4k_blocks = 0;
1972 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1973 statfs ((*i).path.c_str(), &statfsbuf);
1975 scale = statfsbuf.f_bsize/4096.0;
1977 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1978 _total_free_4k_blocks += (*i).blocks;
1984 Session::ensure_sound_dir (string path, string& result)
1989 /* Ensure that the parent directory exists */
1991 if (mkdir (path.c_str(), 0775)) {
1992 if (errno != EEXIST) {
1993 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1998 /* Ensure that the sounds directory exists */
2002 result += sound_dir_name;
2004 if (mkdir (result.c_str(), 0775)) {
2005 if (errno != EEXIST) {
2006 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
2013 dead += dead_sound_dir_name;
2015 if (mkdir (dead.c_str(), 0775)) {
2016 if (errno != EEXIST) {
2017 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
2024 peak += peak_dir_name;
2026 if (mkdir (peak.c_str(), 0775)) {
2027 if (errno != EEXIST) {
2028 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
2033 /* callers expect this to be terminated ... */
2040 Session::discover_best_sound_dir (bool destructive)
2042 vector<space_and_path>::iterator i;
2045 /* destructive files all go into the same place */
2051 /* handle common case without system calls */
2053 if (session_dirs.size() == 1) {
2057 /* OK, here's the algorithm we're following here:
2059 We want to select which directory to use for
2060 the next file source to be created. Ideally,
2061 we'd like to use a round-robin process so as to
2062 get maximum performance benefits from splitting
2063 the files across multiple disks.
2065 However, in situations without much diskspace, an
2066 RR approach may end up filling up a filesystem
2067 with new files while others still have space.
2068 Its therefore important to pay some attention to
2069 the freespace in the filesystem holding each
2070 directory as well. However, if we did that by
2071 itself, we'd keep creating new files in the file
2072 system with the most space until it was as full
2073 as all others, thus negating any performance
2074 benefits of this RAID-1 like approach.
2076 So, we use a user-configurable space threshold. If
2077 there are at least 2 filesystems with more than this
2078 much space available, we use RR selection between them.
2079 If not, then we pick the filesystem with the most space.
2081 This gets a good balance between the two
2085 refresh_disk_space ();
2087 int free_enough = 0;
2089 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2090 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2095 if (free_enough >= 2) {
2097 bool found_it = false;
2099 /* use RR selection process, ensuring that the one
2103 i = last_rr_session_dir;
2106 if (++i == session_dirs.end()) {
2107 i = session_dirs.begin();
2110 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2111 if (ensure_sound_dir ((*i).path, result) == 0) {
2112 last_rr_session_dir = i;
2118 } while (i != last_rr_session_dir);
2121 result = sound_dir();
2126 /* pick FS with the most freespace (and that
2127 seems to actually work ...)
2130 vector<space_and_path> sorted;
2131 space_and_path_ascending_cmp cmp;
2133 sorted = session_dirs;
2134 sort (sorted.begin(), sorted.end(), cmp);
2136 for (i = sorted.begin(); i != sorted.end(); ++i) {
2137 if (ensure_sound_dir ((*i).path, result) == 0) {
2138 last_rr_session_dir = i;
2143 /* if the above fails, fall back to the most simplistic solution */
2145 if (i == sorted.end()) {
2154 Session::load_playlists (const XMLNode& node)
2157 XMLNodeConstIterator niter;
2160 nlist = node.children();
2164 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2166 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2167 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2175 Session::load_unused_playlists (const XMLNode& node)
2178 XMLNodeConstIterator niter;
2181 nlist = node.children();
2185 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2187 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2188 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2192 // now manually untrack it
2194 track_playlist (playlist, false);
2202 Session::XMLPlaylistFactory (const XMLNode& node)
2205 return new AudioPlaylist (*this, node);
2208 catch (failed_constructor& err) {
2214 Session::load_named_selections (const XMLNode& node)
2217 XMLNodeConstIterator niter;
2220 nlist = node.children();
2224 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2226 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2227 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2235 Session::XMLNamedSelectionFactory (const XMLNode& node)
2238 return new NamedSelection (*this, node);
2241 catch (failed_constructor& err) {
2247 Session::dead_sound_dir () const
2250 res += dead_sound_dir_name;
2256 Session::sound_dir () const
2259 res += sound_dir_name;
2265 Session::tape_dir () const
2268 res += tape_dir_name;
2274 Session::peak_dir () const
2277 res += peak_dir_name;
2283 Session::automation_dir () const
2286 res += "automation/";
2291 Session::template_dir ()
2293 string path = get_user_ardour_path();
2294 path += "templates/";
2300 Session::suffixed_search_path (string suffix, bool data)
2304 path += get_user_ardour_path();
2305 if (path[path.length()-1] != ':') {
2310 path += get_system_data_path();
2312 path += get_system_module_path();
2315 vector<string> split_path;
2317 split (path, split_path, ':');
2320 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2325 if (distance (i, split_path.end()) != 1) {
2334 Session::template_path ()
2336 return suffixed_search_path (X_("templates"), true);
2340 Session::control_protocol_path ()
2342 return suffixed_search_path (X_("surfaces"), false);
2346 Session::load_connections (const XMLNode& node)
2348 XMLNodeList nlist = node.children();
2349 XMLNodeConstIterator niter;
2353 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2354 if ((*niter)->name() == "InputConnection") {
2355 add_connection (new ARDOUR::InputConnection (**niter));
2356 } else if ((*niter)->name() == "OutputConnection") {
2357 add_connection (new ARDOUR::OutputConnection (**niter));
2359 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2368 Session::load_edit_groups (const XMLNode& node)
2370 return load_route_groups (node, true);
2374 Session::load_mix_groups (const XMLNode& node)
2376 return load_route_groups (node, false);
2380 Session::load_route_groups (const XMLNode& node, bool edit)
2382 XMLNodeList nlist = node.children();
2383 XMLNodeConstIterator niter;
2388 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2389 if ((*niter)->name() == "RouteGroup") {
2391 rg = add_edit_group ("");
2392 rg->set_state (**niter);
2394 rg = add_mix_group ("");
2395 rg->set_state (**niter);
2404 Session::swap_configuration(Configuration** new_config)
2406 Glib::RWLock::WriterLock lm (route_lock); // jlc - WHY?
2407 Configuration* tmp = *new_config;
2408 *new_config = Config;
2414 Session::copy_configuration(Configuration* new_config)
2416 Glib::RWLock::WriterLock lm (route_lock);
2417 new_config = new Configuration(*Config);
2421 state_file_filter (const string &str, void *arg)
2423 return (str.length() > strlen(Session::statefile_suffix()) &&
2424 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2428 bool operator()(const string* a, const string* b) {
2434 remove_end(string* state)
2436 string statename(*state);
2438 string::size_type start,end;
2439 if ((start = statename.find_last_of ('/')) != string::npos) {
2440 statename = statename.substr (start+1);
2443 if ((end = statename.rfind(".ardour")) < 0) {
2444 end = statename.length();
2447 return new string(statename.substr (0, end));
2451 Session::possible_states (string path)
2453 PathScanner scanner;
2454 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2456 transform(states->begin(), states->end(), states->begin(), remove_end);
2459 sort (states->begin(), states->end(), cmp);
2465 Session::possible_states () const
2467 return possible_states(_path);
2471 Session::auto_save()
2473 save_state (_current_snapshot_name);
2477 Session::add_edit_group (string name)
2479 RouteGroup* rg = new RouteGroup (*this, name);
2480 edit_groups.push_back (rg);
2481 edit_group_added (rg); /* EMIT SIGNAL */
2487 Session::add_mix_group (string name)
2489 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2490 mix_groups.push_back (rg);
2491 mix_group_added (rg); /* EMIT SIGNAL */
2497 Session::remove_edit_group (RouteGroup& rg)
2499 list<RouteGroup*>::iterator i;
2501 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2502 (*i)->apply (&Route::drop_edit_group, this);
2503 edit_groups.erase (i);
2504 edit_group_removed (); /* EMIT SIGNAL */
2511 Session::remove_mix_group (RouteGroup& rg)
2513 list<RouteGroup*>::iterator i;
2515 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2516 (*i)->apply (&Route::drop_mix_group, this);
2517 mix_groups.erase (i);
2518 mix_group_removed (); /* EMIT SIGNAL */
2525 Session::mix_group_by_name (string name)
2527 list<RouteGroup *>::iterator i;
2529 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2530 if ((*i)->name() == name) {
2538 Session::edit_group_by_name (string name)
2540 list<RouteGroup *>::iterator i;
2542 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2543 if ((*i)->name() == name) {
2551 Session::set_meter_hold (float val)
2554 MeterHoldChanged(); // emit
2558 Session::set_meter_falloff (float val)
2560 _meter_falloff = val;
2561 MeterFalloffChanged(); // emit
2566 Session::begin_reversible_command (string name, UndoAction* private_undo)
2568 current_cmd.clear ();
2569 current_cmd.set_name (name);
2572 current_cmd.add_undo (*private_undo);
2577 Session::commit_reversible_command (UndoAction* private_redo)
2582 current_cmd.add_redo_no_execute (*private_redo);
2585 gettimeofday (&now, 0);
2586 current_cmd.set_timestamp (now);
2588 history.add (current_cmd);
2591 Session::GlobalRouteBooleanState
2592 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2594 GlobalRouteBooleanState s;
2595 Glib::RWLock::ReaderLock lm (route_lock);
2597 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2598 if (!(*i)->hidden()) {
2599 RouteBooleanState v;
2602 v.second = ((*i)->*method)();
2611 Session::GlobalRouteMeterState
2612 Session::get_global_route_metering ()
2614 GlobalRouteMeterState s;
2615 Glib::RWLock::ReaderLock lm (route_lock);
2617 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2618 if (!(*i)->hidden()) {
2622 v.second = (*i)->meter_point();
2632 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2634 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2635 i->first->set_meter_point (i->second, arg);
2640 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2642 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2643 (i->first->*method) (i->second, arg);
2648 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2650 set_global_route_boolean (s, &Route::set_mute, src);
2654 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2656 set_global_route_boolean (s, &Route::set_solo, src);
2660 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2662 set_global_route_boolean (s, &Route::set_record_enable, src);
2666 Session::global_mute_memento (void* src)
2668 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2672 Session::global_metering_memento (void* src)
2674 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2678 Session::global_solo_memento (void* src)
2680 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2684 Session::global_record_enable_memento (void* src)
2686 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2690 template_filter (const string &str, void *arg)
2692 return (str.length() > strlen(Session::template_suffix()) &&
2693 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2697 Session::get_template_list (list<string> &template_names)
2699 vector<string *> *templates;
2700 PathScanner scanner;
2703 path = template_path ();
2705 templates = scanner (path, template_filter, 0, false, true);
2707 vector<string*>::iterator i;
2708 for (i = templates->begin(); i != templates->end(); ++i) {
2709 string fullpath = *(*i);
2712 start = fullpath.find_last_of ('/') + 1;
2713 if ((end = fullpath.find_last_of ('.')) <0) {
2714 end = fullpath.length();
2717 template_names.push_back(fullpath.substr(start, (end-start)));
2722 Session::read_favorite_dirs (FavoriteDirs & favs)
2724 string path = get_user_ardour_path();
2725 path += "/favorite_dirs";
2727 ifstream fav (path.c_str());
2732 if (errno != ENOENT) {
2733 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2744 getline(fav, newfav);
2750 favs.push_back (newfav);
2757 Session::write_favorite_dirs (FavoriteDirs & favs)
2759 string path = get_user_ardour_path();
2760 path += "/favorite_dirs";
2762 ofstream fav (path.c_str());
2768 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2769 fav << (*i) << endl;
2776 accept_all_non_peak_files (const string& path, void *arg)
2778 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2782 accept_all_state_files (const string& path, void *arg)
2784 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2788 Session::find_all_sources (string path, set<string>& result)
2793 if (!tree.read (path)) {
2797 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2802 XMLNodeConstIterator niter;
2804 nlist = node->children();
2808 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2812 if ((prop = (*niter)->property (X_("name"))) == 0) {
2816 if (prop->value()[0] == '/') {
2817 /* external file, ignore */
2821 string path = _path; /* /-terminated */
2822 path += sound_dir_name;
2824 path += prop->value();
2826 result.insert (path);
2833 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2835 PathScanner scanner;
2836 vector<string*>* state_files;
2838 string this_snapshot_path;
2844 if (ripped[ripped.length()-1] == '/') {
2845 ripped = ripped.substr (0, ripped.length() - 1);
2848 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2850 if (state_files == 0) {
2855 this_snapshot_path = _path;
2856 this_snapshot_path += _current_snapshot_name;
2857 this_snapshot_path += _statefile_suffix;
2859 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2861 if (exclude_this_snapshot && **i == this_snapshot_path) {
2865 if (find_all_sources (**i, result) < 0) {
2874 Session::cleanup_sources (Session::cleanup_report& rep)
2876 vector<Source*> dead_sources;
2877 vector<Playlist*> playlists_tbd;
2878 PathScanner scanner;
2880 vector<space_and_path>::iterator i;
2881 vector<space_and_path>::iterator nexti;
2882 vector<string*>* soundfiles;
2883 vector<string> unused;
2884 set<string> all_sources;
2889 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2891 /* step 1: consider deleting all unused playlists */
2893 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2896 status = AskAboutPlaylistDeletion (*x);
2905 playlists_tbd.push_back (*x);
2909 /* leave it alone */
2914 /* now delete any that were marked for deletion */
2916 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2917 PlaylistList::iterator foo;
2919 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2920 unused_playlists.erase (foo);
2925 /* step 2: clear the undo/redo history for all playlists */
2927 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2928 (*x)->drop_all_states ();
2931 /* step 3: find all un-referenced sources */
2936 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2938 AudioSourceList::iterator tmp;
2943 /* only remove files that are not in use and have some size
2944 to them. otherwise we remove the current "nascent"
2948 if ((*i).second->use_cnt() == 0 && (*i).second->length() > 0) {
2949 dead_sources.push_back (i->second);
2951 /* remove this source from our own list to avoid us
2952 adding it to the list of all sources below
2955 audio_sources.erase (i);
2961 /* Step 4: get rid of all regions in the region list that use any dead sources
2962 in case the sources themselves don't go away (they might be referenced in
2966 for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2968 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2969 AudioRegionList::iterator tmp;
2977 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2978 if (&ar->source (n) == (*i)) {
2979 /* this region is dead */
2988 /* build a list of all the possible sound directories for the session */
2990 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2995 sound_path += (*i).path;
2996 sound_path += sound_dir_name;
2998 if (nexti != session_dirs.end()) {
3005 /* now do the same thing for the files that ended up in the sounds dir(s)
3006 but are not referenced as sources in any snapshot.
3009 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
3011 if (soundfiles == 0) {
3015 /* find all sources, but don't use this snapshot because the
3016 state file on disk still references sources we may have already
3020 find_all_sources_across_snapshots (all_sources, true);
3022 /* add our current source list
3025 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
3026 AudioFileSource* fs;
3028 if ((fs = dynamic_cast<AudioFileSource*> ((*i).second)) != 0) {
3029 all_sources.insert (fs->path());
3033 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
3038 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
3048 unused.push_back (spath);
3052 /* now try to move all unused files into the "dead_sounds" directory(ies) */
3054 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
3055 struct stat statbuf;
3057 rep.paths.push_back (*x);
3058 if (stat ((*x).c_str(), &statbuf) == 0) {
3059 rep.space += statbuf.st_size;
3064 /* don't move the file across filesystems, just
3065 stick it in the `dead_sound_dir_name' directory
3066 on whichever filesystem it was already on.
3069 newpath = Glib::path_get_dirname (*x);
3070 newpath = Glib::path_get_dirname (newpath);
3073 newpath += dead_sound_dir_name;
3075 newpath += Glib::path_get_basename ((*x));
3077 if (access (newpath.c_str(), F_OK) == 0) {
3079 /* the new path already exists, try versioning */
3081 char buf[PATH_MAX+1];
3085 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
3088 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
3089 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
3093 if (version == 999) {
3094 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
3098 newpath = newpath_v;
3103 /* it doesn't exist, or we can't read it or something */
3107 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
3108 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
3109 (*x), newpath, strerror (errno))
3115 /* see if there an easy to find peakfile for this file, and remove it.
3118 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
3119 peakpath += ".peak";
3121 if (access (peakpath.c_str(), W_OK) == 0) {
3122 if (::unlink (peakpath.c_str()) != 0) {
3123 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3124 peakpath, _path, strerror (errno))
3126 /* try to back out */
3127 rename (newpath.c_str(), _path.c_str());
3136 /* dump the history list */
3140 /* save state so we don't end up a session file
3141 referring to non-existent sources.
3147 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3152 Session::cleanup_trash_sources (Session::cleanup_report& rep)
3154 vector<space_and_path>::iterator i;
3155 string dead_sound_dir;
3156 struct dirent* dentry;
3157 struct stat statbuf;
3163 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3165 dead_sound_dir = (*i).path;
3166 dead_sound_dir += dead_sound_dir_name;
3168 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
3172 while ((dentry = readdir (dead)) != 0) {
3174 /* avoid '.' and '..' */
3176 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
3177 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3183 fullpath = dead_sound_dir;
3185 fullpath += dentry->d_name;
3187 if (stat (fullpath.c_str(), &statbuf)) {
3191 if (!S_ISREG (statbuf.st_mode)) {
3195 if (unlink (fullpath.c_str())) {
3196 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3197 fullpath, strerror (errno))
3201 rep.paths.push_back (dentry->d_name);
3202 rep.space += statbuf.st_size;
3213 Session::set_dirty ()
3215 bool was_dirty = dirty();
3217 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3220 DirtyChanged(); /* EMIT SIGNAL */
3226 Session::set_clean ()
3228 bool was_dirty = dirty();
3230 _state_of_the_state = Clean;
3233 DirtyChanged(); /* EMIT SIGNAL */