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;
93 Session::first_stage_init (string fullpath, string snapshot_name)
95 if (fullpath.length() == 0) {
96 throw failed_constructor();
100 if (!realpath(fullpath.c_str(), buf) && (errno != ENOENT)) {
101 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
102 throw failed_constructor();
106 if (_path[_path.length()-1] != '/') {
110 /* these two are just provisional settings. set_state()
111 will likely override them.
114 _name = _current_snapshot_name = snapshot_name;
115 setup_raid_path (_path);
117 _current_frame_rate = _engine.frame_rate ();
118 _tempo_map = new TempoMap (_current_frame_rate);
119 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
121 g_atomic_int_set (&processing_prohibited, 0);
124 _transport_speed = 0;
125 _last_transport_speed = 0;
126 transport_sub_state = 0;
127 _transport_frame = 0;
129 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
130 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
131 _end_location_is_free = true;
132 g_atomic_int_set (&_record_status, Disabled);
137 seamless_loop = false;
138 loop_changing = false;
140 crossfades_active = false;
143 _last_roll_location = 0;
144 _last_record_location = 0;
145 pending_locate_frame = 0;
146 pending_locate_roll = false;
147 pending_locate_flush = false;
148 dstream_buffer_size = 0;
150 state_was_pending = false;
152 outbound_mtc_smpte_frame = 0;
153 next_quarter_frame_to_send = -1;
154 current_block_size = 0;
155 _solo_latched = true;
156 _solo_model = InverseMute;
157 solo_update_disabled = false;
158 currently_soloing = false;
159 _have_captured = false;
160 _worst_output_latency = 0;
161 _worst_input_latency = 0;
162 _worst_track_latency = 0;
163 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
166 butler_mixdown_buffer = 0;
167 butler_gain_buffer = 0;
172 post_transport_work = PostTransportWork (0);
173 g_atomic_int_set (&butler_should_do_transport_work, 0);
174 g_atomic_int_set (&butler_active, 0);
175 g_atomic_int_set (&_playback_load, 100);
176 g_atomic_int_set (&_capture_load, 100);
177 g_atomic_int_set (&_playback_load_min, 100);
178 g_atomic_int_set (&_capture_load_min, 100);
179 pending_audition_region = 0;
181 pending_edit_mode = _edit_mode;
185 input_auto_connect = AutoConnectOption (0);
186 output_auto_connect = AutoConnectOption (0);
187 waiting_to_start = false;
189 _gain_automation_buffer = 0;
190 _pan_automation_buffer = 0;
192 pending_abort = false;
193 layer_model = MoveAddHigher;
194 xfade_model = ShortCrossfade;
195 destructive_index = 0;
197 /* allocate conversion buffers */
198 _conversion_buffers[ButlerContext] = new char[AudioDiskstream::disk_io_frames() * 4];
199 _conversion_buffers[TransportContext] = new char[AudioDiskstream::disk_io_frames() * 4];
201 /* default short fade = 15ms */
203 Crossfade::set_short_xfade_length ((jack_nframes_t) floor ((15.0 * frame_rate()) / 1000.0));
204 DestructiveFileSource::setup_standard_crossfades (frame_rate());
206 last_mmc_step.tv_sec = 0;
207 last_mmc_step.tv_usec = 0;
210 preroll.type = AnyTime::Frames;
212 postroll.type = AnyTime::Frames;
215 /* click sounds are unset by default, which causes us to internal
216 waveforms for clicks.
221 click_requested = false;
223 click_emphasis_data = 0;
225 click_emphasis_length = 0;
227 process_function = &Session::process_with_events;
231 _smpte_offset_negative = true;
232 last_smpte_valid = false;
234 last_rr_session_dir = session_dirs.begin();
235 refresh_disk_space ();
237 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
239 /* default configuration */
241 do_not_record_plugins = false;
242 over_length_short = 2;
243 over_length_long = 10;
244 send_midi_timecode = false;
245 send_midi_machine_control = false;
246 shuttle_speed_factor = 1.0;
247 shuttle_speed_threshold = 5;
249 _meter_hold = 100; // XXX unknown units: number of calls to meter::set()
250 _meter_falloff = 1.5f; // XXX unknown units: refresh_rate
256 average_slave_delta = 1800;
257 have_first_delta_accumulator = false;
258 delta_accumulator_cnt = 0;
259 slave_state = Stopped;
261 /* default SMPTE type is 30 FPS, non-drop */
263 set_smpte_type (30.0, false);
265 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
267 /* These are all static "per-class" signals */
269 Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
270 AudioSource::AudioSourceCreated.connect (mem_fun (*this, &Session::add_audio_source));
271 Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
272 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
273 AudioDiskstream::AudioDiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
274 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
276 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
278 /* stop IO objects from doing stuff until we're ready for them */
280 IO::disable_panners ();
281 IO::disable_ports ();
282 IO::disable_connecting ();
286 Session::second_stage_init (bool new_session)
288 AudioFileSource::set_peak_dir (peak_dir());
291 if (load_state (_current_snapshot_name)) {
294 remove_empty_sounds ();
297 if (start_butler_thread()) {
301 if (start_midi_thread ()) {
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);
345 ControlProtocolManager::instance().set_session (*this);
348 _end_location_is_free = true;
350 _end_location_is_free = false;
357 Session::raid_path () const
361 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
366 return path.substr (0, path.length() - 1); // drop final colon
370 Session::set_raid_path (string path)
372 /* public-access to setup_raid_path() */
374 setup_raid_path (path);
378 Session::setup_raid_path (string path)
380 string::size_type colon;
384 string::size_type len = path.length();
389 if (path.length() == 0) {
393 session_dirs.clear ();
395 for (string::size_type n = 0; n < len; ++n) {
396 if (path[n] == ':') {
403 /* no multiple search path, just one location (common case) */
407 session_dirs.push_back (sp);
414 if (fspath[fspath.length()-1] != '/') {
417 fspath += sound_dir_name;
423 if (fspath[fspath.length()-1] != '/') {
426 fspath += tape_dir_name;
428 AudioFileSource::set_search_path (fspath);
435 while ((colon = remaining.find_first_of (':')) != string::npos) {
438 sp.path = remaining.substr (0, colon);
439 session_dirs.push_back (sp);
441 /* add sounds to file search path */
444 if (fspath[fspath.length()-1] != '/') {
447 fspath += sound_dir_name;
450 /* add tape dir to file search path */
453 if (fspath[fspath.length()-1] != '/') {
456 fspath += tape_dir_name;
459 remaining = remaining.substr (colon+1);
462 if (remaining.length()) {
469 if (fspath[fspath.length()-1] != '/') {
472 fspath += sound_dir_name;
476 if (fspath[fspath.length()-1] != '/') {
479 fspath += tape_dir_name;
481 session_dirs.push_back (sp);
484 /* set the AudioFileSource search path */
486 AudioFileSource::set_search_path (fspath);
488 /* reset the round-robin soundfile path thingie */
490 last_rr_session_dir = session_dirs.begin();
494 Session::create (bool& new_session, string* mix_template, jack_nframes_t initial_length)
498 if (mkdir (_path.c_str(), 0755) < 0) {
499 if (errno == EEXIST) {
502 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
511 if (mkdir (dir.c_str(), 0755) < 0) {
512 if (errno != EEXIST) {
513 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
520 if (mkdir (dir.c_str(), 0755) < 0) {
521 if (errno != EEXIST) {
522 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
529 if (mkdir (dir.c_str(), 0755) < 0) {
530 if (errno != EEXIST) {
531 error << string_compose(_("Session: cannot create session tape dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
536 dir = dead_sound_dir ();
538 if (mkdir (dir.c_str(), 0755) < 0) {
539 if (errno != EEXIST) {
540 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
545 dir = automation_dir ();
547 if (mkdir (dir.c_str(), 0755) < 0) {
548 if (errno != EEXIST) {
549 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
555 /* check new_session so we don't overwrite an existing one */
559 std::string in_path = *mix_template;
561 ifstream in(in_path.c_str());
564 string out_path = _path;
566 out_path += _statefile_suffix;
568 ofstream out(out_path.c_str());
573 // okay, session is set up. Treat like normal saved
574 // session from now on.
580 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
586 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
593 warning << _("Session already exists. Not overwriting") << endmsg;
600 /* set initial start + end point */
602 start_location->set_end (0);
603 _locations.add (start_location);
605 end_location->set_end (initial_length);
606 _locations.add (end_location);
608 _state_of_the_state = Clean;
610 if (save_state (_current_snapshot_name)) {
619 Session::load_diskstreams (const XMLNode& node)
622 XMLNodeConstIterator citer;
624 clist = node.children();
626 for (citer = clist.begin(); citer != clist.end(); ++citer) {
628 AudioDiskstream* dstream;
631 dstream = new AudioDiskstream (*this, **citer);
632 /* added automatically by AudioDiskstreamCreated handler */
635 catch (failed_constructor& err) {
636 error << _("Session: could not load diskstream via XML state") << endmsg;
645 Session::remove_pending_capture_state ()
650 xml_path += _current_snapshot_name;
651 xml_path += _pending_suffix;
653 unlink (xml_path.c_str());
657 Session::save_state (string snapshot_name, bool pending)
663 if (_state_of_the_state & CannotSave) {
667 tree.set_root (&get_state());
669 if (snapshot_name.empty()) {
670 snapshot_name = _current_snapshot_name;
676 xml_path += snapshot_name;
677 xml_path += _statefile_suffix;
681 // Make backup of state file
683 if ((access (xml_path.c_str(), F_OK) == 0) &&
684 (rename(xml_path.c_str(), bak_path.c_str()))) {
685 error << _("could not backup old state file, current state not saved.") << endmsg;
692 xml_path += snapshot_name;
693 xml_path += _pending_suffix;
697 if (!tree.write (xml_path)) {
698 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
700 /* don't leave a corrupt file lying around if it is
704 if (unlink (xml_path.c_str())) {
705 error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
708 if (rename (bak_path.c_str(), xml_path.c_str())) {
709 error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
719 bool was_dirty = dirty();
721 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
724 DirtyChanged (); /* EMIT SIGNAL */
727 StateSaved (snapshot_name); /* EMIT SIGNAL */
734 Session::restore_state (string snapshot_name)
736 if (load_state (snapshot_name) == 0) {
737 set_state (*state_tree->root());
744 Session::load_state (string snapshot_name)
753 state_was_pending = false;
755 /* check for leftover pending state from a crashed capture attempt */
758 xmlpath += snapshot_name;
759 xmlpath += _pending_suffix;
761 if (!access (xmlpath.c_str(), F_OK)) {
763 /* there is pending state from a crashed capture attempt */
765 if (AskAboutPendingState()) {
766 state_was_pending = true;
770 if (!state_was_pending) {
773 xmlpath += snapshot_name;
774 xmlpath += _statefile_suffix;
777 if (access (xmlpath.c_str(), F_OK)) {
778 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
782 state_tree = new XMLTree;
786 if (state_tree->read (xmlpath)) {
789 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
798 Session::load_options (const XMLNode& node)
802 bool have_fade_msecs = false;
803 bool have_fade_steepness = false;
804 float fade_msecs = 0;
805 float fade_steepness = 0;
806 SlaveSource slave_src = None;
808 LocaleGuard lg (X_("POSIX"));
810 if ((child = find_named_node (node, "input-auto-connect")) != 0) {
811 if ((prop = child->property ("val")) != 0) {
812 sscanf (prop->value().c_str(), "%x", &x);
813 input_auto_connect = AutoConnectOption (x);
817 if ((child = find_named_node (node, "output-auto-connect")) != 0) {
818 if ((prop = child->property ("val")) != 0) {
819 sscanf (prop->value().c_str(), "%x", &x);
820 output_auto_connect = AutoConnectOption (x);
824 if ((child = find_named_node (node, "slave")) != 0) {
825 if ((prop = child->property ("type")) != 0) {
826 if (prop->value() == "none") {
828 } else if (prop->value() == "mtc") {
830 } else if (prop->value() == "jack") {
833 set_slave_source (slave_src, 0);
837 /* we cannot set edit mode if we are loading a session,
838 because it might destroy the playlist's positioning
841 if ((child = find_named_node (node, "edit-mode")) != 0) {
842 if ((prop = child->property ("val")) != 0) {
843 if (prop->value() == "slide") {
844 pending_edit_mode = Slide;
845 } else if (prop->value() == "splice") {
846 pending_edit_mode = Splice;
851 if ((child = find_named_node (node, "send-midi-timecode")) != 0) {
852 if ((prop = child->property ("val")) != 0) {
853 bool x = (prop->value() == "yes");
854 send_mtc = !x; /* force change in value */
858 if ((child = find_named_node (node, "send-midi-machine-control")) != 0) {
859 if ((prop = child->property ("val")) != 0) {
860 bool x = (prop->value() == "yes");
861 send_mmc = !x; /* force change in value */
862 set_send_mmc (prop->value() == "yes");
865 if ((child = find_named_node (node, "max-level")) != 0) {
866 if ((prop = child->property ("val")) != 0) {
867 max_level = atoi (prop->value().c_str());
870 if ((child = find_named_node (node, "min-level")) != 0) {
871 if ((prop = child->property ("val")) != 0) {
872 min_level = atoi (prop->value().c_str());
875 if ((child = find_named_node (node, "meter-hold")) != 0) {
876 if ((prop = child->property ("val")) != 0) {
877 _meter_hold = atof (prop->value().c_str());
880 if ((child = find_named_node (node, "meter-falloff")) != 0) {
881 if ((prop = child->property ("val")) != 0) {
882 _meter_falloff = atof (prop->value().c_str());
885 if ((child = find_named_node (node, "long-over-length")) != 0) {
886 if ((prop = child->property ("val")) != 0) {
887 over_length_long = atoi (prop->value().c_str());
890 if ((child = find_named_node (node, "short-over-length")) != 0) {
891 if ((prop = child->property ("val")) != 0) {
892 over_length_short = atoi (prop->value().c_str());
895 if ((child = find_named_node (node, "shuttle-speed-factor")) != 0) {
896 if ((prop = child->property ("val")) != 0) {
897 shuttle_speed_factor = atof (prop->value().c_str());
900 if ((child = find_named_node (node, "shuttle-speed-threshold")) != 0) {
901 if ((prop = child->property ("val")) != 0) {
902 shuttle_speed_threshold = atof (prop->value().c_str());
905 if ((child = find_named_node (node, "rf-speed")) != 0) {
906 if ((prop = child->property ("val")) != 0) {
907 rf_speed = atof (prop->value().c_str());
910 if ((child = find_named_node (node, "smpte-frames-per-second")) != 0) {
911 if ((prop = child->property ("val")) != 0) {
912 set_smpte_type( atof (prop->value().c_str()), smpte_drop_frames );
915 if ((child = find_named_node (node, "smpte-drop-frames")) != 0) {
916 if ((prop = child->property ("val")) != 0) {
917 set_smpte_type( smpte_frames_per_second, (prop->value() == "yes") );
920 if ((child = find_named_node (node, "smpte-offset")) != 0) {
921 if ((prop = child->property ("val")) != 0) {
922 set_smpte_offset( atoi (prop->value().c_str()) );
925 if ((child = find_named_node (node, "smpte-offset-negative")) != 0) {
926 if ((prop = child->property ("val")) != 0) {
927 set_smpte_offset_negative( (prop->value() == "yes") );
930 if ((child = find_named_node (node, "click-sound")) != 0) {
931 if ((prop = child->property ("val")) != 0) {
932 click_sound = prop->value();
935 if ((child = find_named_node (node, "click-emphasis-sound")) != 0) {
936 if ((prop = child->property ("val")) != 0) {
937 click_emphasis_sound = prop->value();
941 if ((child = find_named_node (node, "solo-model")) != 0) {
942 if ((prop = child->property ("val")) != 0) {
943 if (prop->value() == "SoloBus")
944 _solo_model = SoloBus;
946 _solo_model = InverseMute;
950 /* BOOLEAN OPTIONS */
952 if ((child = find_named_node (node, "auto-play")) != 0) {
953 if ((prop = child->property ("val")) != 0) {
954 set_auto_play (prop->value() == "yes");
957 if ((child = find_named_node (node, "auto-input")) != 0) {
958 if ((prop = child->property ("val")) != 0) {
959 set_auto_input (prop->value() == "yes");
962 if ((child = find_named_node (node, "seamless-loop")) != 0) {
963 if ((prop = child->property ("val")) != 0) {
964 set_seamless_loop (prop->value() == "yes");
967 if ((child = find_named_node (node, "punch-in")) != 0) {
968 if ((prop = child->property ("val")) != 0) {
969 set_punch_in (prop->value() == "yes");
972 if ((child = find_named_node (node, "punch-out")) != 0) {
973 if ((prop = child->property ("val")) != 0) {
974 set_punch_out (prop->value() == "yes");
977 if ((child = find_named_node (node, "auto-return")) != 0) {
978 if ((prop = child->property ("val")) != 0) {
979 set_auto_return (prop->value() == "yes");
982 if ((child = find_named_node (node, "send-mtc")) != 0) {
983 if ((prop = child->property ("val")) != 0) {
984 set_send_mtc (prop->value() == "yes");
987 if ((child = find_named_node (node, "mmc-control")) != 0) {
988 if ((prop = child->property ("val")) != 0) {
989 set_mmc_control (prop->value() == "yes");
992 if ((child = find_named_node (node, "midi-control")) != 0) {
993 if ((prop = child->property ("val")) != 0) {
994 set_midi_control (prop->value() == "yes");
997 if ((child = find_named_node (node, "midi-feedback")) != 0) {
998 if ((prop = child->property ("val")) != 0) {
999 set_midi_feedback (prop->value() == "yes");
1002 // Legacy support for <recording-plugins>
1003 if ((child = find_named_node (node, "recording-plugins")) != 0) {
1004 if ((prop = child->property ("val")) != 0) {
1005 set_do_not_record_plugins (prop->value() == "no");
1008 if ((child = find_named_node (node, "do-not-record-plugins")) != 0) {
1009 if ((prop = child->property ("val")) != 0) {
1010 set_do_not_record_plugins (prop->value() == "yes");
1013 if ((child = find_named_node (node, "crossfades-active")) != 0) {
1014 if ((prop = child->property ("val")) != 0) {
1015 set_crossfades_active (prop->value() == "yes");
1018 if ((child = find_named_node (node, "audible-click")) != 0) {
1019 if ((prop = child->property ("val")) != 0) {
1020 set_clicking (prop->value() == "yes");
1024 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
1025 if ((prop = child->property ("val")) != 0) {
1026 _end_location_is_free = (prop->value() == "yes");
1030 if ((child = find_named_node (node, "layer-model")) != 0) {
1031 if ((prop = child->property ("val")) != 0) {
1032 if (prop->value() == X_("LaterHigher")) {
1033 set_layer_model (LaterHigher);
1034 } else if (prop->value() == X_("AddHigher")) {
1035 set_layer_model (AddHigher);
1037 set_layer_model (MoveAddHigher);
1042 if ((child = find_named_node (node, "xfade-model")) != 0) {
1043 if ((prop = child->property ("val")) != 0) {
1044 if (prop->value() == X_("Short")) {
1045 set_xfade_model (ShortCrossfade);
1047 set_xfade_model (FullCrossfade);
1052 if ((child = find_named_node (node, "short-xfade-length")) != 0) {
1053 if ((prop = child->property ("val")) != 0) {
1054 /* value is stored as a fractional seconds */
1055 float secs = atof (prop->value().c_str());
1056 Crossfade::set_short_xfade_length ((jack_nframes_t) floor (secs * frame_rate()));
1060 if ((child = find_named_node (node, "full-xfades-unmuted")) != 0) {
1061 if ((prop = child->property ("val")) != 0) {
1062 crossfades_active = (prop->value() == "yes");
1068 if ((child = find_named_node (node, "default-fade-steepness")) != 0) {
1069 if ((prop = child->property ("val")) != 0) {
1070 fade_steepness = atof (prop->value().c_str());
1071 have_fade_steepness = true;
1074 if ((child = find_named_node (node, "default-fade-msec")) != 0) {
1075 if ((prop = child->property ("val")) != 0) {
1076 fade_msecs = atof (prop->value().c_str());
1077 have_fade_msecs = true;
1081 if (have_fade_steepness || have_fade_msecs) {
1082 // set_default_fade (fade_steepness, fade_msecs);
1089 Session::get_options () const
1094 LocaleGuard lg (X_("POSIX"));
1096 opthead = new XMLNode ("Options");
1098 SlaveSource src = slave_source ();
1102 src_string = "none";
1108 src_string = "jack";
1111 child = opthead->add_child ("slave");
1112 child->add_property ("type", src_string);
1114 child = opthead->add_child ("send-midi-timecode");
1115 child->add_property ("val", send_midi_timecode?"yes":"no");
1117 child = opthead->add_child ("send-midi-machine-control");
1118 child->add_property ("val", send_midi_machine_control?"yes":"no");
1120 snprintf (buf, sizeof(buf)-1, "%x", (int) input_auto_connect);
1121 child = opthead->add_child ("input-auto-connect");
1122 child->add_property ("val", buf);
1124 snprintf (buf, sizeof(buf)-1, "%x", (int) output_auto_connect);
1125 child = opthead->add_child ("output-auto-connect");
1126 child->add_property ("val", buf);
1128 snprintf (buf, sizeof(buf)-1, "%d", max_level);
1129 child = opthead->add_child ("max-level");
1130 child->add_property ("val", buf);
1132 snprintf (buf, sizeof(buf)-1, "%d", min_level);
1133 child = opthead->add_child ("min-level");
1134 child->add_property ("val", buf);
1136 snprintf (buf, sizeof(buf)-1, "%f", _meter_hold);
1137 child = opthead->add_child ("meter-hold");
1138 child->add_property ("val", buf);
1140 snprintf (buf, sizeof(buf)-1, "%f", _meter_falloff);
1141 child = opthead->add_child ("meter-falloff");
1142 child->add_property ("val", buf);
1144 snprintf (buf, sizeof(buf)-1, "%u", over_length_long);
1145 child = opthead->add_child ("long-over-length");
1146 child->add_property ("val", buf);
1148 snprintf (buf, sizeof(buf)-1, "%u", over_length_short);
1149 child = opthead->add_child ("short-over-length");
1150 child->add_property ("val", buf);
1152 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_factor);
1153 child = opthead->add_child ("shuttle-speed-factor");
1154 child->add_property ("val", buf);
1156 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_threshold);
1157 child = opthead->add_child ("shuttle-speed-threshold");
1158 child->add_property ("val", buf);
1160 snprintf (buf, sizeof(buf)-1, "%f", rf_speed);
1161 child = opthead->add_child ("rf-speed");
1162 child->add_property ("val", buf);
1164 snprintf (buf, sizeof(buf)-1, "%.2f", smpte_frames_per_second);
1165 child = opthead->add_child ("smpte-frames-per-second");
1166 child->add_property ("val", buf);
1168 child = opthead->add_child ("smpte-drop-frames");
1169 child->add_property ("val", smpte_drop_frames ? "yes" : "no");
1171 snprintf (buf, sizeof(buf)-1, "%u", smpte_offset ());
1172 child = opthead->add_child ("smpte-offset");
1173 child->add_property ("val", buf);
1175 child = opthead->add_child ("smpte-offset-negative");
1176 child->add_property ("val", smpte_offset_negative () ? "yes" : "no");
1178 child = opthead->add_child ("edit-mode");
1179 switch (_edit_mode) {
1181 child->add_property ("val", "splice");
1185 child->add_property ("val", "slide");
1189 child = opthead->add_child ("auto-play");
1190 child->add_property ("val", get_auto_play () ? "yes" : "no");
1191 child = opthead->add_child ("auto-input");
1192 child->add_property ("val", get_auto_input () ? "yes" : "no");
1193 child = opthead->add_child ("seamless-loop");
1194 child->add_property ("val", get_seamless_loop () ? "yes" : "no");
1195 child = opthead->add_child ("punch-in");
1196 child->add_property ("val", get_punch_in () ? "yes" : "no");
1197 child = opthead->add_child ("punch-out");
1198 child->add_property ("val", get_punch_out () ? "yes" : "no");
1199 child = opthead->add_child ("all-safe");
1200 child->add_property ("val", get_all_safe () ? "yes" : "no");
1201 child = opthead->add_child ("auto-return");
1202 child->add_property ("val", get_auto_return () ? "yes" : "no");
1203 child = opthead->add_child ("mmc-control");
1204 child->add_property ("val", get_mmc_control () ? "yes" : "no");
1205 child = opthead->add_child ("midi-control");
1206 child->add_property ("val", get_midi_control () ? "yes" : "no");
1207 child = opthead->add_child ("midi-feedback");
1208 child->add_property ("val", get_midi_feedback () ? "yes" : "no");
1209 child = opthead->add_child ("do-not-record-plugins");
1210 child->add_property ("val", get_do_not_record_plugins () ? "yes" : "no");
1211 child = opthead->add_child ("auto-crossfade");
1212 child->add_property ("val", get_crossfades_active () ? "yes" : "no");
1213 child = opthead->add_child ("audible-click");
1214 child->add_property ("val", get_clicking () ? "yes" : "no");
1215 child = opthead->add_child ("end-marker-is-free");
1216 child->add_property ("val", _end_location_is_free ? "yes" : "no");
1218 if (click_sound.length()) {
1219 child = opthead->add_child ("click-sound");
1220 child->add_property ("val", click_sound);
1223 if (click_emphasis_sound.length()) {
1224 child = opthead->add_child ("click-emphasis-sound");
1225 child->add_property ("val", click_emphasis_sound);
1228 child = opthead->add_child ("solo-model");
1229 child->add_property ("val", _solo_model == SoloBus ? "SoloBus" : "InverseMute");
1231 child = opthead->add_child ("layer-model");
1232 switch (layer_model) {
1234 child->add_property ("val", X_("LaterHigher"));
1237 child->add_property ("val", X_("MoveAddHigher"));
1240 child->add_property ("val", X_("AddHigher"));
1244 child = opthead->add_child ("xfade-model");
1245 switch (xfade_model) {
1247 child->add_property ("val", X_("Full"));
1249 case ShortCrossfade:
1250 child->add_property ("val", X_("Short"));
1253 child = opthead->add_child ("short-xfade-length");
1254 /* store as fractions of a second */
1255 snprintf (buf, sizeof(buf)-1, "%f",
1256 (float) Crossfade::short_xfade_length() / frame_rate());
1257 child->add_property ("val", buf);
1259 child = opthead->add_child ("full-xfades-unmuted");
1260 child->add_property ("val", crossfades_active ? "yes" : "no");
1266 Session::get_state()
1272 Session::get_template()
1274 /* if we don't disable rec-enable, diskstreams
1275 will believe they need to store their capture
1276 sources in their state node.
1279 disable_record (false);
1281 return state(false);
1285 Session::state(bool full_state)
1287 XMLNode* node = new XMLNode("Session");
1290 // store libardour version, just in case
1292 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
1293 libardour_major_version, libardour_minor_version, libardour_micro_version);
1294 node->add_property("version", string(buf));
1296 /* store configuration settings */
1300 /* store the name */
1301 node->add_property ("name", _name);
1303 if (session_dirs.size() > 1) {
1307 vector<space_and_path>::iterator i = session_dirs.begin();
1308 vector<space_and_path>::iterator next;
1310 ++i; /* skip the first one */
1314 while (i != session_dirs.end()) {
1318 if (next != session_dirs.end()) {
1328 child = node->add_child ("Path");
1329 child->add_content (p);
1333 node->add_child_nocopy (get_options());
1335 child = node->add_child ("Sources");
1338 Glib::Mutex::Lock sl (audio_source_lock);
1340 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
1342 /* Don't save information about AudioFileSources that are empty */
1344 AudioFileSource* fs;
1346 if ((fs = dynamic_cast<AudioFileSource*> ((*siter).second)) != 0) {
1347 DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
1349 /* destructive file sources are OK if they are empty, because
1350 we will re-use them every time.
1354 if (fs->length() == 0) {
1360 child->add_child_nocopy ((*siter).second->get_state());
1364 child = node->add_child ("Regions");
1367 Glib::Mutex::Lock rl (region_lock);
1369 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1371 /* only store regions not attached to playlists */
1373 if ((*i).second->playlist() == 0) {
1374 child->add_child_nocopy (i->second->state (true));
1379 child = node->add_child ("DiskStreams");
1382 Glib::RWLock::ReaderLock dl (diskstream_lock);
1383 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
1384 if (!(*i)->hidden()) {
1385 child->add_child_nocopy ((*i)->get_state());
1390 node->add_child_nocopy (_locations.get_state());
1392 child = node->add_child ("Connections");
1394 Glib::Mutex::Lock lm (connection_lock);
1395 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1396 if (!(*i)->system_dependent()) {
1397 child->add_child_nocopy ((*i)->get_state());
1402 child = node->add_child ("Routes");
1404 Glib::RWLock::ReaderLock lm (route_lock);
1406 RoutePublicOrderSorter cmp;
1407 RouteList public_order(routes);
1408 public_order.sort (cmp);
1410 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1411 if (!(*i)->hidden()) {
1413 child->add_child_nocopy ((*i)->get_state());
1415 child->add_child_nocopy ((*i)->get_template());
1422 child = node->add_child ("EditGroups");
1423 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1424 child->add_child_nocopy ((*i)->get_state());
1427 child = node->add_child ("MixGroups");
1428 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1429 child->add_child_nocopy ((*i)->get_state());
1432 child = node->add_child ("Playlists");
1433 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1434 if (!(*i)->hidden()) {
1435 if (!(*i)->empty()) {
1437 child->add_child_nocopy ((*i)->get_state());
1439 child->add_child_nocopy ((*i)->get_template());
1445 child = node->add_child ("UnusedPlaylists");
1446 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1447 if (!(*i)->hidden()) {
1448 if (!(*i)->empty()) {
1450 child->add_child_nocopy ((*i)->get_state());
1452 child->add_child_nocopy ((*i)->get_template());
1460 child = node->add_child ("Click");
1461 child->add_child_nocopy (_click_io->state (full_state));
1465 child = node->add_child ("NamedSelections");
1466 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1468 child->add_child_nocopy ((*i)->get_state());
1473 node->add_child_nocopy (_tempo_map->get_state());
1476 node->add_child_copy (*_extra_xml);
1483 Session::set_state (const XMLNode& node)
1487 const XMLProperty* prop;
1490 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1492 if (node.name() != "Session"){
1493 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1497 StateManager::prohibit_save ();
1499 if ((prop = node.property ("name")) != 0) {
1500 _name = prop->value ();
1503 IO::disable_ports ();
1504 IO::disable_connecting ();
1506 /* Object loading order:
1523 if (use_config_midi_ports ()) {
1526 if ((child = find_named_node (node, "Path")) != 0) {
1527 /* XXX this XML content stuff horrible API design */
1528 string raid_path = _path + ':' + child->children().front()->content();
1529 setup_raid_path (raid_path);
1531 /* the path is already set */
1534 if ((child = find_named_node (node, "extra")) != 0) {
1535 _extra_xml = new XMLNode (*child);
1538 if ((child = find_named_node (node, "Options")) == 0) {
1539 error << _("Session: XML state has no options section") << endmsg;
1540 } else if (load_options (*child)) {
1543 if ((child = find_named_node (node, "Sources")) == 0) {
1544 error << _("Session: XML state has no sources section") << endmsg;
1546 } else if (load_sources (*child)) {
1550 if ((child = find_named_node (node, "Regions")) == 0) {
1551 error << _("Session: XML state has no Regions section") << endmsg;
1553 } else if (load_regions (*child)) {
1557 if ((child = find_named_node (node, "Playlists")) == 0) {
1558 error << _("Session: XML state has no playlists section") << endmsg;
1560 } else if (load_playlists (*child)) {
1564 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1566 } else if (load_unused_playlists (*child)) {
1570 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1571 if (load_named_selections (*child)) {
1576 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1577 error << _("Session: XML state has no diskstreams section") << endmsg;
1579 } else if (load_diskstreams (*child)) {
1583 if ((child = find_named_node (node, "Connections")) == 0) {
1584 error << _("Session: XML state has no connections section") << endmsg;
1586 } else if (load_connections (*child)) {
1590 if ((child = find_named_node (node, "Locations")) == 0) {
1591 error << _("Session: XML state has no locations section") << endmsg;
1593 } else if (_locations.set_state (*child)) {
1599 if ((location = _locations.auto_loop_location()) != 0) {
1600 set_auto_loop_location (location);
1603 if ((location = _locations.auto_punch_location()) != 0) {
1604 set_auto_punch_location (location);
1607 if ((location = _locations.end_location()) == 0) {
1608 _locations.add (end_location);
1610 delete end_location;
1611 end_location = location;
1614 if ((location = _locations.start_location()) == 0) {
1615 _locations.add (start_location);
1617 delete start_location;
1618 start_location = location;
1621 _locations.save_state (_("initial state"));
1623 if ((child = find_named_node (node, "EditGroups")) == 0) {
1624 error << _("Session: XML state has no edit groups section") << endmsg;
1626 } else if (load_edit_groups (*child)) {
1630 if ((child = find_named_node (node, "MixGroups")) == 0) {
1631 error << _("Session: XML state has no mix groups section") << endmsg;
1633 } else if (load_mix_groups (*child)) {
1637 if ((child = find_named_node (node, "TempoMap")) == 0) {
1638 error << _("Session: XML state has no Tempo Map section") << endmsg;
1640 } else if (_tempo_map->set_state (*child)) {
1644 if ((child = find_named_node (node, "Routes")) == 0) {
1645 error << _("Session: XML state has no routes section") << endmsg;
1647 } else if (load_routes (*child)) {
1651 if ((child = find_named_node (node, "Click")) == 0) {
1652 warning << _("Session: XML state has no click section") << endmsg;
1653 } else if (_click_io) {
1654 _click_io->set_state (*child);
1657 /* OK, now we can set edit mode */
1659 set_edit_mode (pending_edit_mode);
1661 /* here beginneth the second phase ... */
1663 StateReady (); /* EMIT SIGNAL */
1665 _state_of_the_state = Clean;
1667 StateManager::allow_save (_("initial state"), true);
1669 if (state_was_pending) {
1670 save_state (_current_snapshot_name);
1671 remove_pending_capture_state ();
1672 state_was_pending = false;
1678 /* we failed, re-enable state saving but don't actually save internal state */
1679 StateManager::allow_save (X_("ignored"), false);
1684 Session::load_routes (const XMLNode& node)
1687 XMLNodeConstIterator niter;
1690 nlist = node.children();
1694 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1696 if ((route = XMLRouteFactory (**niter)) == 0) {
1697 error << _("Session: cannot create Route from XML description.") << endmsg;
1708 Session::XMLRouteFactory (const XMLNode& node)
1710 if (node.name() != "Route") {
1714 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1715 return new AudioTrack (*this, node);
1717 return new Route (*this, node);
1722 Session::load_regions (const XMLNode& node)
1725 XMLNodeConstIterator niter;
1726 AudioRegion* region;
1728 nlist = node.children();
1732 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1734 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1735 error << _("Session: cannot create Region from XML description.") << endmsg;
1743 Session::XMLRegionFactory (const XMLNode& node, bool full)
1745 const XMLProperty* prop;
1749 AudioRegion::SourceList sources;
1750 uint32_t nchans = 1;
1753 if (node.name() != X_("Region")) {
1757 if ((prop = node.property (X_("channels"))) != 0) {
1758 nchans = atoi (prop->value().c_str());
1762 if ((prop = node.property (X_("source-0"))) == 0) {
1763 if ((prop = node.property ("source")) == 0) {
1764 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1769 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1771 if ((source = get_source (s_id)) == 0) {
1772 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1776 as = dynamic_cast<AudioSource*>(source);
1778 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1782 sources.push_back (as);
1784 /* pickup other channels */
1786 for (uint32_t n=1; n < nchans; ++n) {
1787 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1788 if ((prop = node.property (buf)) != 0) {
1789 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1791 if ((source = get_source (s_id)) == 0) {
1792 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1796 as = dynamic_cast<AudioSource*>(source);
1798 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1801 sources.push_back (as);
1807 return new AudioRegion (sources, node);
1810 catch (failed_constructor& err) {
1816 Session::get_sources_as_xml ()
1819 XMLNode* node = new XMLNode (X_("Sources"));
1820 Glib::Mutex::Lock lm (audio_source_lock);
1822 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1823 node->add_child_nocopy ((*i).second->get_state());
1826 /* XXX get MIDI and other sources here */
1832 Session::path_from_region_name (string name, string identifier)
1834 char buf[PATH_MAX+1];
1836 string dir = discover_best_sound_dir ();
1838 for (n = 0; n < 999999; ++n) {
1839 if (identifier.length()) {
1840 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1841 identifier.c_str(), n);
1843 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1845 if (access (buf, F_OK) != 0) {
1855 Session::load_sources (const XMLNode& node)
1858 XMLNodeConstIterator niter;
1861 nlist = node.children();
1865 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1867 if ((source = XMLSourceFactory (**niter)) == 0) {
1868 error << _("Session: cannot create Source from XML description.") << endmsg;
1876 Session::XMLSourceFactory (const XMLNode& node)
1880 if (node.name() != "Source") {
1885 src = AudioFileSource::create (node);
1888 catch (failed_constructor& err) {
1889 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1897 Session::save_template (string template_name)
1900 string xml_path, bak_path, template_path;
1902 if (_state_of_the_state & CannotSave) {
1907 string dir = template_dir();
1909 if ((dp = opendir (dir.c_str()))) {
1912 if (mkdir (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)<0) {
1913 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1918 tree.set_root (&get_template());
1921 xml_path += template_name;
1922 xml_path += _template_suffix;
1924 ifstream in(xml_path.c_str());
1927 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1933 if (!tree.write (xml_path)) {
1934 error << _("mix template not saved") << endmsg;
1942 Session::rename_template (string old_name, string new_name)
1944 string old_path = template_dir() + old_name + _template_suffix;
1945 string new_path = template_dir() + new_name + _template_suffix;
1947 return rename (old_path.c_str(), new_path.c_str());
1951 Session::delete_template (string name)
1953 string template_path = template_dir();
1954 template_path += name;
1955 template_path += _template_suffix;
1957 return remove (template_path.c_str());
1961 Session::refresh_disk_space ()
1964 struct statfs statfsbuf;
1965 vector<space_and_path>::iterator i;
1966 Glib::Mutex::Lock lm (space_lock);
1969 /* get freespace on every FS that is part of the session path */
1971 _total_free_4k_blocks = 0;
1973 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1974 statfs ((*i).path.c_str(), &statfsbuf);
1976 scale = statfsbuf.f_bsize/4096.0;
1978 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1979 _total_free_4k_blocks += (*i).blocks;
1985 Session::ensure_sound_dir (string path, string& result)
1990 /* Ensure that the parent directory exists */
1992 if (mkdir (path.c_str(), 0775)) {
1993 if (errno != EEXIST) {
1994 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1999 /* Ensure that the sounds directory exists */
2003 result += sound_dir_name;
2005 if (mkdir (result.c_str(), 0775)) {
2006 if (errno != EEXIST) {
2007 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
2014 dead += dead_sound_dir_name;
2016 if (mkdir (dead.c_str(), 0775)) {
2017 if (errno != EEXIST) {
2018 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
2025 peak += peak_dir_name;
2027 if (mkdir (peak.c_str(), 0775)) {
2028 if (errno != EEXIST) {
2029 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
2034 /* callers expect this to be terminated ... */
2041 Session::discover_best_sound_dir (bool destructive)
2043 vector<space_and_path>::iterator i;
2046 /* destructive files all go into the same place */
2052 /* handle common case without system calls */
2054 if (session_dirs.size() == 1) {
2058 /* OK, here's the algorithm we're following here:
2060 We want to select which directory to use for
2061 the next file source to be created. Ideally,
2062 we'd like to use a round-robin process so as to
2063 get maximum performance benefits from splitting
2064 the files across multiple disks.
2066 However, in situations without much diskspace, an
2067 RR approach may end up filling up a filesystem
2068 with new files while others still have space.
2069 Its therefore important to pay some attention to
2070 the freespace in the filesystem holding each
2071 directory as well. However, if we did that by
2072 itself, we'd keep creating new files in the file
2073 system with the most space until it was as full
2074 as all others, thus negating any performance
2075 benefits of this RAID-1 like approach.
2077 So, we use a user-configurable space threshold. If
2078 there are at least 2 filesystems with more than this
2079 much space available, we use RR selection between them.
2080 If not, then we pick the filesystem with the most space.
2082 This gets a good balance between the two
2086 refresh_disk_space ();
2088 int free_enough = 0;
2090 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2091 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2096 if (free_enough >= 2) {
2098 bool found_it = false;
2100 /* use RR selection process, ensuring that the one
2104 i = last_rr_session_dir;
2107 if (++i == session_dirs.end()) {
2108 i = session_dirs.begin();
2111 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2112 if (ensure_sound_dir ((*i).path, result) == 0) {
2113 last_rr_session_dir = i;
2119 } while (i != last_rr_session_dir);
2122 result = sound_dir();
2127 /* pick FS with the most freespace (and that
2128 seems to actually work ...)
2131 vector<space_and_path> sorted;
2132 space_and_path_ascending_cmp cmp;
2134 sorted = session_dirs;
2135 sort (sorted.begin(), sorted.end(), cmp);
2137 for (i = sorted.begin(); i != sorted.end(); ++i) {
2138 if (ensure_sound_dir ((*i).path, result) == 0) {
2139 last_rr_session_dir = i;
2144 /* if the above fails, fall back to the most simplistic solution */
2146 if (i == sorted.end()) {
2155 Session::load_playlists (const XMLNode& node)
2158 XMLNodeConstIterator niter;
2161 nlist = node.children();
2165 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2167 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2168 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2176 Session::load_unused_playlists (const XMLNode& node)
2179 XMLNodeConstIterator niter;
2182 nlist = node.children();
2186 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2188 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2189 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2193 // now manually untrack it
2195 track_playlist (playlist, false);
2203 Session::XMLPlaylistFactory (const XMLNode& node)
2206 return new AudioPlaylist (*this, node);
2209 catch (failed_constructor& err) {
2215 Session::load_named_selections (const XMLNode& node)
2218 XMLNodeConstIterator niter;
2221 nlist = node.children();
2225 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2227 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2228 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2236 Session::XMLNamedSelectionFactory (const XMLNode& node)
2239 return new NamedSelection (*this, node);
2242 catch (failed_constructor& err) {
2248 Session::dead_sound_dir () const
2251 res += dead_sound_dir_name;
2257 Session::sound_dir () const
2260 res += sound_dir_name;
2266 Session::tape_dir () const
2269 res += tape_dir_name;
2275 Session::peak_dir () const
2278 res += peak_dir_name;
2284 Session::automation_dir () const
2287 res += "automation/";
2292 Session::template_dir ()
2294 string path = get_user_ardour_path();
2295 path += "templates/";
2301 Session::suffixed_search_path (string suffix, bool data)
2305 path += get_user_ardour_path();
2306 if (path[path.length()-1] != ':') {
2311 path += get_system_data_path();
2313 path += get_system_module_path();
2316 vector<string> split_path;
2318 split (path, split_path, ':');
2321 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2326 if (distance (i, split_path.end()) != 1) {
2335 Session::template_path ()
2337 return suffixed_search_path (X_("templates"), true);
2341 Session::control_protocol_path ()
2343 return suffixed_search_path (X_("surfaces"), false);
2347 Session::load_connections (const XMLNode& node)
2349 XMLNodeList nlist = node.children();
2350 XMLNodeConstIterator niter;
2354 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2355 if ((*niter)->name() == "InputConnection") {
2356 add_connection (new ARDOUR::InputConnection (**niter));
2357 } else if ((*niter)->name() == "OutputConnection") {
2358 add_connection (new ARDOUR::OutputConnection (**niter));
2360 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2369 Session::load_edit_groups (const XMLNode& node)
2371 return load_route_groups (node, true);
2375 Session::load_mix_groups (const XMLNode& node)
2377 return load_route_groups (node, false);
2381 Session::load_route_groups (const XMLNode& node, bool edit)
2383 XMLNodeList nlist = node.children();
2384 XMLNodeConstIterator niter;
2389 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2390 if ((*niter)->name() == "RouteGroup") {
2392 rg = add_edit_group ("");
2393 rg->set_state (**niter);
2395 rg = add_mix_group ("");
2396 rg->set_state (**niter);
2405 Session::swap_configuration(Configuration** new_config)
2407 Glib::RWLock::WriterLock lm (route_lock); // jlc - WHY?
2408 Configuration* tmp = *new_config;
2409 *new_config = Config;
2415 Session::copy_configuration(Configuration* new_config)
2417 Glib::RWLock::WriterLock lm (route_lock);
2418 new_config = new Configuration(*Config);
2422 state_file_filter (const string &str, void *arg)
2424 return (str.length() > strlen(Session::statefile_suffix()) &&
2425 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2429 bool operator()(const string* a, const string* b) {
2435 remove_end(string* state)
2437 string statename(*state);
2439 string::size_type start,end;
2440 if ((start = statename.find_last_of ('/')) != string::npos) {
2441 statename = statename.substr (start+1);
2444 if ((end = statename.rfind(".ardour")) < 0) {
2445 end = statename.length();
2448 return new string(statename.substr (0, end));
2452 Session::possible_states (string path)
2454 PathScanner scanner;
2455 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2457 transform(states->begin(), states->end(), states->begin(), remove_end);
2460 sort (states->begin(), states->end(), cmp);
2466 Session::possible_states () const
2468 return possible_states(_path);
2472 Session::auto_save()
2474 save_state (_current_snapshot_name);
2478 Session::add_edit_group (string name)
2480 RouteGroup* rg = new RouteGroup (*this, name);
2481 edit_groups.push_back (rg);
2482 edit_group_added (rg); /* EMIT SIGNAL */
2488 Session::add_mix_group (string name)
2490 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2491 mix_groups.push_back (rg);
2492 mix_group_added (rg); /* EMIT SIGNAL */
2498 Session::remove_edit_group (RouteGroup& rg)
2500 list<RouteGroup*>::iterator i;
2502 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2503 (*i)->apply (&Route::drop_edit_group, this);
2504 edit_groups.erase (i);
2505 edit_group_removed (); /* EMIT SIGNAL */
2512 Session::remove_mix_group (RouteGroup& rg)
2514 list<RouteGroup*>::iterator i;
2516 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2517 (*i)->apply (&Route::drop_mix_group, this);
2518 mix_groups.erase (i);
2519 mix_group_removed (); /* EMIT SIGNAL */
2526 Session::mix_group_by_name (string name)
2528 list<RouteGroup *>::iterator i;
2530 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2531 if ((*i)->name() == name) {
2539 Session::edit_group_by_name (string name)
2541 list<RouteGroup *>::iterator i;
2543 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2544 if ((*i)->name() == name) {
2552 Session::set_meter_hold (float val)
2555 MeterHoldChanged(); // emit
2559 Session::set_meter_falloff (float val)
2561 _meter_falloff = val;
2562 MeterFalloffChanged(); // emit
2567 Session::begin_reversible_command (string name)
2569 current_trans.clear ();
2570 current_trans.set_name (name);
2574 Session::commit_reversible_command (Command *cmd)
2579 current_trans.add_command (cmd);
2582 gettimeofday (&now, 0);
2583 current_trans.set_timestamp (now);
2585 history.add (current_trans);
2588 Session::GlobalRouteBooleanState
2589 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2591 GlobalRouteBooleanState s;
2592 Glib::RWLock::ReaderLock lm (route_lock);
2594 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2595 if (!(*i)->hidden()) {
2596 RouteBooleanState v;
2599 v.second = ((*i)->*method)();
2608 Session::GlobalRouteMeterState
2609 Session::get_global_route_metering ()
2611 GlobalRouteMeterState s;
2612 Glib::RWLock::ReaderLock lm (route_lock);
2614 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2615 if (!(*i)->hidden()) {
2619 v.second = (*i)->meter_point();
2629 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2631 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2632 i->first->set_meter_point (i->second, arg);
2637 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2639 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2640 (i->first->*method) (i->second, arg);
2645 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2647 set_global_route_boolean (s, &Route::set_mute, src);
2651 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2653 set_global_route_boolean (s, &Route::set_solo, src);
2657 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2659 set_global_route_boolean (s, &Route::set_record_enable, src);
2664 Session::global_mute_memento (void* src)
2666 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2670 Session::global_metering_memento (void* src)
2672 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2676 Session::global_solo_memento (void* src)
2678 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2682 Session::global_record_enable_memento (void* src)
2684 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2689 template_filter (const string &str, void *arg)
2691 return (str.length() > strlen(Session::template_suffix()) &&
2692 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2696 Session::get_template_list (list<string> &template_names)
2698 vector<string *> *templates;
2699 PathScanner scanner;
2702 path = template_path ();
2704 templates = scanner (path, template_filter, 0, false, true);
2706 vector<string*>::iterator i;
2707 for (i = templates->begin(); i != templates->end(); ++i) {
2708 string fullpath = *(*i);
2711 start = fullpath.find_last_of ('/') + 1;
2712 if ((end = fullpath.find_last_of ('.')) <0) {
2713 end = fullpath.length();
2716 template_names.push_back(fullpath.substr(start, (end-start)));
2721 Session::read_favorite_dirs (FavoriteDirs & favs)
2723 string path = get_user_ardour_path();
2724 path += "/favorite_dirs";
2726 ifstream fav (path.c_str());
2731 if (errno != ENOENT) {
2732 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2743 getline(fav, newfav);
2749 favs.push_back (newfav);
2756 Session::write_favorite_dirs (FavoriteDirs & favs)
2758 string path = get_user_ardour_path();
2759 path += "/favorite_dirs";
2761 ofstream fav (path.c_str());
2767 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2768 fav << (*i) << endl;
2775 accept_all_non_peak_files (const string& path, void *arg)
2777 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2781 accept_all_state_files (const string& path, void *arg)
2783 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2787 Session::find_all_sources (string path, set<string>& result)
2792 if (!tree.read (path)) {
2796 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2801 XMLNodeConstIterator niter;
2803 nlist = node->children();
2807 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2811 if ((prop = (*niter)->property (X_("name"))) == 0) {
2815 if (prop->value()[0] == '/') {
2816 /* external file, ignore */
2820 string path = _path; /* /-terminated */
2821 path += sound_dir_name;
2823 path += prop->value();
2825 result.insert (path);
2832 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2834 PathScanner scanner;
2835 vector<string*>* state_files;
2837 string this_snapshot_path;
2843 if (ripped[ripped.length()-1] == '/') {
2844 ripped = ripped.substr (0, ripped.length() - 1);
2847 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2849 if (state_files == 0) {
2854 this_snapshot_path = _path;
2855 this_snapshot_path += _current_snapshot_name;
2856 this_snapshot_path += _statefile_suffix;
2858 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2860 if (exclude_this_snapshot && **i == this_snapshot_path) {
2864 if (find_all_sources (**i, result) < 0) {
2873 Session::cleanup_sources (Session::cleanup_report& rep)
2875 vector<Source*> dead_sources;
2876 vector<Playlist*> playlists_tbd;
2877 PathScanner scanner;
2879 vector<space_and_path>::iterator i;
2880 vector<space_and_path>::iterator nexti;
2881 vector<string*>* soundfiles;
2882 vector<string> unused;
2883 set<string> all_sources;
2888 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2890 /* step 1: consider deleting all unused playlists */
2892 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2895 status = AskAboutPlaylistDeletion (*x);
2904 playlists_tbd.push_back (*x);
2908 /* leave it alone */
2913 /* now delete any that were marked for deletion */
2915 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2916 PlaylistList::iterator foo;
2918 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2919 unused_playlists.erase (foo);
2924 /* step 2: clear the undo/redo history for all playlists */
2926 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2927 (*x)->drop_all_states ();
2930 /* step 3: find all un-referenced sources */
2935 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2937 AudioSourceList::iterator tmp;
2942 /* only remove files that are not in use and have some size
2943 to them. otherwise we remove the current "nascent"
2947 if ((*i).second->use_cnt() == 0 && (*i).second->length() > 0) {
2948 dead_sources.push_back (i->second);
2950 /* remove this source from our own list to avoid us
2951 adding it to the list of all sources below
2954 audio_sources.erase (i);
2960 /* Step 4: get rid of all regions in the region list that use any dead sources
2961 in case the sources themselves don't go away (they might be referenced in
2965 for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2967 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2968 AudioRegionList::iterator tmp;
2976 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2977 if (&ar->source (n) == (*i)) {
2978 /* this region is dead */
2987 /* build a list of all the possible sound directories for the session */
2989 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2994 sound_path += (*i).path;
2995 sound_path += sound_dir_name;
2997 if (nexti != session_dirs.end()) {
3004 /* now do the same thing for the files that ended up in the sounds dir(s)
3005 but are not referenced as sources in any snapshot.
3008 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
3010 if (soundfiles == 0) {
3014 /* find all sources, but don't use this snapshot because the
3015 state file on disk still references sources we may have already
3019 find_all_sources_across_snapshots (all_sources, true);
3021 /* add our current source list
3024 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
3025 AudioFileSource* fs;
3027 if ((fs = dynamic_cast<AudioFileSource*> ((*i).second)) != 0) {
3028 all_sources.insert (fs->path());
3032 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
3037 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
3047 unused.push_back (spath);
3051 /* now try to move all unused files into the "dead_sounds" directory(ies) */
3053 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
3054 struct stat statbuf;
3056 rep.paths.push_back (*x);
3057 if (stat ((*x).c_str(), &statbuf) == 0) {
3058 rep.space += statbuf.st_size;
3063 /* don't move the file across filesystems, just
3064 stick it in the `dead_sound_dir_name' directory
3065 on whichever filesystem it was already on.
3068 newpath = Glib::path_get_dirname (*x);
3069 newpath = Glib::path_get_dirname (newpath);
3072 newpath += dead_sound_dir_name;
3074 newpath += Glib::path_get_basename ((*x));
3076 if (access (newpath.c_str(), F_OK) == 0) {
3078 /* the new path already exists, try versioning */
3080 char buf[PATH_MAX+1];
3084 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
3087 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
3088 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
3092 if (version == 999) {
3093 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
3097 newpath = newpath_v;
3102 /* it doesn't exist, or we can't read it or something */
3106 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
3107 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
3108 (*x), newpath, strerror (errno))
3114 /* see if there an easy to find peakfile for this file, and remove it.
3117 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
3118 peakpath += ".peak";
3120 if (access (peakpath.c_str(), W_OK) == 0) {
3121 if (::unlink (peakpath.c_str()) != 0) {
3122 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3123 peakpath, _path, strerror (errno))
3125 /* try to back out */
3126 rename (newpath.c_str(), _path.c_str());
3135 /* dump the history list */
3139 /* save state so we don't end up a session file
3140 referring to non-existent sources.
3146 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3151 Session::cleanup_trash_sources (Session::cleanup_report& rep)
3153 vector<space_and_path>::iterator i;
3154 string dead_sound_dir;
3155 struct dirent* dentry;
3156 struct stat statbuf;
3162 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3164 dead_sound_dir = (*i).path;
3165 dead_sound_dir += dead_sound_dir_name;
3167 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
3171 while ((dentry = readdir (dead)) != 0) {
3173 /* avoid '.' and '..' */
3175 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
3176 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3182 fullpath = dead_sound_dir;
3184 fullpath += dentry->d_name;
3186 if (stat (fullpath.c_str(), &statbuf)) {
3190 if (!S_ISREG (statbuf.st_mode)) {
3194 if (unlink (fullpath.c_str())) {
3195 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3196 fullpath, strerror (errno))
3200 rep.paths.push_back (dentry->d_name);
3201 rep.space += statbuf.st_size;
3212 Session::set_dirty ()
3214 bool was_dirty = dirty();
3216 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3219 DirtyChanged(); /* EMIT SIGNAL */
3225 Session::set_clean ()
3227 bool was_dirty = dirty();
3229 _state_of_the_state = Clean;
3232 DirtyChanged(); /* EMIT SIGNAL */