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/midi_diskstream.h>
63 #include <ardour/utils.h>
64 #include <ardour/audioplaylist.h>
65 #include <ardour/audiofilesource.h>
66 #include <ardour/destructive_filesource.h>
67 #include <ardour/sndfile_helpers.h>
68 #include <ardour/auditioner.h>
69 #include <ardour/export.h>
70 #include <ardour/redirect.h>
71 #include <ardour/send.h>
72 #include <ardour/insert.h>
73 #include <ardour/connection.h>
74 #include <ardour/slave.h>
75 #include <ardour/tempo.h>
76 #include <ardour/audio_track.h>
77 #include <ardour/midi_track.h>
78 #include <ardour/cycle_timer.h>
79 #include <ardour/utils.h>
80 #include <ardour/named_selection.h>
81 #include <ardour/version.h>
82 #include <ardour/location.h>
83 #include <ardour/audioregion.h>
84 #include <ardour/crossfade.h>
85 #include <ardour/control_protocol_manager.h>
91 using namespace ARDOUR;
95 Session::first_stage_init (string fullpath, string snapshot_name)
97 if (fullpath.length() == 0) {
98 throw failed_constructor();
101 char buf[PATH_MAX+1];
102 if (!realpath(fullpath.c_str(), buf) && (errno != ENOENT)) {
103 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
104 throw failed_constructor();
108 if (_path[_path.length()-1] != '/') {
112 /* these two are just provisional settings. set_state()
113 will likely override them.
116 _name = _current_snapshot_name = snapshot_name;
117 setup_raid_path (_path);
119 _current_frame_rate = _engine.frame_rate ();
120 _tempo_map = new TempoMap (_current_frame_rate);
121 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
123 g_atomic_int_set (&processing_prohibited, 0);
126 _transport_speed = 0;
127 _last_transport_speed = 0;
128 transport_sub_state = 0;
129 _transport_frame = 0;
131 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
132 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
133 _end_location_is_free = true;
134 g_atomic_int_set (&_record_status, Disabled);
139 seamless_loop = false;
140 loop_changing = false;
142 crossfades_active = false;
145 _last_roll_location = 0;
146 _last_record_location = 0;
147 pending_locate_frame = 0;
148 pending_locate_roll = false;
149 pending_locate_flush = false;
150 dstream_buffer_size = 0;
152 state_was_pending = false;
154 outbound_mtc_smpte_frame = 0;
155 next_quarter_frame_to_send = -1;
156 current_block_size = 0;
157 _solo_latched = true;
158 _solo_model = InverseMute;
159 solo_update_disabled = false;
160 currently_soloing = false;
161 _have_captured = false;
162 _worst_output_latency = 0;
163 _worst_input_latency = 0;
164 _worst_track_latency = 0;
165 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
168 butler_mixdown_buffer = 0;
169 butler_gain_buffer = 0;
174 post_transport_work = PostTransportWork (0);
175 g_atomic_int_set (&butler_should_do_transport_work, 0);
176 g_atomic_int_set (&butler_active, 0);
177 g_atomic_int_set (&_playback_load, 100);
178 g_atomic_int_set (&_capture_load, 100);
179 g_atomic_int_set (&_playback_load_min, 100);
180 g_atomic_int_set (&_capture_load_min, 100);
181 pending_audition_region = 0;
183 pending_edit_mode = _edit_mode;
187 input_auto_connect = AutoConnectOption (0);
188 output_auto_connect = AutoConnectOption (0);
189 waiting_to_start = false;
191 _gain_automation_buffer = 0;
192 _pan_automation_buffer = 0;
194 pending_abort = false;
195 layer_model = MoveAddHigher;
196 xfade_model = ShortCrossfade;
197 destructive_index = 0;
199 /* allocate conversion buffers */
200 _conversion_buffers[ButlerContext] = new char[AudioDiskstream::disk_io_frames() * 4];
201 _conversion_buffers[TransportContext] = new char[AudioDiskstream::disk_io_frames() * 4];
203 /* default short fade = 15ms */
205 Crossfade::set_short_xfade_length ((jack_nframes_t) floor ((15.0 * frame_rate()) / 1000.0));
206 DestructiveFileSource::setup_standard_crossfades (frame_rate());
208 last_mmc_step.tv_sec = 0;
209 last_mmc_step.tv_usec = 0;
212 preroll.type = AnyTime::Frames;
214 postroll.type = AnyTime::Frames;
217 /* click sounds are unset by default, which causes us to internal
218 waveforms for clicks.
223 click_requested = false;
225 click_emphasis_data = 0;
227 click_emphasis_length = 0;
229 process_function = &Session::process_with_events;
233 _smpte_offset_negative = true;
234 last_smpte_valid = false;
236 last_rr_session_dir = session_dirs.begin();
237 refresh_disk_space ();
239 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
241 /* default configuration */
243 do_not_record_plugins = false;
244 over_length_short = 2;
245 over_length_long = 10;
246 send_midi_timecode = false;
247 send_midi_machine_control = false;
248 shuttle_speed_factor = 1.0;
249 shuttle_speed_threshold = 5;
251 _meter_hold = 100; // XXX unknown units: number of calls to meter::set()
252 _meter_falloff = 1.5f; // XXX unknown units: refresh_rate
258 average_slave_delta = 1800;
259 have_first_delta_accumulator = false;
260 delta_accumulator_cnt = 0;
261 slave_state = Stopped;
263 /* default SMPTE type is 30 FPS, non-drop */
265 set_smpte_type (30.0, false);
267 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
269 /* These are all static "per-class" signals */
271 Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
272 AudioSource::AudioSourceCreated.connect (mem_fun (*this, &Session::add_audio_source));
273 Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
274 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
275 Diskstream::DiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
276 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
278 Controllable::Created.connect (mem_fun (*this, &Session::add_controllable));
279 Controllable::GoingAway.connect (mem_fun (*this, &Session::remove_controllable));
281 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
283 /* stop IO objects from doing stuff until we're ready for them */
285 IO::disable_panners ();
286 IO::disable_ports ();
287 IO::disable_connecting ();
291 Session::second_stage_init (bool new_session)
293 AudioFileSource::set_peak_dir (peak_dir());
296 if (load_state (_current_snapshot_name)) {
299 remove_empty_sounds ();
302 if (start_butler_thread()) {
306 /*if (start_midi_thread ()) {
311 if (set_state (*state_tree->root())) {
316 /* we can't save till after ::when_engine_running() is called,
317 because otherwise we save state with no connections made.
318 therefore, we reset _state_of_the_state because ::set_state()
319 will have cleared it.
321 we also have to include Loading so that any events that get
322 generated between here and the end of ::when_engine_running()
323 will be processed directly rather than queued.
326 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
328 // set_auto_input (true);
329 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
330 _locations.added.connect (mem_fun (this, &Session::locations_added));
331 setup_click_sounds (0);
332 setup_midi_control ();
334 /* Pay attention ... */
336 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
337 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
339 if (_engine.running()) {
340 when_engine_running();
342 first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
345 //send_full_time_code ();
346 _engine.transport_locate (0);
347 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
348 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
350 ControlProtocolManager::instance().set_session (*this);
353 _end_location_is_free = true;
355 _end_location_is_free = false;
362 Session::raid_path () const
366 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
371 return path.substr (0, path.length() - 1); // drop final colon
375 Session::set_raid_path (string path)
377 /* public-access to setup_raid_path() */
379 setup_raid_path (path);
383 Session::setup_raid_path (string path)
385 string::size_type colon;
389 string::size_type len = path.length();
394 if (path.length() == 0) {
398 session_dirs.clear ();
400 for (string::size_type n = 0; n < len; ++n) {
401 if (path[n] == ':') {
408 /* no multiple search path, just one location (common case) */
412 session_dirs.push_back (sp);
419 if (fspath[fspath.length()-1] != '/') {
422 fspath += sound_dir_name;
428 if (fspath[fspath.length()-1] != '/') {
431 fspath += tape_dir_name;
433 AudioFileSource::set_search_path (fspath);
440 while ((colon = remaining.find_first_of (':')) != string::npos) {
443 sp.path = remaining.substr (0, colon);
444 session_dirs.push_back (sp);
446 /* add sounds to file search path */
449 if (fspath[fspath.length()-1] != '/') {
452 fspath += sound_dir_name;
455 /* add tape dir to file search path */
458 if (fspath[fspath.length()-1] != '/') {
461 fspath += tape_dir_name;
464 remaining = remaining.substr (colon+1);
467 if (remaining.length()) {
474 if (fspath[fspath.length()-1] != '/') {
477 fspath += sound_dir_name;
481 if (fspath[fspath.length()-1] != '/') {
484 fspath += tape_dir_name;
486 session_dirs.push_back (sp);
489 /* set the AudioFileSource search path */
491 AudioFileSource::set_search_path (fspath);
493 /* reset the round-robin soundfile path thingie */
495 last_rr_session_dir = session_dirs.begin();
499 Session::create (bool& new_session, string* mix_template, jack_nframes_t initial_length)
503 if (mkdir (_path.c_str(), 0755) < 0) {
504 if (errno == EEXIST) {
507 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
516 if (mkdir (dir.c_str(), 0755) < 0) {
517 if (errno != EEXIST) {
518 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
525 if (mkdir (dir.c_str(), 0755) < 0) {
526 if (errno != EEXIST) {
527 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
534 if (mkdir (dir.c_str(), 0755) < 0) {
535 if (errno != EEXIST) {
536 error << string_compose(_("Session: cannot create session tape dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
541 dir = dead_sound_dir ();
543 if (mkdir (dir.c_str(), 0755) < 0) {
544 if (errno != EEXIST) {
545 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
550 dir = automation_dir ();
552 if (mkdir (dir.c_str(), 0755) < 0) {
553 if (errno != EEXIST) {
554 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
560 /* check new_session so we don't overwrite an existing one */
564 std::string in_path = *mix_template;
566 ifstream in(in_path.c_str());
569 string out_path = _path;
571 out_path += _statefile_suffix;
573 ofstream out(out_path.c_str());
578 // okay, session is set up. Treat like normal saved
579 // session from now on.
585 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
591 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
598 warning << _("Session already exists. Not overwriting") << endmsg;
605 /* set initial start + end point */
607 start_location->set_end (0);
608 _locations.add (start_location);
610 end_location->set_end (initial_length);
611 _locations.add (end_location);
613 _state_of_the_state = Clean;
615 if (save_state (_current_snapshot_name)) {
624 Session::load_diskstreams (const XMLNode& node)
627 XMLNodeConstIterator citer;
629 clist = node.children();
631 for (citer = clist.begin(); citer != clist.end(); ++citer) {
632 Diskstream* dstream = NULL;
635 if ((*citer)->name() == "AudioDiskstream") {
636 dstream = new AudioDiskstream (*this, **citer);
637 /* added automatically by DiskstreamCreated handler */
639 assert((*citer)->name() == "MidiDiskstream");
640 dstream = new MidiDiskstream (*this, **citer);
644 catch (failed_constructor& err) {
645 error << _("Session: could not load diskstream via XML state") << endmsg;
654 Session::remove_pending_capture_state ()
659 xml_path += _current_snapshot_name;
660 xml_path += _pending_suffix;
662 unlink (xml_path.c_str());
666 Session::save_state (string snapshot_name, bool pending)
672 if (_state_of_the_state & CannotSave) {
676 tree.set_root (&get_state());
678 if (snapshot_name.empty()) {
679 snapshot_name = _current_snapshot_name;
685 xml_path += snapshot_name;
686 xml_path += _statefile_suffix;
690 // Make backup of state file
692 if ((access (xml_path.c_str(), F_OK) == 0) &&
693 (rename(xml_path.c_str(), bak_path.c_str()))) {
694 error << _("could not backup old state file, current state not saved.") << endmsg;
701 xml_path += snapshot_name;
702 xml_path += _pending_suffix;
706 if (!tree.write (xml_path)) {
707 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
709 /* don't leave a corrupt file lying around if it is
713 if (unlink (xml_path.c_str())) {
714 error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
717 if (rename (bak_path.c_str(), xml_path.c_str())) {
718 error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
728 bool was_dirty = dirty();
730 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
733 DirtyChanged (); /* EMIT SIGNAL */
736 StateSaved (snapshot_name); /* EMIT SIGNAL */
743 Session::restore_state (string snapshot_name)
745 if (load_state (snapshot_name) == 0) {
746 set_state (*state_tree->root());
753 Session::load_state (string snapshot_name)
762 state_was_pending = false;
764 /* check for leftover pending state from a crashed capture attempt */
767 xmlpath += snapshot_name;
768 xmlpath += _pending_suffix;
770 if (!access (xmlpath.c_str(), F_OK)) {
772 /* there is pending state from a crashed capture attempt */
774 if (AskAboutPendingState()) {
775 state_was_pending = true;
779 if (!state_was_pending) {
782 xmlpath += snapshot_name;
783 xmlpath += _statefile_suffix;
786 if (access (xmlpath.c_str(), F_OK)) {
787 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
791 state_tree = new XMLTree;
795 if (state_tree->read (xmlpath)) {
798 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
807 Session::load_options (const XMLNode& node)
811 bool have_fade_msecs = false;
812 bool have_fade_steepness = false;
813 float fade_msecs = 0;
814 float fade_steepness = 0;
815 SlaveSource slave_src = None;
817 LocaleGuard lg (X_("POSIX"));
819 if ((child = find_named_node (node, "input-auto-connect")) != 0) {
820 if ((prop = child->property ("val")) != 0) {
821 sscanf (prop->value().c_str(), "%x", &x);
822 input_auto_connect = AutoConnectOption (x);
826 if ((child = find_named_node (node, "output-auto-connect")) != 0) {
827 if ((prop = child->property ("val")) != 0) {
828 sscanf (prop->value().c_str(), "%x", &x);
829 output_auto_connect = AutoConnectOption (x);
833 if ((child = find_named_node (node, "slave")) != 0) {
834 if ((prop = child->property ("type")) != 0) {
835 if (prop->value() == "none") {
837 } else if (prop->value() == "mtc") {
839 } else if (prop->value() == "jack") {
842 set_slave_source (slave_src, 0);
846 /* we cannot set edit mode if we are loading a session,
847 because it might destroy the playlist's positioning
850 if ((child = find_named_node (node, "edit-mode")) != 0) {
851 if ((prop = child->property ("val")) != 0) {
852 if (prop->value() == "slide") {
853 pending_edit_mode = Slide;
854 } else if (prop->value() == "splice") {
855 pending_edit_mode = Splice;
860 if ((child = find_named_node (node, "send-midi-timecode")) != 0) {
861 if ((prop = child->property ("val")) != 0) {
862 bool x = (prop->value() == "yes");
863 send_mtc = !x; /* force change in value */
867 if ((child = find_named_node (node, "send-midi-machine-control")) != 0) {
868 if ((prop = child->property ("val")) != 0) {
869 bool x = (prop->value() == "yes");
870 send_mmc = !x; /* force change in value */
871 set_send_mmc (prop->value() == "yes");
874 if ((child = find_named_node (node, "max-level")) != 0) {
875 if ((prop = child->property ("val")) != 0) {
876 max_level = atoi (prop->value().c_str());
879 if ((child = find_named_node (node, "min-level")) != 0) {
880 if ((prop = child->property ("val")) != 0) {
881 min_level = atoi (prop->value().c_str());
884 if ((child = find_named_node (node, "meter-hold")) != 0) {
885 if ((prop = child->property ("val")) != 0) {
886 _meter_hold = atof (prop->value().c_str());
889 if ((child = find_named_node (node, "meter-falloff")) != 0) {
890 if ((prop = child->property ("val")) != 0) {
891 _meter_falloff = atof (prop->value().c_str());
894 if ((child = find_named_node (node, "long-over-length")) != 0) {
895 if ((prop = child->property ("val")) != 0) {
896 over_length_long = atoi (prop->value().c_str());
899 if ((child = find_named_node (node, "short-over-length")) != 0) {
900 if ((prop = child->property ("val")) != 0) {
901 over_length_short = atoi (prop->value().c_str());
904 if ((child = find_named_node (node, "shuttle-speed-factor")) != 0) {
905 if ((prop = child->property ("val")) != 0) {
906 shuttle_speed_factor = atof (prop->value().c_str());
909 if ((child = find_named_node (node, "shuttle-speed-threshold")) != 0) {
910 if ((prop = child->property ("val")) != 0) {
911 shuttle_speed_threshold = atof (prop->value().c_str());
914 if ((child = find_named_node (node, "rf-speed")) != 0) {
915 if ((prop = child->property ("val")) != 0) {
916 rf_speed = atof (prop->value().c_str());
919 if ((child = find_named_node (node, "smpte-frames-per-second")) != 0) {
920 if ((prop = child->property ("val")) != 0) {
921 set_smpte_type( atof (prop->value().c_str()), smpte_drop_frames );
924 if ((child = find_named_node (node, "smpte-drop-frames")) != 0) {
925 if ((prop = child->property ("val")) != 0) {
926 set_smpte_type( smpte_frames_per_second, (prop->value() == "yes") );
929 if ((child = find_named_node (node, "smpte-offset")) != 0) {
930 if ((prop = child->property ("val")) != 0) {
931 set_smpte_offset( atoi (prop->value().c_str()) );
934 if ((child = find_named_node (node, "smpte-offset-negative")) != 0) {
935 if ((prop = child->property ("val")) != 0) {
936 set_smpte_offset_negative( (prop->value() == "yes") );
939 if ((child = find_named_node (node, "click-sound")) != 0) {
940 if ((prop = child->property ("val")) != 0) {
941 click_sound = prop->value();
944 if ((child = find_named_node (node, "click-emphasis-sound")) != 0) {
945 if ((prop = child->property ("val")) != 0) {
946 click_emphasis_sound = prop->value();
950 if ((child = find_named_node (node, "solo-model")) != 0) {
951 if ((prop = child->property ("val")) != 0) {
952 if (prop->value() == "SoloBus")
953 _solo_model = SoloBus;
955 _solo_model = InverseMute;
959 /* BOOLEAN OPTIONS */
961 if ((child = find_named_node (node, "auto-play")) != 0) {
962 if ((prop = child->property ("val")) != 0) {
963 set_auto_play (prop->value() == "yes");
966 if ((child = find_named_node (node, "auto-input")) != 0) {
967 if ((prop = child->property ("val")) != 0) {
968 set_auto_input (prop->value() == "yes");
971 if ((child = find_named_node (node, "seamless-loop")) != 0) {
972 if ((prop = child->property ("val")) != 0) {
973 set_seamless_loop (prop->value() == "yes");
976 if ((child = find_named_node (node, "punch-in")) != 0) {
977 if ((prop = child->property ("val")) != 0) {
978 set_punch_in (prop->value() == "yes");
981 if ((child = find_named_node (node, "punch-out")) != 0) {
982 if ((prop = child->property ("val")) != 0) {
983 set_punch_out (prop->value() == "yes");
986 if ((child = find_named_node (node, "auto-return")) != 0) {
987 if ((prop = child->property ("val")) != 0) {
988 set_auto_return (prop->value() == "yes");
991 if ((child = find_named_node (node, "send-mtc")) != 0) {
992 if ((prop = child->property ("val")) != 0) {
993 set_send_mtc (prop->value() == "yes");
996 if ((child = find_named_node (node, "mmc-control")) != 0) {
997 if ((prop = child->property ("val")) != 0) {
998 set_mmc_control (prop->value() == "yes");
1001 if ((child = find_named_node (node, "midi-control")) != 0) {
1002 if ((prop = child->property ("val")) != 0) {
1003 set_midi_control (prop->value() == "yes");
1006 if ((child = find_named_node (node, "midi-feedback")) != 0) {
1007 if ((prop = child->property ("val")) != 0) {
1008 set_midi_feedback (prop->value() == "yes");
1011 // Legacy support for <recording-plugins>
1012 if ((child = find_named_node (node, "recording-plugins")) != 0) {
1013 if ((prop = child->property ("val")) != 0) {
1014 set_do_not_record_plugins (prop->value() == "no");
1017 if ((child = find_named_node (node, "do-not-record-plugins")) != 0) {
1018 if ((prop = child->property ("val")) != 0) {
1019 set_do_not_record_plugins (prop->value() == "yes");
1022 if ((child = find_named_node (node, "crossfades-active")) != 0) {
1023 if ((prop = child->property ("val")) != 0) {
1024 set_crossfades_active (prop->value() == "yes");
1027 if ((child = find_named_node (node, "audible-click")) != 0) {
1028 if ((prop = child->property ("val")) != 0) {
1029 set_clicking (prop->value() == "yes");
1033 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
1034 if ((prop = child->property ("val")) != 0) {
1035 _end_location_is_free = (prop->value() == "yes");
1039 if ((child = find_named_node (node, "layer-model")) != 0) {
1040 if ((prop = child->property ("val")) != 0) {
1041 if (prop->value() == X_("LaterHigher")) {
1042 set_layer_model (LaterHigher);
1043 } else if (prop->value() == X_("AddHigher")) {
1044 set_layer_model (AddHigher);
1046 set_layer_model (MoveAddHigher);
1051 if ((child = find_named_node (node, "xfade-model")) != 0) {
1052 if ((prop = child->property ("val")) != 0) {
1053 if (prop->value() == X_("Short")) {
1054 set_xfade_model (ShortCrossfade);
1056 set_xfade_model (FullCrossfade);
1061 if ((child = find_named_node (node, "short-xfade-length")) != 0) {
1062 if ((prop = child->property ("val")) != 0) {
1063 /* value is stored as a fractional seconds */
1064 float secs = atof (prop->value().c_str());
1065 Crossfade::set_short_xfade_length ((jack_nframes_t) floor (secs * frame_rate()));
1069 if ((child = find_named_node (node, "full-xfades-unmuted")) != 0) {
1070 if ((prop = child->property ("val")) != 0) {
1071 crossfades_active = (prop->value() == "yes");
1077 if ((child = find_named_node (node, "default-fade-steepness")) != 0) {
1078 if ((prop = child->property ("val")) != 0) {
1079 fade_steepness = atof (prop->value().c_str());
1080 have_fade_steepness = true;
1083 if ((child = find_named_node (node, "default-fade-msec")) != 0) {
1084 if ((prop = child->property ("val")) != 0) {
1085 fade_msecs = atof (prop->value().c_str());
1086 have_fade_msecs = true;
1090 if (have_fade_steepness || have_fade_msecs) {
1091 // set_default_fade (fade_steepness, fade_msecs);
1098 Session::get_options () const
1103 LocaleGuard lg (X_("POSIX"));
1105 opthead = new XMLNode ("Options");
1107 SlaveSource src = slave_source ();
1111 src_string = "none";
1117 src_string = "jack";
1120 child = opthead->add_child ("slave");
1121 child->add_property ("type", src_string);
1123 child = opthead->add_child ("send-midi-timecode");
1124 child->add_property ("val", send_midi_timecode?"yes":"no");
1126 child = opthead->add_child ("send-midi-machine-control");
1127 child->add_property ("val", send_midi_machine_control?"yes":"no");
1129 snprintf (buf, sizeof(buf)-1, "%x", (int) input_auto_connect);
1130 child = opthead->add_child ("input-auto-connect");
1131 child->add_property ("val", buf);
1133 snprintf (buf, sizeof(buf)-1, "%x", (int) output_auto_connect);
1134 child = opthead->add_child ("output-auto-connect");
1135 child->add_property ("val", buf);
1137 snprintf (buf, sizeof(buf)-1, "%d", max_level);
1138 child = opthead->add_child ("max-level");
1139 child->add_property ("val", buf);
1141 snprintf (buf, sizeof(buf)-1, "%d", min_level);
1142 child = opthead->add_child ("min-level");
1143 child->add_property ("val", buf);
1145 snprintf (buf, sizeof(buf)-1, "%f", _meter_hold);
1146 child = opthead->add_child ("meter-hold");
1147 child->add_property ("val", buf);
1149 snprintf (buf, sizeof(buf)-1, "%f", _meter_falloff);
1150 child = opthead->add_child ("meter-falloff");
1151 child->add_property ("val", buf);
1153 snprintf (buf, sizeof(buf)-1, "%u", over_length_long);
1154 child = opthead->add_child ("long-over-length");
1155 child->add_property ("val", buf);
1157 snprintf (buf, sizeof(buf)-1, "%u", over_length_short);
1158 child = opthead->add_child ("short-over-length");
1159 child->add_property ("val", buf);
1161 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_factor);
1162 child = opthead->add_child ("shuttle-speed-factor");
1163 child->add_property ("val", buf);
1165 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_threshold);
1166 child = opthead->add_child ("shuttle-speed-threshold");
1167 child->add_property ("val", buf);
1169 snprintf (buf, sizeof(buf)-1, "%f", rf_speed);
1170 child = opthead->add_child ("rf-speed");
1171 child->add_property ("val", buf);
1173 snprintf (buf, sizeof(buf)-1, "%.2f", smpte_frames_per_second);
1174 child = opthead->add_child ("smpte-frames-per-second");
1175 child->add_property ("val", buf);
1177 child = opthead->add_child ("smpte-drop-frames");
1178 child->add_property ("val", smpte_drop_frames ? "yes" : "no");
1180 snprintf (buf, sizeof(buf)-1, "%u", smpte_offset ());
1181 child = opthead->add_child ("smpte-offset");
1182 child->add_property ("val", buf);
1184 child = opthead->add_child ("smpte-offset-negative");
1185 child->add_property ("val", smpte_offset_negative () ? "yes" : "no");
1187 child = opthead->add_child ("edit-mode");
1188 switch (_edit_mode) {
1190 child->add_property ("val", "splice");
1194 child->add_property ("val", "slide");
1198 child = opthead->add_child ("auto-play");
1199 child->add_property ("val", get_auto_play () ? "yes" : "no");
1200 child = opthead->add_child ("auto-input");
1201 child->add_property ("val", get_auto_input () ? "yes" : "no");
1202 child = opthead->add_child ("seamless-loop");
1203 child->add_property ("val", get_seamless_loop () ? "yes" : "no");
1204 child = opthead->add_child ("punch-in");
1205 child->add_property ("val", get_punch_in () ? "yes" : "no");
1206 child = opthead->add_child ("punch-out");
1207 child->add_property ("val", get_punch_out () ? "yes" : "no");
1208 child = opthead->add_child ("all-safe");
1209 child->add_property ("val", get_all_safe () ? "yes" : "no");
1210 child = opthead->add_child ("auto-return");
1211 child->add_property ("val", get_auto_return () ? "yes" : "no");
1212 child = opthead->add_child ("mmc-control");
1213 child->add_property ("val", get_mmc_control () ? "yes" : "no");
1214 child = opthead->add_child ("midi-control");
1215 child->add_property ("val", get_midi_control () ? "yes" : "no");
1216 child = opthead->add_child ("midi-feedback");
1217 child->add_property ("val", get_midi_feedback () ? "yes" : "no");
1218 child = opthead->add_child ("do-not-record-plugins");
1219 child->add_property ("val", get_do_not_record_plugins () ? "yes" : "no");
1220 child = opthead->add_child ("auto-crossfade");
1221 child->add_property ("val", get_crossfades_active () ? "yes" : "no");
1222 child = opthead->add_child ("audible-click");
1223 child->add_property ("val", get_clicking () ? "yes" : "no");
1224 child = opthead->add_child ("end-marker-is-free");
1225 child->add_property ("val", _end_location_is_free ? "yes" : "no");
1227 if (click_sound.length()) {
1228 child = opthead->add_child ("click-sound");
1229 child->add_property ("val", click_sound);
1232 if (click_emphasis_sound.length()) {
1233 child = opthead->add_child ("click-emphasis-sound");
1234 child->add_property ("val", click_emphasis_sound);
1237 child = opthead->add_child ("solo-model");
1238 child->add_property ("val", _solo_model == SoloBus ? "SoloBus" : "InverseMute");
1240 child = opthead->add_child ("layer-model");
1241 switch (layer_model) {
1243 child->add_property ("val", X_("LaterHigher"));
1246 child->add_property ("val", X_("MoveAddHigher"));
1249 child->add_property ("val", X_("AddHigher"));
1253 child = opthead->add_child ("xfade-model");
1254 switch (xfade_model) {
1256 child->add_property ("val", X_("Full"));
1258 case ShortCrossfade:
1259 child->add_property ("val", X_("Short"));
1262 child = opthead->add_child ("short-xfade-length");
1263 /* store as fractions of a second */
1264 snprintf (buf, sizeof(buf)-1, "%f",
1265 (float) Crossfade::short_xfade_length() / frame_rate());
1266 child->add_property ("val", buf);
1268 child = opthead->add_child ("full-xfades-unmuted");
1269 child->add_property ("val", crossfades_active ? "yes" : "no");
1275 Session::get_state()
1281 Session::get_template()
1283 /* if we don't disable rec-enable, diskstreams
1284 will believe they need to store their capture
1285 sources in their state node.
1288 disable_record (false);
1290 return state(false);
1294 Session::state(bool full_state)
1296 XMLNode* node = new XMLNode("Session");
1299 // store libardour version, just in case
1301 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
1302 libardour_major_version, libardour_minor_version, libardour_micro_version);
1303 node->add_property("version", string(buf));
1305 /* store configuration settings */
1309 /* store the name */
1310 node->add_property ("name", _name);
1312 if (session_dirs.size() > 1) {
1316 vector<space_and_path>::iterator i = session_dirs.begin();
1317 vector<space_and_path>::iterator next;
1319 ++i; /* skip the first one */
1323 while (i != session_dirs.end()) {
1327 if (next != session_dirs.end()) {
1337 child = node->add_child ("Path");
1338 child->add_content (p);
1342 /* save the ID counter */
1344 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1345 node->add_property ("id-counter", buf);
1347 /* various options */
1349 node->add_child_nocopy (get_options());
1351 child = node->add_child ("Sources");
1354 Glib::Mutex::Lock sl (audio_source_lock);
1356 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
1358 /* Don't save information about AudioFileSources that are empty */
1360 AudioFileSource* fs;
1362 if ((fs = dynamic_cast<AudioFileSource*> (siter->second)) != 0) {
1363 DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
1365 /* destructive file sources are OK if they are empty, because
1366 we will re-use them every time.
1370 if (fs->length() == 0) {
1376 child->add_child_nocopy (siter->second->get_state());
1380 child = node->add_child ("Regions");
1383 Glib::Mutex::Lock rl (region_lock);
1385 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1387 /* only store regions not attached to playlists */
1389 if (i->second->playlist() == 0) {
1390 child->add_child_nocopy (i->second->state (true));
1395 child = node->add_child ("DiskStreams");
1398 Glib::RWLock::ReaderLock dl (diskstream_lock);
1399 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1400 if (!(*i)->hidden()) {
1401 child->add_child_nocopy ((*i)->get_state());
1406 node->add_child_nocopy (_locations.get_state());
1408 child = node->add_child ("Connections");
1410 Glib::Mutex::Lock lm (connection_lock);
1411 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1412 if (!(*i)->system_dependent()) {
1413 child->add_child_nocopy ((*i)->get_state());
1418 child = node->add_child ("Routes");
1420 Glib::RWLock::ReaderLock lm (route_lock);
1422 RoutePublicOrderSorter cmp;
1423 RouteList public_order(routes);
1424 public_order.sort (cmp);
1426 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1427 if (!(*i)->hidden()) {
1429 child->add_child_nocopy ((*i)->get_state());
1431 child->add_child_nocopy ((*i)->get_template());
1438 child = node->add_child ("EditGroups");
1439 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1440 child->add_child_nocopy ((*i)->get_state());
1443 child = node->add_child ("MixGroups");
1444 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1445 child->add_child_nocopy ((*i)->get_state());
1448 child = node->add_child ("Playlists");
1449 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1450 if (!(*i)->hidden()) {
1451 if (!(*i)->empty()) {
1453 child->add_child_nocopy ((*i)->get_state());
1455 child->add_child_nocopy ((*i)->get_template());
1461 child = node->add_child ("UnusedPlaylists");
1462 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1463 if (!(*i)->hidden()) {
1464 if (!(*i)->empty()) {
1466 child->add_child_nocopy ((*i)->get_state());
1468 child->add_child_nocopy ((*i)->get_template());
1476 child = node->add_child ("Click");
1477 child->add_child_nocopy (_click_io->state (full_state));
1481 child = node->add_child ("NamedSelections");
1482 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1484 child->add_child_nocopy ((*i)->get_state());
1489 node->add_child_nocopy (_tempo_map->get_state());
1492 node->add_child_copy (*_extra_xml);
1499 Session::set_state (const XMLNode& node)
1503 const XMLProperty* prop;
1506 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1508 if (node.name() != X_("Session")){
1509 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1513 StateManager::prohibit_save ();
1515 if ((prop = node.property ("name")) != 0) {
1516 _name = prop->value ();
1519 if ((prop = node.property (X_("id-counter"))) != 0) {
1521 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1522 ID::init_counter (x);
1524 /* old sessions used a timebased counter, so fake
1525 the startup ID counter based on a standard
1530 ID::init_counter (now);
1534 IO::disable_ports ();
1535 IO::disable_connecting ();
1537 /* Object loading order:
1554 if (use_config_midi_ports ()) {
1557 if ((child = find_named_node (node, "Path")) != 0) {
1558 /* XXX this XML content stuff horrible API design */
1559 string raid_path = _path + ':' + child->children().front()->content();
1560 setup_raid_path (raid_path);
1562 /* the path is already set */
1565 if ((child = find_named_node (node, "extra")) != 0) {
1566 _extra_xml = new XMLNode (*child);
1569 if ((child = find_named_node (node, "Options")) == 0) {
1570 error << _("Session: XML state has no options section") << endmsg;
1571 } else if (load_options (*child)) {
1574 if ((child = find_named_node (node, "Sources")) == 0) {
1575 error << _("Session: XML state has no sources section") << endmsg;
1577 } else if (load_sources (*child)) {
1581 if ((child = find_named_node (node, "Regions")) == 0) {
1582 error << _("Session: XML state has no Regions section") << endmsg;
1584 } else if (load_regions (*child)) {
1588 if ((child = find_named_node (node, "Playlists")) == 0) {
1589 error << _("Session: XML state has no playlists section") << endmsg;
1591 } else if (load_playlists (*child)) {
1595 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1597 } else if (load_unused_playlists (*child)) {
1601 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1602 if (load_named_selections (*child)) {
1607 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1608 error << _("Session: XML state has no diskstreams section") << endmsg;
1610 } else if (load_diskstreams (*child)) {
1614 if ((child = find_named_node (node, "Connections")) == 0) {
1615 error << _("Session: XML state has no connections section") << endmsg;
1617 } else if (load_connections (*child)) {
1621 if ((child = find_named_node (node, "Locations")) == 0) {
1622 error << _("Session: XML state has no locations section") << endmsg;
1624 } else if (_locations.set_state (*child)) {
1630 if ((location = _locations.auto_loop_location()) != 0) {
1631 set_auto_loop_location (location);
1634 if ((location = _locations.auto_punch_location()) != 0) {
1635 set_auto_punch_location (location);
1638 if ((location = _locations.end_location()) == 0) {
1639 _locations.add (end_location);
1641 delete end_location;
1642 end_location = location;
1645 if ((location = _locations.start_location()) == 0) {
1646 _locations.add (start_location);
1648 delete start_location;
1649 start_location = location;
1652 _locations.save_state (_("initial state"));
1654 if ((child = find_named_node (node, "EditGroups")) == 0) {
1655 error << _("Session: XML state has no edit groups section") << endmsg;
1657 } else if (load_edit_groups (*child)) {
1661 if ((child = find_named_node (node, "MixGroups")) == 0) {
1662 error << _("Session: XML state has no mix groups section") << endmsg;
1664 } else if (load_mix_groups (*child)) {
1668 if ((child = find_named_node (node, "TempoMap")) == 0) {
1669 error << _("Session: XML state has no Tempo Map section") << endmsg;
1671 } else if (_tempo_map->set_state (*child)) {
1675 if ((child = find_named_node (node, "Routes")) == 0) {
1676 error << _("Session: XML state has no routes section") << endmsg;
1678 } else if (load_routes (*child)) {
1682 if ((child = find_named_node (node, "Click")) == 0) {
1683 warning << _("Session: XML state has no click section") << endmsg;
1684 } else if (_click_io) {
1685 _click_io->set_state (*child);
1688 /* OK, now we can set edit mode */
1690 set_edit_mode (pending_edit_mode);
1692 /* here beginneth the second phase ... */
1694 StateReady (); /* EMIT SIGNAL */
1696 _state_of_the_state = Clean;
1698 StateManager::allow_save (_("initial state"), true);
1700 if (state_was_pending) {
1701 save_state (_current_snapshot_name);
1702 remove_pending_capture_state ();
1703 state_was_pending = false;
1709 /* we failed, re-enable state saving but don't actually save internal state */
1710 StateManager::allow_save (X_("ignored"), false);
1715 Session::load_routes (const XMLNode& node)
1718 XMLNodeConstIterator niter;
1721 nlist = node.children();
1725 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1727 if ((route = XMLRouteFactory (**niter)) == 0) {
1728 error << _("Session: cannot create Route from XML description.") << endmsg;
1739 Session::XMLRouteFactory (const XMLNode& node)
1741 if (node.name() != "Route") {
1745 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1747 Buffer::Type type = Buffer::AUDIO;
1748 const XMLProperty* prop = node.property("default-type");
1750 type = Buffer::type_from_string(prop->value());
1752 assert(type != Buffer::NIL);
1754 if (has_diskstream) {
1755 if (type == Buffer::AUDIO)
1756 return new AudioTrack (*this, node);
1758 return new MidiTrack (*this, node);
1760 return new Route (*this, node);
1765 Session::load_regions (const XMLNode& node)
1768 XMLNodeConstIterator niter;
1769 AudioRegion* region;
1771 nlist = node.children();
1775 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1776 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1777 error << _("Session: cannot create Region from XML description.") << endmsg;
1784 Session::XMLRegionFactory (const XMLNode& node, bool full)
1786 const XMLProperty* prop;
1789 AudioRegion::SourceList sources;
1790 uint32_t nchans = 1;
1793 if (node.name() != X_("Region")) {
1797 if ((prop = node.property (X_("channels"))) != 0) {
1798 nchans = atoi (prop->value().c_str());
1802 if ((prop = node.property (X_("source-0"))) == 0) {
1803 if ((prop = node.property ("source")) == 0) {
1804 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1809 PBD::ID s_id (prop->value());
1811 if ((source = source_by_id (s_id)) == 0) {
1812 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1816 as = dynamic_cast<AudioSource*>(source);
1818 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1822 sources.push_back (as);
1824 /* pickup other channels */
1826 for (uint32_t n=1; n < nchans; ++n) {
1827 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1828 if ((prop = node.property (buf)) != 0) {
1830 PBD::ID id2 (prop->value());
1832 if ((source = source_by_id (id2)) == 0) {
1833 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1837 as = dynamic_cast<AudioSource*>(source);
1839 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1842 sources.push_back (as);
1847 return new AudioRegion (sources, node);
1850 catch (failed_constructor& err) {
1856 Session::get_sources_as_xml ()
1859 XMLNode* node = new XMLNode (X_("Sources"));
1860 Glib::Mutex::Lock lm (audio_source_lock);
1862 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1863 node->add_child_nocopy (i->second->get_state());
1866 /* XXX get MIDI and other sources here */
1872 Session::path_from_region_name (string name, string identifier)
1874 char buf[PATH_MAX+1];
1876 string dir = discover_best_sound_dir ();
1878 for (n = 0; n < 999999; ++n) {
1879 if (identifier.length()) {
1880 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1881 identifier.c_str(), n);
1883 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1885 if (access (buf, F_OK) != 0) {
1895 Session::load_sources (const XMLNode& node)
1898 XMLNodeConstIterator niter;
1901 nlist = node.children();
1905 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1907 if ((source = XMLSourceFactory (**niter)) == 0) {
1908 error << _("Session: cannot create Source from XML description.") << endmsg;
1916 Session::XMLSourceFactory (const XMLNode& node)
1920 if (node.name() != "Source") {
1925 src = AudioFileSource::create (node);
1928 catch (failed_constructor& err) {
1929 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1937 Session::save_template (string template_name)
1940 string xml_path, bak_path, template_path;
1942 if (_state_of_the_state & CannotSave) {
1947 string dir = template_dir();
1949 if ((dp = opendir (dir.c_str()))) {
1952 if (mkdir (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)<0) {
1953 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1958 tree.set_root (&get_template());
1961 xml_path += template_name;
1962 xml_path += _template_suffix;
1964 ifstream in(xml_path.c_str());
1967 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1973 if (!tree.write (xml_path)) {
1974 error << _("mix template not saved") << endmsg;
1982 Session::rename_template (string old_name, string new_name)
1984 string old_path = template_dir() + old_name + _template_suffix;
1985 string new_path = template_dir() + new_name + _template_suffix;
1987 return rename (old_path.c_str(), new_path.c_str());
1991 Session::delete_template (string name)
1993 string template_path = template_dir();
1994 template_path += name;
1995 template_path += _template_suffix;
1997 return remove (template_path.c_str());
2001 Session::refresh_disk_space ()
2004 struct statfs statfsbuf;
2005 vector<space_and_path>::iterator i;
2006 Glib::Mutex::Lock lm (space_lock);
2009 /* get freespace on every FS that is part of the session path */
2011 _total_free_4k_blocks = 0;
2013 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2014 statfs ((*i).path.c_str(), &statfsbuf);
2016 scale = statfsbuf.f_bsize/4096.0;
2018 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2019 _total_free_4k_blocks += (*i).blocks;
2025 Session::ensure_sound_dir (string path, string& result)
2030 /* Ensure that the parent directory exists */
2032 if (mkdir (path.c_str(), 0775)) {
2033 if (errno != EEXIST) {
2034 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
2039 /* Ensure that the sounds directory exists */
2043 result += sound_dir_name;
2045 if (mkdir (result.c_str(), 0775)) {
2046 if (errno != EEXIST) {
2047 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
2054 dead += dead_sound_dir_name;
2056 if (mkdir (dead.c_str(), 0775)) {
2057 if (errno != EEXIST) {
2058 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
2065 peak += peak_dir_name;
2067 if (mkdir (peak.c_str(), 0775)) {
2068 if (errno != EEXIST) {
2069 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
2074 /* callers expect this to be terminated ... */
2081 Session::discover_best_sound_dir (bool destructive)
2083 vector<space_and_path>::iterator i;
2086 /* destructive files all go into the same place */
2092 /* handle common case without system calls */
2094 if (session_dirs.size() == 1) {
2098 /* OK, here's the algorithm we're following here:
2100 We want to select which directory to use for
2101 the next file source to be created. Ideally,
2102 we'd like to use a round-robin process so as to
2103 get maximum performance benefits from splitting
2104 the files across multiple disks.
2106 However, in situations without much diskspace, an
2107 RR approach may end up filling up a filesystem
2108 with new files while others still have space.
2109 Its therefore important to pay some attention to
2110 the freespace in the filesystem holding each
2111 directory as well. However, if we did that by
2112 itself, we'd keep creating new files in the file
2113 system with the most space until it was as full
2114 as all others, thus negating any performance
2115 benefits of this RAID-1 like approach.
2117 So, we use a user-configurable space threshold. If
2118 there are at least 2 filesystems with more than this
2119 much space available, we use RR selection between them.
2120 If not, then we pick the filesystem with the most space.
2122 This gets a good balance between the two
2126 refresh_disk_space ();
2128 int free_enough = 0;
2130 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2131 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2136 if (free_enough >= 2) {
2138 bool found_it = false;
2140 /* use RR selection process, ensuring that the one
2144 i = last_rr_session_dir;
2147 if (++i == session_dirs.end()) {
2148 i = session_dirs.begin();
2151 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2152 if (ensure_sound_dir ((*i).path, result) == 0) {
2153 last_rr_session_dir = i;
2159 } while (i != last_rr_session_dir);
2162 result = sound_dir();
2167 /* pick FS with the most freespace (and that
2168 seems to actually work ...)
2171 vector<space_and_path> sorted;
2172 space_and_path_ascending_cmp cmp;
2174 sorted = session_dirs;
2175 sort (sorted.begin(), sorted.end(), cmp);
2177 for (i = sorted.begin(); i != sorted.end(); ++i) {
2178 if (ensure_sound_dir ((*i).path, result) == 0) {
2179 last_rr_session_dir = i;
2184 /* if the above fails, fall back to the most simplistic solution */
2186 if (i == sorted.end()) {
2195 Session::load_playlists (const XMLNode& node)
2198 XMLNodeConstIterator niter;
2201 nlist = node.children();
2205 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2207 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2208 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2216 Session::load_unused_playlists (const XMLNode& node)
2219 XMLNodeConstIterator niter;
2222 nlist = node.children();
2226 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2228 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2229 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2233 // now manually untrack it
2235 track_playlist (playlist, false);
2243 Session::XMLPlaylistFactory (const XMLNode& node)
2246 return new AudioPlaylist (*this, node);
2249 catch (failed_constructor& err) {
2255 Session::load_named_selections (const XMLNode& node)
2258 XMLNodeConstIterator niter;
2261 nlist = node.children();
2265 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2267 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2268 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2276 Session::XMLNamedSelectionFactory (const XMLNode& node)
2279 return new NamedSelection (*this, node);
2282 catch (failed_constructor& err) {
2288 Session::dead_sound_dir () const
2291 res += dead_sound_dir_name;
2297 Session::sound_dir () const
2300 res += sound_dir_name;
2306 Session::tape_dir () const
2309 res += tape_dir_name;
2315 Session::peak_dir () const
2318 res += peak_dir_name;
2324 Session::automation_dir () const
2327 res += "automation/";
2332 Session::template_dir ()
2334 string path = get_user_ardour_path();
2335 path += "templates/";
2341 Session::suffixed_search_path (string suffix, bool data)
2345 path += get_user_ardour_path();
2346 if (path[path.length()-1] != ':') {
2351 path += get_system_data_path();
2353 path += get_system_module_path();
2356 vector<string> split_path;
2358 split (path, split_path, ':');
2361 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2366 if (distance (i, split_path.end()) != 1) {
2375 Session::template_path ()
2377 return suffixed_search_path (X_("templates"), true);
2381 Session::control_protocol_path ()
2383 return suffixed_search_path (X_("surfaces"), false);
2387 Session::load_connections (const XMLNode& node)
2389 XMLNodeList nlist = node.children();
2390 XMLNodeConstIterator niter;
2394 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2395 if ((*niter)->name() == "InputConnection") {
2396 add_connection (new ARDOUR::InputConnection (**niter));
2397 } else if ((*niter)->name() == "OutputConnection") {
2398 add_connection (new ARDOUR::OutputConnection (**niter));
2400 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2409 Session::load_edit_groups (const XMLNode& node)
2411 return load_route_groups (node, true);
2415 Session::load_mix_groups (const XMLNode& node)
2417 return load_route_groups (node, false);
2421 Session::load_route_groups (const XMLNode& node, bool edit)
2423 XMLNodeList nlist = node.children();
2424 XMLNodeConstIterator niter;
2429 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2430 if ((*niter)->name() == "RouteGroup") {
2432 rg = add_edit_group ("");
2433 rg->set_state (**niter);
2435 rg = add_mix_group ("");
2436 rg->set_state (**niter);
2445 Session::swap_configuration(Configuration** new_config)
2447 Glib::RWLock::WriterLock lm (route_lock); // jlc - WHY?
2448 Configuration* tmp = *new_config;
2449 *new_config = Config;
2455 Session::copy_configuration(Configuration* new_config)
2457 Glib::RWLock::WriterLock lm (route_lock);
2458 new_config = new Configuration(*Config);
2462 state_file_filter (const string &str, void *arg)
2464 return (str.length() > strlen(Session::statefile_suffix()) &&
2465 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2469 bool operator()(const string* a, const string* b) {
2475 remove_end(string* state)
2477 string statename(*state);
2479 string::size_type start,end;
2480 if ((start = statename.find_last_of ('/')) != string::npos) {
2481 statename = statename.substr (start+1);
2484 if ((end = statename.rfind(".ardour")) < 0) {
2485 end = statename.length();
2488 return new string(statename.substr (0, end));
2492 Session::possible_states (string path)
2494 PathScanner scanner;
2495 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2497 transform(states->begin(), states->end(), states->begin(), remove_end);
2500 sort (states->begin(), states->end(), cmp);
2506 Session::possible_states () const
2508 return possible_states(_path);
2512 Session::auto_save()
2514 save_state (_current_snapshot_name);
2518 Session::add_edit_group (string name)
2520 RouteGroup* rg = new RouteGroup (*this, name);
2521 edit_groups.push_back (rg);
2522 edit_group_added (rg); /* EMIT SIGNAL */
2528 Session::add_mix_group (string name)
2530 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2531 mix_groups.push_back (rg);
2532 mix_group_added (rg); /* EMIT SIGNAL */
2538 Session::remove_edit_group (RouteGroup& rg)
2540 list<RouteGroup*>::iterator i;
2542 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2543 (*i)->apply (&Route::drop_edit_group, this);
2544 edit_groups.erase (i);
2545 edit_group_removed (); /* EMIT SIGNAL */
2552 Session::remove_mix_group (RouteGroup& rg)
2554 list<RouteGroup*>::iterator i;
2556 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2557 (*i)->apply (&Route::drop_mix_group, this);
2558 mix_groups.erase (i);
2559 mix_group_removed (); /* EMIT SIGNAL */
2566 Session::mix_group_by_name (string name)
2568 list<RouteGroup *>::iterator i;
2570 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2571 if ((*i)->name() == name) {
2579 Session::edit_group_by_name (string name)
2581 list<RouteGroup *>::iterator i;
2583 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2584 if ((*i)->name() == name) {
2592 Session::set_meter_hold (float val)
2595 MeterHoldChanged(); // emit
2599 Session::set_meter_falloff (float val)
2601 _meter_falloff = val;
2602 MeterFalloffChanged(); // emit
2607 Session::begin_reversible_command (string name, UndoAction* private_undo)
2609 current_cmd.clear ();
2610 current_cmd.set_name (name);
2613 current_cmd.add_undo (*private_undo);
2618 Session::commit_reversible_command (UndoAction* private_redo)
2623 current_cmd.add_redo_no_execute (*private_redo);
2626 gettimeofday (&now, 0);
2627 current_cmd.set_timestamp (now);
2629 history.add (current_cmd);
2632 Session::GlobalRouteBooleanState
2633 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2635 GlobalRouteBooleanState s;
2636 Glib::RWLock::ReaderLock lm (route_lock);
2638 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2639 if (!(*i)->hidden()) {
2640 RouteBooleanState v;
2643 v.second = ((*i)->*method)();
2652 Session::GlobalRouteMeterState
2653 Session::get_global_route_metering ()
2655 GlobalRouteMeterState s;
2656 Glib::RWLock::ReaderLock lm (route_lock);
2658 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2659 if (!(*i)->hidden()) {
2663 v.second = (*i)->meter_point();
2673 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2675 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2676 i->first->set_meter_point (i->second, arg);
2681 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2683 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2684 (i->first->*method) (i->second, arg);
2689 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2691 set_global_route_boolean (s, &Route::set_mute, src);
2695 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2697 set_global_route_boolean (s, &Route::set_solo, src);
2701 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2703 set_global_route_boolean (s, &Route::set_record_enable, src);
2707 Session::global_mute_memento (void* src)
2709 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2713 Session::global_metering_memento (void* src)
2715 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2719 Session::global_solo_memento (void* src)
2721 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2725 Session::global_record_enable_memento (void* src)
2727 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2731 template_filter (const string &str, void *arg)
2733 return (str.length() > strlen(Session::template_suffix()) &&
2734 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2738 Session::get_template_list (list<string> &template_names)
2740 vector<string *> *templates;
2741 PathScanner scanner;
2744 path = template_path ();
2746 templates = scanner (path, template_filter, 0, false, true);
2748 vector<string*>::iterator i;
2749 for (i = templates->begin(); i != templates->end(); ++i) {
2750 string fullpath = *(*i);
2753 start = fullpath.find_last_of ('/') + 1;
2754 if ((end = fullpath.find_last_of ('.')) <0) {
2755 end = fullpath.length();
2758 template_names.push_back(fullpath.substr(start, (end-start)));
2763 Session::read_favorite_dirs (FavoriteDirs & favs)
2765 string path = get_user_ardour_path();
2766 path += "/favorite_dirs";
2768 ifstream fav (path.c_str());
2773 if (errno != ENOENT) {
2774 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2785 getline(fav, newfav);
2791 favs.push_back (newfav);
2798 Session::write_favorite_dirs (FavoriteDirs & favs)
2800 string path = get_user_ardour_path();
2801 path += "/favorite_dirs";
2803 ofstream fav (path.c_str());
2809 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2810 fav << (*i) << endl;
2817 accept_all_non_peak_files (const string& path, void *arg)
2819 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2823 accept_all_state_files (const string& path, void *arg)
2825 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2829 Session::find_all_sources (string path, set<string>& result)
2834 if (!tree.read (path)) {
2838 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2843 XMLNodeConstIterator niter;
2845 nlist = node->children();
2849 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2853 if ((prop = (*niter)->property (X_("name"))) == 0) {
2857 if (prop->value()[0] == '/') {
2858 /* external file, ignore */
2862 string path = _path; /* /-terminated */
2863 path += sound_dir_name;
2865 path += prop->value();
2867 result.insert (path);
2874 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2876 PathScanner scanner;
2877 vector<string*>* state_files;
2879 string this_snapshot_path;
2885 if (ripped[ripped.length()-1] == '/') {
2886 ripped = ripped.substr (0, ripped.length() - 1);
2889 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2891 if (state_files == 0) {
2896 this_snapshot_path = _path;
2897 this_snapshot_path += _current_snapshot_name;
2898 this_snapshot_path += _statefile_suffix;
2900 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2902 if (exclude_this_snapshot && **i == this_snapshot_path) {
2906 if (find_all_sources (**i, result) < 0) {
2915 Session::cleanup_sources (Session::cleanup_report& rep)
2917 vector<Source*> dead_sources;
2918 vector<Playlist*> playlists_tbd;
2919 PathScanner scanner;
2921 vector<space_and_path>::iterator i;
2922 vector<space_and_path>::iterator nexti;
2923 vector<string*>* soundfiles;
2924 vector<string> unused;
2925 set<string> all_sources;
2930 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2932 /* step 1: consider deleting all unused playlists */
2934 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2937 status = AskAboutPlaylistDeletion (*x);
2946 playlists_tbd.push_back (*x);
2950 /* leave it alone */
2955 /* now delete any that were marked for deletion */
2957 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2958 PlaylistList::iterator foo;
2960 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2961 unused_playlists.erase (foo);
2966 /* step 2: clear the undo/redo history for all playlists */
2968 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2969 (*x)->drop_all_states ();
2972 /* step 3: find all un-referenced sources */
2977 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2979 AudioSourceList::iterator tmp;
2984 /* only remove files that are not in use and have some size
2985 to them. otherwise we remove the current "nascent"
2989 if (i->second->use_cnt() == 0 && i->second->length() > 0) {
2990 dead_sources.push_back (i->second);
2992 /* remove this source from our own list to avoid us
2993 adding it to the list of all sources below
2996 audio_sources.erase (i);
3002 /* Step 4: get rid of all regions in the region list that use any dead sources
3003 in case the sources themselves don't go away (they might be referenced in
3007 for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
3009 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
3010 AudioRegionList::iterator tmp;
3018 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
3019 if (&ar->source (n) == (*i)) {
3020 /* this region is dead */
3029 /* build a list of all the possible sound directories for the session */
3031 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
3036 sound_path += (*i).path;
3037 sound_path += sound_dir_name;
3039 if (nexti != session_dirs.end()) {
3046 /* now do the same thing for the files that ended up in the sounds dir(s)
3047 but are not referenced as sources in any snapshot.
3050 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
3052 if (soundfiles == 0) {
3056 /* find all sources, but don't use this snapshot because the
3057 state file on disk still references sources we may have already
3061 find_all_sources_across_snapshots (all_sources, true);
3063 /* add our current source list
3066 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
3067 AudioFileSource* fs;
3069 if ((fs = dynamic_cast<AudioFileSource*> (i->second)) != 0) {
3070 all_sources.insert (fs->path());
3074 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
3079 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
3089 unused.push_back (spath);
3093 /* now try to move all unused files into the "dead_sounds" directory(ies) */
3095 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
3096 struct stat statbuf;
3098 rep.paths.push_back (*x);
3099 if (stat ((*x).c_str(), &statbuf) == 0) {
3100 rep.space += statbuf.st_size;
3105 /* don't move the file across filesystems, just
3106 stick it in the `dead_sound_dir_name' directory
3107 on whichever filesystem it was already on.
3110 newpath = Glib::path_get_dirname (*x);
3111 newpath = Glib::path_get_dirname (newpath);
3114 newpath += dead_sound_dir_name;
3116 newpath += Glib::path_get_basename ((*x));
3118 if (access (newpath.c_str(), F_OK) == 0) {
3120 /* the new path already exists, try versioning */
3122 char buf[PATH_MAX+1];
3126 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
3129 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
3130 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
3134 if (version == 999) {
3135 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
3139 newpath = newpath_v;
3144 /* it doesn't exist, or we can't read it or something */
3148 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
3149 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
3150 (*x), newpath, strerror (errno))
3156 /* see if there an easy to find peakfile for this file, and remove it.
3159 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
3160 peakpath += ".peak";
3162 if (access (peakpath.c_str(), W_OK) == 0) {
3163 if (::unlink (peakpath.c_str()) != 0) {
3164 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3165 peakpath, _path, strerror (errno))
3167 /* try to back out */
3168 rename (newpath.c_str(), _path.c_str());
3177 /* dump the history list */
3181 /* save state so we don't end up a session file
3182 referring to non-existent sources.
3188 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3193 Session::cleanup_trash_sources (Session::cleanup_report& rep)
3195 vector<space_and_path>::iterator i;
3196 string dead_sound_dir;
3197 struct dirent* dentry;
3198 struct stat statbuf;
3204 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3206 dead_sound_dir = (*i).path;
3207 dead_sound_dir += dead_sound_dir_name;
3209 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
3213 while ((dentry = readdir (dead)) != 0) {
3215 /* avoid '.' and '..' */
3217 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
3218 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3224 fullpath = dead_sound_dir;
3226 fullpath += dentry->d_name;
3228 if (stat (fullpath.c_str(), &statbuf)) {
3232 if (!S_ISREG (statbuf.st_mode)) {
3236 if (unlink (fullpath.c_str())) {
3237 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3238 fullpath, strerror (errno))
3242 rep.paths.push_back (dentry->d_name);
3243 rep.space += statbuf.st_size;
3254 Session::set_dirty ()
3256 bool was_dirty = dirty();
3258 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3261 DirtyChanged(); /* EMIT SIGNAL */
3267 Session::set_clean ()
3269 bool was_dirty = dirty();
3271 _state_of_the_state = Clean;
3274 DirtyChanged(); /* EMIT SIGNAL */
3279 Session::add_controllable (Controllable* c)
3281 Glib::Mutex::Lock lm (controllables_lock);
3282 controllables.push_back (c);
3286 Session::remove_controllable (Controllable* c)
3288 Glib::Mutex::Lock lm (controllables_lock);
3289 controllables.remove (c);
3293 Session::controllable_by_id (const PBD::ID& id)
3295 Glib::Mutex::Lock lm (controllables_lock);
3297 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3298 if ((*i)->id() == id) {