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/cycle_timer.h>
78 #include <ardour/utils.h>
79 #include <ardour/named_selection.h>
80 #include <ardour/version.h>
81 #include <ardour/location.h>
82 #include <ardour/audioregion.h>
83 #include <ardour/crossfade.h>
84 #include <ardour/control_protocol_manager.h>
90 using namespace ARDOUR;
94 Session::first_stage_init (string fullpath, string snapshot_name)
96 if (fullpath.length() == 0) {
97 throw failed_constructor();
100 char buf[PATH_MAX+1];
101 if (!realpath(fullpath.c_str(), buf) && (errno != ENOENT)) {
102 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
103 throw failed_constructor();
107 if (_path[_path.length()-1] != '/') {
111 /* these two are just provisional settings. set_state()
112 will likely override them.
115 _name = _current_snapshot_name = snapshot_name;
116 setup_raid_path (_path);
118 _current_frame_rate = _engine.frame_rate ();
119 _tempo_map = new TempoMap (_current_frame_rate);
120 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
122 g_atomic_int_set (&processing_prohibited, 0);
125 _transport_speed = 0;
126 _last_transport_speed = 0;
127 transport_sub_state = 0;
128 _transport_frame = 0;
130 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
131 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
132 _end_location_is_free = true;
133 g_atomic_int_set (&_record_status, Disabled);
138 seamless_loop = false;
139 loop_changing = false;
141 crossfades_active = false;
144 _last_roll_location = 0;
145 _last_record_location = 0;
146 pending_locate_frame = 0;
147 pending_locate_roll = false;
148 pending_locate_flush = false;
149 dstream_buffer_size = 0;
151 state_was_pending = false;
153 outbound_mtc_smpte_frame = 0;
154 next_quarter_frame_to_send = -1;
155 current_block_size = 0;
156 _solo_latched = true;
157 _solo_model = InverseMute;
158 solo_update_disabled = false;
159 currently_soloing = false;
160 _have_captured = false;
161 _worst_output_latency = 0;
162 _worst_input_latency = 0;
163 _worst_track_latency = 0;
164 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
167 butler_mixdown_buffer = 0;
168 butler_gain_buffer = 0;
173 post_transport_work = PostTransportWork (0);
174 g_atomic_int_set (&butler_should_do_transport_work, 0);
175 g_atomic_int_set (&butler_active, 0);
176 g_atomic_int_set (&_playback_load, 100);
177 g_atomic_int_set (&_capture_load, 100);
178 g_atomic_int_set (&_playback_load_min, 100);
179 g_atomic_int_set (&_capture_load_min, 100);
180 pending_audition_region = 0;
182 pending_edit_mode = _edit_mode;
186 input_auto_connect = AutoConnectOption (0);
187 output_auto_connect = AutoConnectOption (0);
188 waiting_to_start = false;
190 _gain_automation_buffer = 0;
191 _pan_automation_buffer = 0;
193 pending_abort = false;
194 layer_model = MoveAddHigher;
195 xfade_model = ShortCrossfade;
196 destructive_index = 0;
198 /* allocate conversion buffers */
199 _conversion_buffers[ButlerContext] = new char[AudioDiskstream::disk_io_frames() * 4];
200 _conversion_buffers[TransportContext] = new char[AudioDiskstream::disk_io_frames() * 4];
202 /* default short fade = 15ms */
204 Crossfade::set_short_xfade_length ((jack_nframes_t) floor ((15.0 * frame_rate()) / 1000.0));
205 DestructiveFileSource::setup_standard_crossfades (frame_rate());
207 last_mmc_step.tv_sec = 0;
208 last_mmc_step.tv_usec = 0;
211 preroll.type = AnyTime::Frames;
213 postroll.type = AnyTime::Frames;
216 /* click sounds are unset by default, which causes us to internal
217 waveforms for clicks.
222 click_requested = false;
224 click_emphasis_data = 0;
226 click_emphasis_length = 0;
228 process_function = &Session::process_with_events;
232 _smpte_offset_negative = true;
233 last_smpte_valid = false;
235 last_rr_session_dir = session_dirs.begin();
236 refresh_disk_space ();
238 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
240 /* default configuration */
242 do_not_record_plugins = false;
243 over_length_short = 2;
244 over_length_long = 10;
245 send_midi_timecode = false;
246 send_midi_machine_control = false;
247 shuttle_speed_factor = 1.0;
248 shuttle_speed_threshold = 5;
250 _meter_hold = 100; // XXX unknown units: number of calls to meter::set()
251 _meter_falloff = 1.5f; // XXX unknown units: refresh_rate
257 average_slave_delta = 1800;
258 have_first_delta_accumulator = false;
259 delta_accumulator_cnt = 0;
260 slave_state = Stopped;
262 /* default SMPTE type is 30 FPS, non-drop */
264 set_smpte_type (30.0, false);
266 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
268 /* These are all static "per-class" signals */
270 Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
271 AudioSource::AudioSourceCreated.connect (mem_fun (*this, &Session::add_audio_source));
272 Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
273 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
274 Diskstream::DiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
275 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
277 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
279 /* stop IO objects from doing stuff until we're ready for them */
281 IO::disable_panners ();
282 IO::disable_ports ();
283 IO::disable_connecting ();
287 Session::second_stage_init (bool new_session)
289 AudioFileSource::set_peak_dir (peak_dir());
292 if (load_state (_current_snapshot_name)) {
295 remove_empty_sounds ();
298 if (start_butler_thread()) {
302 /*if (start_midi_thread ()) {
307 if (set_state (*state_tree->root())) {
312 /* we can't save till after ::when_engine_running() is called,
313 because otherwise we save state with no connections made.
314 therefore, we reset _state_of_the_state because ::set_state()
315 will have cleared it.
317 we also have to include Loading so that any events that get
318 generated between here and the end of ::when_engine_running()
319 will be processed directly rather than queued.
322 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
324 // set_auto_input (true);
325 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
326 _locations.added.connect (mem_fun (this, &Session::locations_added));
327 setup_click_sounds (0);
328 setup_midi_control ();
330 /* Pay attention ... */
332 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
333 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
335 if (_engine.running()) {
336 when_engine_running();
338 first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
341 //send_full_time_code ();
342 _engine.transport_locate (0);
343 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
344 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
346 ControlProtocolManager::instance().set_session (*this);
349 _end_location_is_free = true;
351 _end_location_is_free = false;
358 Session::raid_path () const
362 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
367 return path.substr (0, path.length() - 1); // drop final colon
371 Session::set_raid_path (string path)
373 /* public-access to setup_raid_path() */
375 setup_raid_path (path);
379 Session::setup_raid_path (string path)
381 string::size_type colon;
385 string::size_type len = path.length();
390 if (path.length() == 0) {
394 session_dirs.clear ();
396 for (string::size_type n = 0; n < len; ++n) {
397 if (path[n] == ':') {
404 /* no multiple search path, just one location (common case) */
408 session_dirs.push_back (sp);
415 if (fspath[fspath.length()-1] != '/') {
418 fspath += sound_dir_name;
424 if (fspath[fspath.length()-1] != '/') {
427 fspath += tape_dir_name;
429 AudioFileSource::set_search_path (fspath);
436 while ((colon = remaining.find_first_of (':')) != string::npos) {
439 sp.path = remaining.substr (0, colon);
440 session_dirs.push_back (sp);
442 /* add sounds to file search path */
445 if (fspath[fspath.length()-1] != '/') {
448 fspath += sound_dir_name;
451 /* add tape dir to file search path */
454 if (fspath[fspath.length()-1] != '/') {
457 fspath += tape_dir_name;
460 remaining = remaining.substr (colon+1);
463 if (remaining.length()) {
470 if (fspath[fspath.length()-1] != '/') {
473 fspath += sound_dir_name;
477 if (fspath[fspath.length()-1] != '/') {
480 fspath += tape_dir_name;
482 session_dirs.push_back (sp);
485 /* set the AudioFileSource search path */
487 AudioFileSource::set_search_path (fspath);
489 /* reset the round-robin soundfile path thingie */
491 last_rr_session_dir = session_dirs.begin();
495 Session::create (bool& new_session, string* mix_template, jack_nframes_t initial_length)
499 if (mkdir (_path.c_str(), 0755) < 0) {
500 if (errno == EEXIST) {
503 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
512 if (mkdir (dir.c_str(), 0755) < 0) {
513 if (errno != EEXIST) {
514 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
521 if (mkdir (dir.c_str(), 0755) < 0) {
522 if (errno != EEXIST) {
523 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
530 if (mkdir (dir.c_str(), 0755) < 0) {
531 if (errno != EEXIST) {
532 error << string_compose(_("Session: cannot create session tape dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
537 dir = dead_sound_dir ();
539 if (mkdir (dir.c_str(), 0755) < 0) {
540 if (errno != EEXIST) {
541 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
546 dir = automation_dir ();
548 if (mkdir (dir.c_str(), 0755) < 0) {
549 if (errno != EEXIST) {
550 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
556 /* check new_session so we don't overwrite an existing one */
560 std::string in_path = *mix_template;
562 ifstream in(in_path.c_str());
565 string out_path = _path;
567 out_path += _statefile_suffix;
569 ofstream out(out_path.c_str());
574 // okay, session is set up. Treat like normal saved
575 // session from now on.
581 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
587 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
594 warning << _("Session already exists. Not overwriting") << endmsg;
601 /* set initial start + end point */
603 start_location->set_end (0);
604 _locations.add (start_location);
606 end_location->set_end (initial_length);
607 _locations.add (end_location);
609 _state_of_the_state = Clean;
611 if (save_state (_current_snapshot_name)) {
620 Session::load_diskstreams (const XMLNode& node)
623 XMLNodeConstIterator citer;
625 clist = node.children();
627 for (citer = clist.begin(); citer != clist.end(); ++citer) {
628 Diskstream* dstream = NULL;
631 if ((*citer)->name() == "AudioDiskstream") {
632 dstream = new AudioDiskstream (*this, **citer);
633 /* added automatically by DiskstreamCreated handler */
635 assert((*citer)->name() == "MidiDiskstream");
636 dstream = new MidiDiskstream (*this, **citer);
640 catch (failed_constructor& err) {
641 error << _("Session: could not load diskstream via XML state") << endmsg;
650 Session::remove_pending_capture_state ()
655 xml_path += _current_snapshot_name;
656 xml_path += _pending_suffix;
658 unlink (xml_path.c_str());
662 Session::save_state (string snapshot_name, bool pending)
668 if (_state_of_the_state & CannotSave) {
672 tree.set_root (&get_state());
674 if (snapshot_name.empty()) {
675 snapshot_name = _current_snapshot_name;
681 xml_path += snapshot_name;
682 xml_path += _statefile_suffix;
686 // Make backup of state file
688 if ((access (xml_path.c_str(), F_OK) == 0) &&
689 (rename(xml_path.c_str(), bak_path.c_str()))) {
690 error << _("could not backup old state file, current state not saved.") << endmsg;
697 xml_path += snapshot_name;
698 xml_path += _pending_suffix;
702 if (!tree.write (xml_path)) {
703 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
705 /* don't leave a corrupt file lying around if it is
709 if (unlink (xml_path.c_str())) {
710 error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
713 if (rename (bak_path.c_str(), xml_path.c_str())) {
714 error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
724 bool was_dirty = dirty();
726 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
729 DirtyChanged (); /* EMIT SIGNAL */
732 StateSaved (snapshot_name); /* EMIT SIGNAL */
739 Session::restore_state (string snapshot_name)
741 if (load_state (snapshot_name) == 0) {
742 set_state (*state_tree->root());
749 Session::load_state (string snapshot_name)
758 state_was_pending = false;
760 /* check for leftover pending state from a crashed capture attempt */
763 xmlpath += snapshot_name;
764 xmlpath += _pending_suffix;
766 if (!access (xmlpath.c_str(), F_OK)) {
768 /* there is pending state from a crashed capture attempt */
770 if (AskAboutPendingState()) {
771 state_was_pending = true;
775 if (!state_was_pending) {
778 xmlpath += snapshot_name;
779 xmlpath += _statefile_suffix;
782 if (access (xmlpath.c_str(), F_OK)) {
783 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
787 state_tree = new XMLTree;
791 if (state_tree->read (xmlpath)) {
794 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
803 Session::load_options (const XMLNode& node)
807 bool have_fade_msecs = false;
808 bool have_fade_steepness = false;
809 float fade_msecs = 0;
810 float fade_steepness = 0;
811 SlaveSource slave_src = None;
813 LocaleGuard lg (X_("POSIX"));
815 if ((child = find_named_node (node, "input-auto-connect")) != 0) {
816 if ((prop = child->property ("val")) != 0) {
817 sscanf (prop->value().c_str(), "%x", &x);
818 input_auto_connect = AutoConnectOption (x);
822 if ((child = find_named_node (node, "output-auto-connect")) != 0) {
823 if ((prop = child->property ("val")) != 0) {
824 sscanf (prop->value().c_str(), "%x", &x);
825 output_auto_connect = AutoConnectOption (x);
829 if ((child = find_named_node (node, "slave")) != 0) {
830 if ((prop = child->property ("type")) != 0) {
831 if (prop->value() == "none") {
833 } else if (prop->value() == "mtc") {
835 } else if (prop->value() == "jack") {
838 set_slave_source (slave_src, 0);
842 /* we cannot set edit mode if we are loading a session,
843 because it might destroy the playlist's positioning
846 if ((child = find_named_node (node, "edit-mode")) != 0) {
847 if ((prop = child->property ("val")) != 0) {
848 if (prop->value() == "slide") {
849 pending_edit_mode = Slide;
850 } else if (prop->value() == "splice") {
851 pending_edit_mode = Splice;
856 if ((child = find_named_node (node, "send-midi-timecode")) != 0) {
857 if ((prop = child->property ("val")) != 0) {
858 bool x = (prop->value() == "yes");
859 send_mtc = !x; /* force change in value */
863 if ((child = find_named_node (node, "send-midi-machine-control")) != 0) {
864 if ((prop = child->property ("val")) != 0) {
865 bool x = (prop->value() == "yes");
866 send_mmc = !x; /* force change in value */
867 set_send_mmc (prop->value() == "yes");
870 if ((child = find_named_node (node, "max-level")) != 0) {
871 if ((prop = child->property ("val")) != 0) {
872 max_level = atoi (prop->value().c_str());
875 if ((child = find_named_node (node, "min-level")) != 0) {
876 if ((prop = child->property ("val")) != 0) {
877 min_level = atoi (prop->value().c_str());
880 if ((child = find_named_node (node, "meter-hold")) != 0) {
881 if ((prop = child->property ("val")) != 0) {
882 _meter_hold = atof (prop->value().c_str());
885 if ((child = find_named_node (node, "meter-falloff")) != 0) {
886 if ((prop = child->property ("val")) != 0) {
887 _meter_falloff = atof (prop->value().c_str());
890 if ((child = find_named_node (node, "long-over-length")) != 0) {
891 if ((prop = child->property ("val")) != 0) {
892 over_length_long = atoi (prop->value().c_str());
895 if ((child = find_named_node (node, "short-over-length")) != 0) {
896 if ((prop = child->property ("val")) != 0) {
897 over_length_short = atoi (prop->value().c_str());
900 if ((child = find_named_node (node, "shuttle-speed-factor")) != 0) {
901 if ((prop = child->property ("val")) != 0) {
902 shuttle_speed_factor = atof (prop->value().c_str());
905 if ((child = find_named_node (node, "shuttle-speed-threshold")) != 0) {
906 if ((prop = child->property ("val")) != 0) {
907 shuttle_speed_threshold = atof (prop->value().c_str());
910 if ((child = find_named_node (node, "rf-speed")) != 0) {
911 if ((prop = child->property ("val")) != 0) {
912 rf_speed = atof (prop->value().c_str());
915 if ((child = find_named_node (node, "smpte-frames-per-second")) != 0) {
916 if ((prop = child->property ("val")) != 0) {
917 set_smpte_type( atof (prop->value().c_str()), smpte_drop_frames );
920 if ((child = find_named_node (node, "smpte-drop-frames")) != 0) {
921 if ((prop = child->property ("val")) != 0) {
922 set_smpte_type( smpte_frames_per_second, (prop->value() == "yes") );
925 if ((child = find_named_node (node, "smpte-offset")) != 0) {
926 if ((prop = child->property ("val")) != 0) {
927 set_smpte_offset( atoi (prop->value().c_str()) );
930 if ((child = find_named_node (node, "smpte-offset-negative")) != 0) {
931 if ((prop = child->property ("val")) != 0) {
932 set_smpte_offset_negative( (prop->value() == "yes") );
935 if ((child = find_named_node (node, "click-sound")) != 0) {
936 if ((prop = child->property ("val")) != 0) {
937 click_sound = prop->value();
940 if ((child = find_named_node (node, "click-emphasis-sound")) != 0) {
941 if ((prop = child->property ("val")) != 0) {
942 click_emphasis_sound = prop->value();
946 if ((child = find_named_node (node, "solo-model")) != 0) {
947 if ((prop = child->property ("val")) != 0) {
948 if (prop->value() == "SoloBus")
949 _solo_model = SoloBus;
951 _solo_model = InverseMute;
955 /* BOOLEAN OPTIONS */
957 if ((child = find_named_node (node, "auto-play")) != 0) {
958 if ((prop = child->property ("val")) != 0) {
959 set_auto_play (prop->value() == "yes");
962 if ((child = find_named_node (node, "auto-input")) != 0) {
963 if ((prop = child->property ("val")) != 0) {
964 set_auto_input (prop->value() == "yes");
967 if ((child = find_named_node (node, "seamless-loop")) != 0) {
968 if ((prop = child->property ("val")) != 0) {
969 set_seamless_loop (prop->value() == "yes");
972 if ((child = find_named_node (node, "punch-in")) != 0) {
973 if ((prop = child->property ("val")) != 0) {
974 set_punch_in (prop->value() == "yes");
977 if ((child = find_named_node (node, "punch-out")) != 0) {
978 if ((prop = child->property ("val")) != 0) {
979 set_punch_out (prop->value() == "yes");
982 if ((child = find_named_node (node, "auto-return")) != 0) {
983 if ((prop = child->property ("val")) != 0) {
984 set_auto_return (prop->value() == "yes");
987 if ((child = find_named_node (node, "send-mtc")) != 0) {
988 if ((prop = child->property ("val")) != 0) {
989 set_send_mtc (prop->value() == "yes");
992 if ((child = find_named_node (node, "mmc-control")) != 0) {
993 if ((prop = child->property ("val")) != 0) {
994 set_mmc_control (prop->value() == "yes");
997 if ((child = find_named_node (node, "midi-control")) != 0) {
998 if ((prop = child->property ("val")) != 0) {
999 set_midi_control (prop->value() == "yes");
1002 if ((child = find_named_node (node, "midi-feedback")) != 0) {
1003 if ((prop = child->property ("val")) != 0) {
1004 set_midi_feedback (prop->value() == "yes");
1007 // Legacy support for <recording-plugins>
1008 if ((child = find_named_node (node, "recording-plugins")) != 0) {
1009 if ((prop = child->property ("val")) != 0) {
1010 set_do_not_record_plugins (prop->value() == "no");
1013 if ((child = find_named_node (node, "do-not-record-plugins")) != 0) {
1014 if ((prop = child->property ("val")) != 0) {
1015 set_do_not_record_plugins (prop->value() == "yes");
1018 if ((child = find_named_node (node, "crossfades-active")) != 0) {
1019 if ((prop = child->property ("val")) != 0) {
1020 set_crossfades_active (prop->value() == "yes");
1023 if ((child = find_named_node (node, "audible-click")) != 0) {
1024 if ((prop = child->property ("val")) != 0) {
1025 set_clicking (prop->value() == "yes");
1029 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
1030 if ((prop = child->property ("val")) != 0) {
1031 _end_location_is_free = (prop->value() == "yes");
1035 if ((child = find_named_node (node, "layer-model")) != 0) {
1036 if ((prop = child->property ("val")) != 0) {
1037 if (prop->value() == X_("LaterHigher")) {
1038 set_layer_model (LaterHigher);
1039 } else if (prop->value() == X_("AddHigher")) {
1040 set_layer_model (AddHigher);
1042 set_layer_model (MoveAddHigher);
1047 if ((child = find_named_node (node, "xfade-model")) != 0) {
1048 if ((prop = child->property ("val")) != 0) {
1049 if (prop->value() == X_("Short")) {
1050 set_xfade_model (ShortCrossfade);
1052 set_xfade_model (FullCrossfade);
1057 if ((child = find_named_node (node, "short-xfade-length")) != 0) {
1058 if ((prop = child->property ("val")) != 0) {
1059 /* value is stored as a fractional seconds */
1060 float secs = atof (prop->value().c_str());
1061 Crossfade::set_short_xfade_length ((jack_nframes_t) floor (secs * frame_rate()));
1065 if ((child = find_named_node (node, "full-xfades-unmuted")) != 0) {
1066 if ((prop = child->property ("val")) != 0) {
1067 crossfades_active = (prop->value() == "yes");
1073 if ((child = find_named_node (node, "default-fade-steepness")) != 0) {
1074 if ((prop = child->property ("val")) != 0) {
1075 fade_steepness = atof (prop->value().c_str());
1076 have_fade_steepness = true;
1079 if ((child = find_named_node (node, "default-fade-msec")) != 0) {
1080 if ((prop = child->property ("val")) != 0) {
1081 fade_msecs = atof (prop->value().c_str());
1082 have_fade_msecs = true;
1086 if (have_fade_steepness || have_fade_msecs) {
1087 // set_default_fade (fade_steepness, fade_msecs);
1094 Session::get_options () const
1099 LocaleGuard lg (X_("POSIX"));
1101 opthead = new XMLNode ("Options");
1103 SlaveSource src = slave_source ();
1107 src_string = "none";
1113 src_string = "jack";
1116 child = opthead->add_child ("slave");
1117 child->add_property ("type", src_string);
1119 child = opthead->add_child ("send-midi-timecode");
1120 child->add_property ("val", send_midi_timecode?"yes":"no");
1122 child = opthead->add_child ("send-midi-machine-control");
1123 child->add_property ("val", send_midi_machine_control?"yes":"no");
1125 snprintf (buf, sizeof(buf)-1, "%x", (int) input_auto_connect);
1126 child = opthead->add_child ("input-auto-connect");
1127 child->add_property ("val", buf);
1129 snprintf (buf, sizeof(buf)-1, "%x", (int) output_auto_connect);
1130 child = opthead->add_child ("output-auto-connect");
1131 child->add_property ("val", buf);
1133 snprintf (buf, sizeof(buf)-1, "%d", max_level);
1134 child = opthead->add_child ("max-level");
1135 child->add_property ("val", buf);
1137 snprintf (buf, sizeof(buf)-1, "%d", min_level);
1138 child = opthead->add_child ("min-level");
1139 child->add_property ("val", buf);
1141 snprintf (buf, sizeof(buf)-1, "%f", _meter_hold);
1142 child = opthead->add_child ("meter-hold");
1143 child->add_property ("val", buf);
1145 snprintf (buf, sizeof(buf)-1, "%f", _meter_falloff);
1146 child = opthead->add_child ("meter-falloff");
1147 child->add_property ("val", buf);
1149 snprintf (buf, sizeof(buf)-1, "%u", over_length_long);
1150 child = opthead->add_child ("long-over-length");
1151 child->add_property ("val", buf);
1153 snprintf (buf, sizeof(buf)-1, "%u", over_length_short);
1154 child = opthead->add_child ("short-over-length");
1155 child->add_property ("val", buf);
1157 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_factor);
1158 child = opthead->add_child ("shuttle-speed-factor");
1159 child->add_property ("val", buf);
1161 snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_threshold);
1162 child = opthead->add_child ("shuttle-speed-threshold");
1163 child->add_property ("val", buf);
1165 snprintf (buf, sizeof(buf)-1, "%f", rf_speed);
1166 child = opthead->add_child ("rf-speed");
1167 child->add_property ("val", buf);
1169 snprintf (buf, sizeof(buf)-1, "%.2f", smpte_frames_per_second);
1170 child = opthead->add_child ("smpte-frames-per-second");
1171 child->add_property ("val", buf);
1173 child = opthead->add_child ("smpte-drop-frames");
1174 child->add_property ("val", smpte_drop_frames ? "yes" : "no");
1176 snprintf (buf, sizeof(buf)-1, "%u", smpte_offset ());
1177 child = opthead->add_child ("smpte-offset");
1178 child->add_property ("val", buf);
1180 child = opthead->add_child ("smpte-offset-negative");
1181 child->add_property ("val", smpte_offset_negative () ? "yes" : "no");
1183 child = opthead->add_child ("edit-mode");
1184 switch (_edit_mode) {
1186 child->add_property ("val", "splice");
1190 child->add_property ("val", "slide");
1194 child = opthead->add_child ("auto-play");
1195 child->add_property ("val", get_auto_play () ? "yes" : "no");
1196 child = opthead->add_child ("auto-input");
1197 child->add_property ("val", get_auto_input () ? "yes" : "no");
1198 child = opthead->add_child ("seamless-loop");
1199 child->add_property ("val", get_seamless_loop () ? "yes" : "no");
1200 child = opthead->add_child ("punch-in");
1201 child->add_property ("val", get_punch_in () ? "yes" : "no");
1202 child = opthead->add_child ("punch-out");
1203 child->add_property ("val", get_punch_out () ? "yes" : "no");
1204 child = opthead->add_child ("all-safe");
1205 child->add_property ("val", get_all_safe () ? "yes" : "no");
1206 child = opthead->add_child ("auto-return");
1207 child->add_property ("val", get_auto_return () ? "yes" : "no");
1208 child = opthead->add_child ("mmc-control");
1209 child->add_property ("val", get_mmc_control () ? "yes" : "no");
1210 child = opthead->add_child ("midi-control");
1211 child->add_property ("val", get_midi_control () ? "yes" : "no");
1212 child = opthead->add_child ("midi-feedback");
1213 child->add_property ("val", get_midi_feedback () ? "yes" : "no");
1214 child = opthead->add_child ("do-not-record-plugins");
1215 child->add_property ("val", get_do_not_record_plugins () ? "yes" : "no");
1216 child = opthead->add_child ("auto-crossfade");
1217 child->add_property ("val", get_crossfades_active () ? "yes" : "no");
1218 child = opthead->add_child ("audible-click");
1219 child->add_property ("val", get_clicking () ? "yes" : "no");
1220 child = opthead->add_child ("end-marker-is-free");
1221 child->add_property ("val", _end_location_is_free ? "yes" : "no");
1223 if (click_sound.length()) {
1224 child = opthead->add_child ("click-sound");
1225 child->add_property ("val", click_sound);
1228 if (click_emphasis_sound.length()) {
1229 child = opthead->add_child ("click-emphasis-sound");
1230 child->add_property ("val", click_emphasis_sound);
1233 child = opthead->add_child ("solo-model");
1234 child->add_property ("val", _solo_model == SoloBus ? "SoloBus" : "InverseMute");
1236 child = opthead->add_child ("layer-model");
1237 switch (layer_model) {
1239 child->add_property ("val", X_("LaterHigher"));
1242 child->add_property ("val", X_("MoveAddHigher"));
1245 child->add_property ("val", X_("AddHigher"));
1249 child = opthead->add_child ("xfade-model");
1250 switch (xfade_model) {
1252 child->add_property ("val", X_("Full"));
1254 case ShortCrossfade:
1255 child->add_property ("val", X_("Short"));
1258 child = opthead->add_child ("short-xfade-length");
1259 /* store as fractions of a second */
1260 snprintf (buf, sizeof(buf)-1, "%f",
1261 (float) Crossfade::short_xfade_length() / frame_rate());
1262 child->add_property ("val", buf);
1264 child = opthead->add_child ("full-xfades-unmuted");
1265 child->add_property ("val", crossfades_active ? "yes" : "no");
1271 Session::get_state()
1277 Session::get_template()
1279 /* if we don't disable rec-enable, diskstreams
1280 will believe they need to store their capture
1281 sources in their state node.
1284 disable_record (false);
1286 return state(false);
1290 Session::state(bool full_state)
1292 XMLNode* node = new XMLNode("Session");
1295 // store libardour version, just in case
1297 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
1298 libardour_major_version, libardour_minor_version, libardour_micro_version);
1299 node->add_property("version", string(buf));
1301 /* store configuration settings */
1305 /* store the name */
1306 node->add_property ("name", _name);
1308 if (session_dirs.size() > 1) {
1312 vector<space_and_path>::iterator i = session_dirs.begin();
1313 vector<space_and_path>::iterator next;
1315 ++i; /* skip the first one */
1319 while (i != session_dirs.end()) {
1323 if (next != session_dirs.end()) {
1333 child = node->add_child ("Path");
1334 child->add_content (p);
1338 node->add_child_nocopy (get_options());
1340 child = node->add_child ("Sources");
1343 Glib::Mutex::Lock sl (audio_source_lock);
1345 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
1347 /* Don't save information about AudioFileSources that are empty */
1349 AudioFileSource* fs;
1351 if ((fs = dynamic_cast<AudioFileSource*> ((*siter).second)) != 0) {
1352 DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
1354 /* destructive file sources are OK if they are empty, because
1355 we will re-use them every time.
1359 if (fs->length() == 0) {
1365 child->add_child_nocopy ((*siter).second->get_state());
1369 child = node->add_child ("Regions");
1372 Glib::Mutex::Lock rl (region_lock);
1374 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1376 /* only store regions not attached to playlists */
1378 if ((*i).second->playlist() == 0) {
1379 child->add_child_nocopy (i->second->state (true));
1384 child = node->add_child ("DiskStreams");
1387 Glib::RWLock::ReaderLock dl (diskstream_lock);
1388 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1389 if (!(*i)->hidden()) {
1390 child->add_child_nocopy ((*i)->get_state());
1395 node->add_child_nocopy (_locations.get_state());
1397 child = node->add_child ("Connections");
1399 Glib::Mutex::Lock lm (connection_lock);
1400 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1401 if (!(*i)->system_dependent()) {
1402 child->add_child_nocopy ((*i)->get_state());
1407 child = node->add_child ("Routes");
1409 Glib::RWLock::ReaderLock lm (route_lock);
1411 RoutePublicOrderSorter cmp;
1412 RouteList public_order(routes);
1413 public_order.sort (cmp);
1415 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1416 if (!(*i)->hidden()) {
1418 child->add_child_nocopy ((*i)->get_state());
1420 child->add_child_nocopy ((*i)->get_template());
1427 child = node->add_child ("EditGroups");
1428 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1429 child->add_child_nocopy ((*i)->get_state());
1432 child = node->add_child ("MixGroups");
1433 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1434 child->add_child_nocopy ((*i)->get_state());
1437 child = node->add_child ("Playlists");
1438 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1439 if (!(*i)->hidden()) {
1440 if (!(*i)->empty()) {
1442 child->add_child_nocopy ((*i)->get_state());
1444 child->add_child_nocopy ((*i)->get_template());
1450 child = node->add_child ("UnusedPlaylists");
1451 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1452 if (!(*i)->hidden()) {
1453 if (!(*i)->empty()) {
1455 child->add_child_nocopy ((*i)->get_state());
1457 child->add_child_nocopy ((*i)->get_template());
1465 child = node->add_child ("Click");
1466 child->add_child_nocopy (_click_io->state (full_state));
1470 child = node->add_child ("NamedSelections");
1471 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1473 child->add_child_nocopy ((*i)->get_state());
1478 node->add_child_nocopy (_tempo_map->get_state());
1481 node->add_child_copy (*_extra_xml);
1488 Session::set_state (const XMLNode& node)
1492 const XMLProperty* prop;
1495 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1497 if (node.name() != "Session"){
1498 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1502 StateManager::prohibit_save ();
1504 if ((prop = node.property ("name")) != 0) {
1505 _name = prop->value ();
1508 IO::disable_ports ();
1509 IO::disable_connecting ();
1511 /* Object loading order:
1528 if (use_config_midi_ports ()) {
1531 if ((child = find_named_node (node, "Path")) != 0) {
1532 /* XXX this XML content stuff horrible API design */
1533 string raid_path = _path + ':' + child->children().front()->content();
1534 setup_raid_path (raid_path);
1536 /* the path is already set */
1539 if ((child = find_named_node (node, "extra")) != 0) {
1540 _extra_xml = new XMLNode (*child);
1543 if ((child = find_named_node (node, "Options")) == 0) {
1544 error << _("Session: XML state has no options section") << endmsg;
1545 } else if (load_options (*child)) {
1548 if ((child = find_named_node (node, "Sources")) == 0) {
1549 error << _("Session: XML state has no sources section") << endmsg;
1551 } else if (load_sources (*child)) {
1555 if ((child = find_named_node (node, "Regions")) == 0) {
1556 error << _("Session: XML state has no Regions section") << endmsg;
1558 } else if (load_regions (*child)) {
1562 if ((child = find_named_node (node, "Playlists")) == 0) {
1563 error << _("Session: XML state has no playlists section") << endmsg;
1565 } else if (load_playlists (*child)) {
1569 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1571 } else if (load_unused_playlists (*child)) {
1575 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1576 if (load_named_selections (*child)) {
1581 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1582 error << _("Session: XML state has no diskstreams section") << endmsg;
1584 } else if (load_diskstreams (*child)) {
1588 if ((child = find_named_node (node, "Connections")) == 0) {
1589 error << _("Session: XML state has no connections section") << endmsg;
1591 } else if (load_connections (*child)) {
1595 if ((child = find_named_node (node, "Locations")) == 0) {
1596 error << _("Session: XML state has no locations section") << endmsg;
1598 } else if (_locations.set_state (*child)) {
1604 if ((location = _locations.auto_loop_location()) != 0) {
1605 set_auto_loop_location (location);
1608 if ((location = _locations.auto_punch_location()) != 0) {
1609 set_auto_punch_location (location);
1612 if ((location = _locations.end_location()) == 0) {
1613 _locations.add (end_location);
1615 delete end_location;
1616 end_location = location;
1619 if ((location = _locations.start_location()) == 0) {
1620 _locations.add (start_location);
1622 delete start_location;
1623 start_location = location;
1626 _locations.save_state (_("initial state"));
1628 if ((child = find_named_node (node, "EditGroups")) == 0) {
1629 error << _("Session: XML state has no edit groups section") << endmsg;
1631 } else if (load_edit_groups (*child)) {
1635 if ((child = find_named_node (node, "MixGroups")) == 0) {
1636 error << _("Session: XML state has no mix groups section") << endmsg;
1638 } else if (load_mix_groups (*child)) {
1642 if ((child = find_named_node (node, "TempoMap")) == 0) {
1643 error << _("Session: XML state has no Tempo Map section") << endmsg;
1645 } else if (_tempo_map->set_state (*child)) {
1649 if ((child = find_named_node (node, "Routes")) == 0) {
1650 error << _("Session: XML state has no routes section") << endmsg;
1652 } else if (load_routes (*child)) {
1656 if ((child = find_named_node (node, "Click")) == 0) {
1657 warning << _("Session: XML state has no click section") << endmsg;
1658 } else if (_click_io) {
1659 _click_io->set_state (*child);
1662 /* OK, now we can set edit mode */
1664 set_edit_mode (pending_edit_mode);
1666 /* here beginneth the second phase ... */
1668 StateReady (); /* EMIT SIGNAL */
1670 _state_of_the_state = Clean;
1672 StateManager::allow_save (_("initial state"), true);
1674 if (state_was_pending) {
1675 save_state (_current_snapshot_name);
1676 remove_pending_capture_state ();
1677 state_was_pending = false;
1683 /* we failed, re-enable state saving but don't actually save internal state */
1684 StateManager::allow_save (X_("ignored"), false);
1689 Session::load_routes (const XMLNode& node)
1692 XMLNodeConstIterator niter;
1695 nlist = node.children();
1699 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1701 if ((route = XMLRouteFactory (**niter)) == 0) {
1702 error << _("Session: cannot create Route from XML description.") << endmsg;
1713 Session::XMLRouteFactory (const XMLNode& node)
1715 if (node.name() != "Route") {
1719 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1720 return new AudioTrack (*this, node);
1722 return new Route (*this, node);
1727 Session::load_regions (const XMLNode& node)
1730 XMLNodeConstIterator niter;
1731 AudioRegion* region;
1733 nlist = node.children();
1737 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1739 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1740 error << _("Session: cannot create Region from XML description.") << endmsg;
1748 Session::XMLRegionFactory (const XMLNode& node, bool full)
1750 const XMLProperty* prop;
1754 AudioRegion::SourceList sources;
1755 uint32_t nchans = 1;
1758 if (node.name() != X_("Region")) {
1762 if ((prop = node.property (X_("channels"))) != 0) {
1763 nchans = atoi (prop->value().c_str());
1767 if ((prop = node.property (X_("source-0"))) == 0) {
1768 if ((prop = node.property ("source")) == 0) {
1769 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1774 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1776 if ((source = get_source (s_id)) == 0) {
1777 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1781 as = dynamic_cast<AudioSource*>(source);
1783 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1787 sources.push_back (as);
1789 /* pickup other channels */
1791 for (uint32_t n=1; n < nchans; ++n) {
1792 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1793 if ((prop = node.property (buf)) != 0) {
1794 sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1796 if ((source = get_source (s_id)) == 0) {
1797 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1801 as = dynamic_cast<AudioSource*>(source);
1803 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1806 sources.push_back (as);
1812 return new AudioRegion (sources, node);
1815 catch (failed_constructor& err) {
1821 Session::get_sources_as_xml ()
1824 XMLNode* node = new XMLNode (X_("Sources"));
1825 Glib::Mutex::Lock lm (audio_source_lock);
1827 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1828 node->add_child_nocopy ((*i).second->get_state());
1831 /* XXX get MIDI and other sources here */
1837 Session::path_from_region_name (string name, string identifier)
1839 char buf[PATH_MAX+1];
1841 string dir = discover_best_sound_dir ();
1843 for (n = 0; n < 999999; ++n) {
1844 if (identifier.length()) {
1845 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1846 identifier.c_str(), n);
1848 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1850 if (access (buf, F_OK) != 0) {
1860 Session::load_sources (const XMLNode& node)
1863 XMLNodeConstIterator niter;
1866 nlist = node.children();
1870 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1872 if ((source = XMLSourceFactory (**niter)) == 0) {
1873 error << _("Session: cannot create Source from XML description.") << endmsg;
1881 Session::XMLSourceFactory (const XMLNode& node)
1885 if (node.name() != "Source") {
1890 src = AudioFileSource::create (node);
1893 catch (failed_constructor& err) {
1894 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1902 Session::save_template (string template_name)
1905 string xml_path, bak_path, template_path;
1907 if (_state_of_the_state & CannotSave) {
1912 string dir = template_dir();
1914 if ((dp = opendir (dir.c_str()))) {
1917 if (mkdir (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)<0) {
1918 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1923 tree.set_root (&get_template());
1926 xml_path += template_name;
1927 xml_path += _template_suffix;
1929 ifstream in(xml_path.c_str());
1932 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1938 if (!tree.write (xml_path)) {
1939 error << _("mix template not saved") << endmsg;
1947 Session::rename_template (string old_name, string new_name)
1949 string old_path = template_dir() + old_name + _template_suffix;
1950 string new_path = template_dir() + new_name + _template_suffix;
1952 return rename (old_path.c_str(), new_path.c_str());
1956 Session::delete_template (string name)
1958 string template_path = template_dir();
1959 template_path += name;
1960 template_path += _template_suffix;
1962 return remove (template_path.c_str());
1966 Session::refresh_disk_space ()
1969 struct statfs statfsbuf;
1970 vector<space_and_path>::iterator i;
1971 Glib::Mutex::Lock lm (space_lock);
1974 /* get freespace on every FS that is part of the session path */
1976 _total_free_4k_blocks = 0;
1978 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1979 statfs ((*i).path.c_str(), &statfsbuf);
1981 scale = statfsbuf.f_bsize/4096.0;
1983 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1984 _total_free_4k_blocks += (*i).blocks;
1990 Session::ensure_sound_dir (string path, string& result)
1995 /* Ensure that the parent directory exists */
1997 if (mkdir (path.c_str(), 0775)) {
1998 if (errno != EEXIST) {
1999 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
2004 /* Ensure that the sounds directory exists */
2008 result += sound_dir_name;
2010 if (mkdir (result.c_str(), 0775)) {
2011 if (errno != EEXIST) {
2012 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
2019 dead += dead_sound_dir_name;
2021 if (mkdir (dead.c_str(), 0775)) {
2022 if (errno != EEXIST) {
2023 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
2030 peak += peak_dir_name;
2032 if (mkdir (peak.c_str(), 0775)) {
2033 if (errno != EEXIST) {
2034 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
2039 /* callers expect this to be terminated ... */
2046 Session::discover_best_sound_dir (bool destructive)
2048 vector<space_and_path>::iterator i;
2051 /* destructive files all go into the same place */
2057 /* handle common case without system calls */
2059 if (session_dirs.size() == 1) {
2063 /* OK, here's the algorithm we're following here:
2065 We want to select which directory to use for
2066 the next file source to be created. Ideally,
2067 we'd like to use a round-robin process so as to
2068 get maximum performance benefits from splitting
2069 the files across multiple disks.
2071 However, in situations without much diskspace, an
2072 RR approach may end up filling up a filesystem
2073 with new files while others still have space.
2074 Its therefore important to pay some attention to
2075 the freespace in the filesystem holding each
2076 directory as well. However, if we did that by
2077 itself, we'd keep creating new files in the file
2078 system with the most space until it was as full
2079 as all others, thus negating any performance
2080 benefits of this RAID-1 like approach.
2082 So, we use a user-configurable space threshold. If
2083 there are at least 2 filesystems with more than this
2084 much space available, we use RR selection between them.
2085 If not, then we pick the filesystem with the most space.
2087 This gets a good balance between the two
2091 refresh_disk_space ();
2093 int free_enough = 0;
2095 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2096 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2101 if (free_enough >= 2) {
2103 bool found_it = false;
2105 /* use RR selection process, ensuring that the one
2109 i = last_rr_session_dir;
2112 if (++i == session_dirs.end()) {
2113 i = session_dirs.begin();
2116 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2117 if (ensure_sound_dir ((*i).path, result) == 0) {
2118 last_rr_session_dir = i;
2124 } while (i != last_rr_session_dir);
2127 result = sound_dir();
2132 /* pick FS with the most freespace (and that
2133 seems to actually work ...)
2136 vector<space_and_path> sorted;
2137 space_and_path_ascending_cmp cmp;
2139 sorted = session_dirs;
2140 sort (sorted.begin(), sorted.end(), cmp);
2142 for (i = sorted.begin(); i != sorted.end(); ++i) {
2143 if (ensure_sound_dir ((*i).path, result) == 0) {
2144 last_rr_session_dir = i;
2149 /* if the above fails, fall back to the most simplistic solution */
2151 if (i == sorted.end()) {
2160 Session::load_playlists (const XMLNode& node)
2163 XMLNodeConstIterator niter;
2166 nlist = node.children();
2170 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2172 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2173 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2181 Session::load_unused_playlists (const XMLNode& node)
2184 XMLNodeConstIterator niter;
2187 nlist = node.children();
2191 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2193 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2194 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2198 // now manually untrack it
2200 track_playlist (playlist, false);
2208 Session::XMLPlaylistFactory (const XMLNode& node)
2211 return new AudioPlaylist (*this, node);
2214 catch (failed_constructor& err) {
2220 Session::load_named_selections (const XMLNode& node)
2223 XMLNodeConstIterator niter;
2226 nlist = node.children();
2230 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2232 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2233 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2241 Session::XMLNamedSelectionFactory (const XMLNode& node)
2244 return new NamedSelection (*this, node);
2247 catch (failed_constructor& err) {
2253 Session::dead_sound_dir () const
2256 res += dead_sound_dir_name;
2262 Session::sound_dir () const
2265 res += sound_dir_name;
2271 Session::tape_dir () const
2274 res += tape_dir_name;
2280 Session::peak_dir () const
2283 res += peak_dir_name;
2289 Session::automation_dir () const
2292 res += "automation/";
2297 Session::template_dir ()
2299 string path = get_user_ardour_path();
2300 path += "templates/";
2306 Session::suffixed_search_path (string suffix, bool data)
2310 path += get_user_ardour_path();
2311 if (path[path.length()-1] != ':') {
2316 path += get_system_data_path();
2318 path += get_system_module_path();
2321 vector<string> split_path;
2323 split (path, split_path, ':');
2326 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2331 if (distance (i, split_path.end()) != 1) {
2340 Session::template_path ()
2342 return suffixed_search_path (X_("templates"), true);
2346 Session::control_protocol_path ()
2348 return suffixed_search_path (X_("surfaces"), false);
2352 Session::load_connections (const XMLNode& node)
2354 XMLNodeList nlist = node.children();
2355 XMLNodeConstIterator niter;
2359 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2360 if ((*niter)->name() == "InputConnection") {
2361 add_connection (new ARDOUR::InputConnection (**niter));
2362 } else if ((*niter)->name() == "OutputConnection") {
2363 add_connection (new ARDOUR::OutputConnection (**niter));
2365 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2374 Session::load_edit_groups (const XMLNode& node)
2376 return load_route_groups (node, true);
2380 Session::load_mix_groups (const XMLNode& node)
2382 return load_route_groups (node, false);
2386 Session::load_route_groups (const XMLNode& node, bool edit)
2388 XMLNodeList nlist = node.children();
2389 XMLNodeConstIterator niter;
2394 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2395 if ((*niter)->name() == "RouteGroup") {
2397 rg = add_edit_group ("");
2398 rg->set_state (**niter);
2400 rg = add_mix_group ("");
2401 rg->set_state (**niter);
2410 Session::swap_configuration(Configuration** new_config)
2412 Glib::RWLock::WriterLock lm (route_lock); // jlc - WHY?
2413 Configuration* tmp = *new_config;
2414 *new_config = Config;
2420 Session::copy_configuration(Configuration* new_config)
2422 Glib::RWLock::WriterLock lm (route_lock);
2423 new_config = new Configuration(*Config);
2427 state_file_filter (const string &str, void *arg)
2429 return (str.length() > strlen(Session::statefile_suffix()) &&
2430 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2434 bool operator()(const string* a, const string* b) {
2440 remove_end(string* state)
2442 string statename(*state);
2444 string::size_type start,end;
2445 if ((start = statename.find_last_of ('/')) != string::npos) {
2446 statename = statename.substr (start+1);
2449 if ((end = statename.rfind(".ardour")) < 0) {
2450 end = statename.length();
2453 return new string(statename.substr (0, end));
2457 Session::possible_states (string path)
2459 PathScanner scanner;
2460 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2462 transform(states->begin(), states->end(), states->begin(), remove_end);
2465 sort (states->begin(), states->end(), cmp);
2471 Session::possible_states () const
2473 return possible_states(_path);
2477 Session::auto_save()
2479 save_state (_current_snapshot_name);
2483 Session::add_edit_group (string name)
2485 RouteGroup* rg = new RouteGroup (*this, name);
2486 edit_groups.push_back (rg);
2487 edit_group_added (rg); /* EMIT SIGNAL */
2493 Session::add_mix_group (string name)
2495 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2496 mix_groups.push_back (rg);
2497 mix_group_added (rg); /* EMIT SIGNAL */
2503 Session::remove_edit_group (RouteGroup& rg)
2505 list<RouteGroup*>::iterator i;
2507 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2508 (*i)->apply (&Route::drop_edit_group, this);
2509 edit_groups.erase (i);
2510 edit_group_removed (); /* EMIT SIGNAL */
2517 Session::remove_mix_group (RouteGroup& rg)
2519 list<RouteGroup*>::iterator i;
2521 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2522 (*i)->apply (&Route::drop_mix_group, this);
2523 mix_groups.erase (i);
2524 mix_group_removed (); /* EMIT SIGNAL */
2531 Session::mix_group_by_name (string name)
2533 list<RouteGroup *>::iterator i;
2535 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2536 if ((*i)->name() == name) {
2544 Session::edit_group_by_name (string name)
2546 list<RouteGroup *>::iterator i;
2548 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2549 if ((*i)->name() == name) {
2557 Session::set_meter_hold (float val)
2560 MeterHoldChanged(); // emit
2564 Session::set_meter_falloff (float val)
2566 _meter_falloff = val;
2567 MeterFalloffChanged(); // emit
2572 Session::begin_reversible_command (string name, UndoAction* private_undo)
2574 current_cmd.clear ();
2575 current_cmd.set_name (name);
2578 current_cmd.add_undo (*private_undo);
2583 Session::commit_reversible_command (UndoAction* private_redo)
2588 current_cmd.add_redo_no_execute (*private_redo);
2591 gettimeofday (&now, 0);
2592 current_cmd.set_timestamp (now);
2594 history.add (current_cmd);
2597 Session::GlobalRouteBooleanState
2598 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2600 GlobalRouteBooleanState s;
2601 Glib::RWLock::ReaderLock lm (route_lock);
2603 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2604 if (!(*i)->hidden()) {
2605 RouteBooleanState v;
2608 v.second = ((*i)->*method)();
2617 Session::GlobalRouteMeterState
2618 Session::get_global_route_metering ()
2620 GlobalRouteMeterState s;
2621 Glib::RWLock::ReaderLock lm (route_lock);
2623 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2624 if (!(*i)->hidden()) {
2628 v.second = (*i)->meter_point();
2638 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2640 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2641 i->first->set_meter_point (i->second, arg);
2646 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2648 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2649 (i->first->*method) (i->second, arg);
2654 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2656 set_global_route_boolean (s, &Route::set_mute, src);
2660 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2662 set_global_route_boolean (s, &Route::set_solo, src);
2666 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2668 set_global_route_boolean (s, &Route::set_record_enable, src);
2672 Session::global_mute_memento (void* src)
2674 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2678 Session::global_metering_memento (void* src)
2680 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2684 Session::global_solo_memento (void* src)
2686 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2690 Session::global_record_enable_memento (void* src)
2692 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2696 template_filter (const string &str, void *arg)
2698 return (str.length() > strlen(Session::template_suffix()) &&
2699 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2703 Session::get_template_list (list<string> &template_names)
2705 vector<string *> *templates;
2706 PathScanner scanner;
2709 path = template_path ();
2711 templates = scanner (path, template_filter, 0, false, true);
2713 vector<string*>::iterator i;
2714 for (i = templates->begin(); i != templates->end(); ++i) {
2715 string fullpath = *(*i);
2718 start = fullpath.find_last_of ('/') + 1;
2719 if ((end = fullpath.find_last_of ('.')) <0) {
2720 end = fullpath.length();
2723 template_names.push_back(fullpath.substr(start, (end-start)));
2728 Session::read_favorite_dirs (FavoriteDirs & favs)
2730 string path = get_user_ardour_path();
2731 path += "/favorite_dirs";
2733 ifstream fav (path.c_str());
2738 if (errno != ENOENT) {
2739 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2750 getline(fav, newfav);
2756 favs.push_back (newfav);
2763 Session::write_favorite_dirs (FavoriteDirs & favs)
2765 string path = get_user_ardour_path();
2766 path += "/favorite_dirs";
2768 ofstream fav (path.c_str());
2774 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2775 fav << (*i) << endl;
2782 accept_all_non_peak_files (const string& path, void *arg)
2784 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2788 accept_all_state_files (const string& path, void *arg)
2790 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2794 Session::find_all_sources (string path, set<string>& result)
2799 if (!tree.read (path)) {
2803 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2808 XMLNodeConstIterator niter;
2810 nlist = node->children();
2814 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2818 if ((prop = (*niter)->property (X_("name"))) == 0) {
2822 if (prop->value()[0] == '/') {
2823 /* external file, ignore */
2827 string path = _path; /* /-terminated */
2828 path += sound_dir_name;
2830 path += prop->value();
2832 result.insert (path);
2839 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2841 PathScanner scanner;
2842 vector<string*>* state_files;
2844 string this_snapshot_path;
2850 if (ripped[ripped.length()-1] == '/') {
2851 ripped = ripped.substr (0, ripped.length() - 1);
2854 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2856 if (state_files == 0) {
2861 this_snapshot_path = _path;
2862 this_snapshot_path += _current_snapshot_name;
2863 this_snapshot_path += _statefile_suffix;
2865 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2867 if (exclude_this_snapshot && **i == this_snapshot_path) {
2871 if (find_all_sources (**i, result) < 0) {
2880 Session::cleanup_sources (Session::cleanup_report& rep)
2882 vector<Source*> dead_sources;
2883 vector<Playlist*> playlists_tbd;
2884 PathScanner scanner;
2886 vector<space_and_path>::iterator i;
2887 vector<space_and_path>::iterator nexti;
2888 vector<string*>* soundfiles;
2889 vector<string> unused;
2890 set<string> all_sources;
2895 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2897 /* step 1: consider deleting all unused playlists */
2899 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2902 status = AskAboutPlaylistDeletion (*x);
2911 playlists_tbd.push_back (*x);
2915 /* leave it alone */
2920 /* now delete any that were marked for deletion */
2922 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2923 PlaylistList::iterator foo;
2925 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2926 unused_playlists.erase (foo);
2931 /* step 2: clear the undo/redo history for all playlists */
2933 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2934 (*x)->drop_all_states ();
2937 /* step 3: find all un-referenced sources */
2942 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2944 AudioSourceList::iterator tmp;
2949 /* only remove files that are not in use and have some size
2950 to them. otherwise we remove the current "nascent"
2954 if ((*i).second->use_cnt() == 0 && (*i).second->length() > 0) {
2955 dead_sources.push_back (i->second);
2957 /* remove this source from our own list to avoid us
2958 adding it to the list of all sources below
2961 audio_sources.erase (i);
2967 /* Step 4: get rid of all regions in the region list that use any dead sources
2968 in case the sources themselves don't go away (they might be referenced in
2972 for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2974 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2975 AudioRegionList::iterator tmp;
2983 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2984 if (&ar->source (n) == (*i)) {
2985 /* this region is dead */
2994 /* build a list of all the possible sound directories for the session */
2996 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
3001 sound_path += (*i).path;
3002 sound_path += sound_dir_name;
3004 if (nexti != session_dirs.end()) {
3011 /* now do the same thing for the files that ended up in the sounds dir(s)
3012 but are not referenced as sources in any snapshot.
3015 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
3017 if (soundfiles == 0) {
3021 /* find all sources, but don't use this snapshot because the
3022 state file on disk still references sources we may have already
3026 find_all_sources_across_snapshots (all_sources, true);
3028 /* add our current source list
3031 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
3032 AudioFileSource* fs;
3034 if ((fs = dynamic_cast<AudioFileSource*> ((*i).second)) != 0) {
3035 all_sources.insert (fs->path());
3039 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
3044 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
3054 unused.push_back (spath);
3058 /* now try to move all unused files into the "dead_sounds" directory(ies) */
3060 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
3061 struct stat statbuf;
3063 rep.paths.push_back (*x);
3064 if (stat ((*x).c_str(), &statbuf) == 0) {
3065 rep.space += statbuf.st_size;
3070 /* don't move the file across filesystems, just
3071 stick it in the `dead_sound_dir_name' directory
3072 on whichever filesystem it was already on.
3075 newpath = Glib::path_get_dirname (*x);
3076 newpath = Glib::path_get_dirname (newpath);
3079 newpath += dead_sound_dir_name;
3081 newpath += Glib::path_get_basename ((*x));
3083 if (access (newpath.c_str(), F_OK) == 0) {
3085 /* the new path already exists, try versioning */
3087 char buf[PATH_MAX+1];
3091 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
3094 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
3095 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
3099 if (version == 999) {
3100 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
3104 newpath = newpath_v;
3109 /* it doesn't exist, or we can't read it or something */
3113 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
3114 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
3115 (*x), newpath, strerror (errno))
3121 /* see if there an easy to find peakfile for this file, and remove it.
3124 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
3125 peakpath += ".peak";
3127 if (access (peakpath.c_str(), W_OK) == 0) {
3128 if (::unlink (peakpath.c_str()) != 0) {
3129 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3130 peakpath, _path, strerror (errno))
3132 /* try to back out */
3133 rename (newpath.c_str(), _path.c_str());
3142 /* dump the history list */
3146 /* save state so we don't end up a session file
3147 referring to non-existent sources.
3153 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3158 Session::cleanup_trash_sources (Session::cleanup_report& rep)
3160 vector<space_and_path>::iterator i;
3161 string dead_sound_dir;
3162 struct dirent* dentry;
3163 struct stat statbuf;
3169 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3171 dead_sound_dir = (*i).path;
3172 dead_sound_dir += dead_sound_dir_name;
3174 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
3178 while ((dentry = readdir (dead)) != 0) {
3180 /* avoid '.' and '..' */
3182 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
3183 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3189 fullpath = dead_sound_dir;
3191 fullpath += dentry->d_name;
3193 if (stat (fullpath.c_str(), &statbuf)) {
3197 if (!S_ISREG (statbuf.st_mode)) {
3201 if (unlink (fullpath.c_str())) {
3202 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3203 fullpath, strerror (errno))
3207 rep.paths.push_back (dentry->d_name);
3208 rep.space += statbuf.st_size;
3219 Session::set_dirty ()
3221 bool was_dirty = dirty();
3223 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3226 DirtyChanged(); /* EMIT SIGNAL */
3232 Session::set_clean ()
3234 bool was_dirty = dirty();
3236 _state_of_the_state = Clean;
3239 DirtyChanged(); /* EMIT SIGNAL */