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.
22 #include "libardour-config.h"
25 #define __STDC_FORMAT_MACROS 1
34 #include <cstdio> /* snprintf(3) ... grrr */
49 #include <sys/param.h>
50 #include <sys/mount.h>
54 #include <glibmm/thread.h>
56 #include "midi++/mmc.h"
57 #include "midi++/port.h"
59 #include "pbd/boost_debug.h"
60 #include "pbd/enumwriter.h"
61 #include "pbd/error.h"
62 #include "pbd/pathscanner.h"
63 #include "pbd/pthread_utils.h"
64 #include "pbd/search_path.h"
65 #include "pbd/stacktrace.h"
67 #include "ardour/audio_diskstream.h"
68 #include "ardour/audio_track.h"
69 #include "ardour/audioengine.h"
70 #include "ardour/audiofilesource.h"
71 #include "ardour/audioplaylist.h"
72 #include "ardour/audioregion.h"
73 #include "ardour/auditioner.h"
74 #include "ardour/buffer.h"
75 #include "ardour/butler.h"
76 #include "ardour/configuration.h"
77 #include "ardour/control_protocol_manager.h"
78 #include "ardour/crossfade.h"
79 #include "ardour/cycle_timer.h"
80 #include "ardour/directory_names.h"
81 #include "ardour/filename_extensions.h"
82 #include "ardour/io_processor.h"
83 #include "ardour/location.h"
84 #include "ardour/midi_diskstream.h"
85 #include "ardour/midi_patch_manager.h"
86 #include "ardour/midi_playlist.h"
87 #include "ardour/midi_region.h"
88 #include "ardour/midi_source.h"
89 #include "ardour/midi_track.h"
90 #include "ardour/named_selection.h"
91 #include "ardour/processor.h"
92 #include "ardour/region_factory.h"
93 #include "ardour/route_group.h"
94 #include "ardour/send.h"
95 #include "ardour/session.h"
96 #include "ardour/session_directory.h"
97 #include "ardour/session_metadata.h"
98 #include "ardour/session_state_utils.h"
99 #include "ardour/session_playlists.h"
100 #include "ardour/session_utils.h"
101 #include "ardour/silentfilesource.h"
102 #include "ardour/slave.h"
103 #include "ardour/smf_source.h"
104 #include "ardour/sndfile_helpers.h"
105 #include "ardour/sndfilesource.h"
106 #include "ardour/source_factory.h"
107 #include "ardour/template_utils.h"
108 #include "ardour/tempo.h"
109 #include "ardour/ticker.h"
110 #include "ardour/user_bundle.h"
111 #include "ardour/utils.h"
112 #include "ardour/utils.h"
113 #include "ardour/version.h"
114 #include "ardour/playlist_factory.h"
116 #include "control_protocol/control_protocol.h"
122 using namespace ARDOUR;
126 Session::first_stage_init (string fullpath, string snapshot_name)
128 if (fullpath.length() == 0) {
130 throw failed_constructor();
133 char buf[PATH_MAX+1];
134 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
135 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
137 throw failed_constructor();
142 if (_path[_path.length()-1] != '/') {
146 if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
147 cerr << "Session non-writable based on " << _path << endl;
150 cerr << "Session writable based on " << _path << endl;
154 /* these two are just provisional settings. set_state()
155 will likely override them.
158 _name = _current_snapshot_name = snapshot_name;
160 set_history_depth (Config->get_history_depth());
162 _current_frame_rate = _engine.frame_rate ();
163 _nominal_frame_rate = _current_frame_rate;
164 _base_frame_rate = _current_frame_rate;
166 _tempo_map = new TempoMap (_current_frame_rate);
167 _tempo_map->StateChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
170 _non_soloed_outs_muted = false;
172 g_atomic_int_set (&processing_prohibited, 0);
173 _transport_speed = 0;
174 _last_transport_speed = 0;
175 _target_transport_speed = 0;
176 auto_play_legal = false;
177 transport_sub_state = 0;
178 _transport_frame = 0;
179 _requested_return_frame = -1;
180 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
181 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
182 g_atomic_int_set (&_record_status, Disabled);
183 loop_changing = false;
186 _last_roll_location = 0;
187 _last_record_location = 0;
188 pending_locate_frame = 0;
189 pending_locate_roll = false;
190 pending_locate_flush = false;
191 state_was_pending = false;
193 outbound_mtc_timecode_frame = 0;
194 next_quarter_frame_to_send = -1;
195 current_block_size = 0;
196 solo_update_disabled = false;
197 _have_captured = false;
198 _worst_output_latency = 0;
199 _worst_input_latency = 0;
200 _worst_track_latency = 0;
201 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
202 _was_seamless = Config->get_seamless_loop ();
204 session_send_mmc = false;
205 session_send_mtc = false;
206 g_atomic_int_set (&_playback_load, 100);
207 g_atomic_int_set (&_capture_load, 100);
208 g_atomic_int_set (&_playback_load_min, 100);
209 g_atomic_int_set (&_capture_load_min, 100);
212 _exporting_realtime = false;
213 _gain_automation_buffer = 0;
214 _pan_automation_buffer = 0;
216 pending_abort = false;
217 destructive_index = 0;
218 first_file_data_format_reset = true;
219 first_file_header_format_reset = true;
220 post_export_sync = false;
223 AudioDiskstream::allocate_working_buffers();
225 /* default short fade = 15ms */
227 Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
228 SndFileSource::setup_standard_crossfades (*this, frame_rate());
230 last_mmc_step.tv_sec = 0;
231 last_mmc_step.tv_usec = 0;
234 /* click sounds are unset by default, which causes us to internal
235 waveforms for clicks.
239 click_emphasis_length = 0;
242 process_function = &Session::process_with_events;
244 if (config.get_use_video_sync()) {
245 waiting_for_sync_offset = true;
247 waiting_for_sync_offset = false;
250 last_timecode_when = 0;
251 _timecode_offset = 0;
252 _timecode_offset_negative = true;
253 last_timecode_valid = false;
257 last_rr_session_dir = session_dirs.begin();
258 refresh_disk_space ();
260 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
264 average_slave_delta = 1800; // !!! why 1800 ????
265 have_first_delta_accumulator = false;
266 delta_accumulator_cnt = 0;
267 _slave_state = Stopped;
269 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
271 /* These are all static "per-class" signals */
273 RegionFactory::CheckNewRegion.connect_same_thread (*this, boost::bind (&Session::add_region, this, _1));
274 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
275 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
276 Processor::ProcessorCreated.connect_same_thread (*this, boost::bind (&Session::add_processor, this, _1));
277 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
278 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
279 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
281 /* stop IO objects from doing stuff until we're ready for them */
283 Delivery::disable_panners ();
284 IO::disable_connecting ();
288 Session::second_stage_init (bool new_session)
290 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
293 if (load_state (_current_snapshot_name)) {
296 remove_empty_sounds ();
299 if (_butler->start_thread()) {
303 if (start_midi_thread ()) {
307 // set_state() will call setup_raid_path(), but if it's a new session we need
308 // to call setup_raid_path() here.
311 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
315 setup_raid_path(_path);
318 /* we can't save till after ::when_engine_running() is called,
319 because otherwise we save state with no connections made.
320 therefore, we reset _state_of_the_state because ::set_state()
321 will have cleared it.
323 we also have to include Loading so that any events that get
324 generated between here and the end of ::when_engine_running()
325 will be processed directly rather than queued.
328 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
331 _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
332 _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
333 setup_click_sounds (0);
334 setup_midi_control ();
336 /* Pay attention ... */
338 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
339 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
342 when_engine_running();
345 /* handle this one in a different way than all others, so that its clear what happened */
347 catch (AudioEngine::PortRegistrationFailure& err) {
348 error << err.what() << endmsg;
356 BootMessage (_("Reset Remote Controls"));
358 send_full_time_code (0);
359 _engine.transport_locate (0);
360 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
361 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
363 MidiClockTicker::instance().set_session (this);
364 MIDI::Name::MidiPatchManager::instance().set_session (this);
366 /* initial program change will be delivered later; see ::config_changed() */
368 BootMessage (_("Reset Control Protocols"));
370 ControlProtocolManager::instance().set_session (this);
372 config.set_end_marker_is_free (new_session);
374 _state_of_the_state = Clean;
376 DirtyChanged (); /* EMIT SIGNAL */
378 if (state_was_pending) {
379 save_state (_current_snapshot_name);
380 remove_pending_capture_state ();
381 state_was_pending = false;
384 BootMessage (_("Session loading complete"));
390 Session::raid_path () const
392 SearchPath raid_search_path;
394 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
395 raid_search_path += sys::path((*i).path);
398 return raid_search_path.to_string ();
402 Session::setup_raid_path (string path)
411 session_dirs.clear ();
413 SearchPath search_path(path);
414 SearchPath sound_search_path;
415 SearchPath midi_search_path;
417 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
418 sp.path = (*i).to_string ();
419 sp.blocks = 0; // not needed
420 session_dirs.push_back (sp);
422 SessionDirectory sdir(sp.path);
424 sound_search_path += sdir.sound_path ();
425 midi_search_path += sdir.midi_path ();
428 // set the search path for each data type
429 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
430 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
432 // reset the round-robin soundfile path thingie
433 last_rr_session_dir = session_dirs.begin();
437 Session::path_is_within_session (const std::string& path)
439 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
440 if (path.find ((*i).path) == 0) {
448 Session::ensure_subdirs ()
452 dir = session_directory().peak_path().to_string();
454 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
455 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
459 dir = session_directory().sound_path().to_string();
461 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
462 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
466 dir = session_directory().midi_path().to_string();
468 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
469 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
473 dir = session_directory().dead_sound_path().to_string();
475 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
476 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
480 dir = session_directory().export_path().to_string();
482 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
483 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
487 dir = analysis_dir ();
489 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
490 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
498 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
501 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
502 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
506 if (ensure_subdirs ()) {
510 /* check new_session so we don't overwrite an existing one */
512 if (!mix_template.empty()) {
513 std::string in_path = mix_template;
515 ifstream in(in_path.c_str());
518 string out_path = _path;
520 out_path += statefile_suffix;
522 ofstream out(out_path.c_str());
527 // okay, session is set up. Treat like normal saved
528 // session from now on.
534 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
540 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
547 /* Instantiate metadata */
549 _metadata = new SessionMetadata ();
551 /* set initial start + end point */
553 start_location->set_end (0);
554 _locations.add (start_location);
556 end_location->set_end (initial_length);
557 _locations.add (end_location);
559 _state_of_the_state = Clean;
568 Session::load_diskstreams (const XMLNode& node)
571 XMLNodeConstIterator citer;
573 clist = node.children();
575 for (citer = clist.begin(); citer != clist.end(); ++citer) {
578 /* diskstreams added automatically by DiskstreamCreated handler */
579 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
580 AudioDiskstream* dsp (new AudioDiskstream (*this, **citer));
581 boost::shared_ptr<AudioDiskstream> dstream (dsp);
582 add_diskstream (dstream);
583 } else if ((*citer)->name() == "MidiDiskstream") {
584 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
585 add_diskstream (dstream);
587 error << _("Session: unknown diskstream type in XML") << endmsg;
591 catch (failed_constructor& err) {
592 error << _("Session: could not load diskstream via XML state") << endmsg;
601 Session::maybe_write_autosave()
603 if (dirty() && record_status() != Recording) {
604 save_state("", true);
609 Session::remove_pending_capture_state ()
611 sys::path pending_state_file_path(_session_dir->root_path());
613 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
617 sys::remove (pending_state_file_path);
619 catch(sys::filesystem_error& ex)
621 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
622 pending_state_file_path.to_string(), ex.what()) << endmsg;
626 /** Rename a state file.
627 * @param snapshot_name Snapshot name.
630 Session::rename_state (string old_name, string new_name)
632 if (old_name == _current_snapshot_name || old_name == _name) {
633 /* refuse to rename the current snapshot or the "main" one */
637 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
638 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
640 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
641 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
645 sys::rename (old_xml_path, new_xml_path);
647 catch (const sys::filesystem_error& err)
649 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
650 old_name, new_name, err.what()) << endmsg;
654 /** Remove a state file.
655 * @param snapshot_name Snapshot name.
658 Session::remove_state (string snapshot_name)
660 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
661 // refuse to remove the current snapshot or the "main" one
665 sys::path xml_path(_session_dir->root_path());
667 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
669 if (!create_backup_file (xml_path)) {
670 // don't remove it if a backup can't be made
671 // create_backup_file will log the error.
676 sys::remove (xml_path);
680 Session::save_state (string snapshot_name, bool pending)
683 sys::path xml_path(_session_dir->root_path());
685 if (!_writable || (_state_of_the_state & CannotSave)) {
689 if (!_engine.connected ()) {
690 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
695 /* tell sources we're saving first, in case they write out to a new file
696 * which should be saved with the state rather than the old one */
697 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
698 i->second->session_saved();
700 tree.set_root (&get_state());
702 if (snapshot_name.empty()) {
703 snapshot_name = _current_snapshot_name;
708 /* proper save: use statefile_suffix (.ardour in English) */
710 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
712 /* make a backup copy of the old file */
714 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
715 // create_backup_file will log the error
721 /* pending save: use pending_suffix (.pending in English) */
722 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
725 sys::path tmp_path(_session_dir->root_path());
727 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
729 // cerr << "actually writing state to " << xml_path.to_string() << endl;
731 if (!tree.write (tmp_path.to_string())) {
732 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
733 sys::remove (tmp_path);
738 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
739 error << string_compose (_("could not rename temporary session file %1 to %2"),
740 tmp_path.to_string(), xml_path.to_string()) << endmsg;
741 sys::remove (tmp_path);
748 save_history (snapshot_name);
750 bool was_dirty = dirty();
752 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
755 DirtyChanged (); /* EMIT SIGNAL */
758 StateSaved (snapshot_name); /* EMIT SIGNAL */
765 Session::restore_state (string snapshot_name)
767 if (load_state (snapshot_name) == 0) {
768 set_state (*state_tree->root(), Stateful::loading_state_version);
775 Session::load_state (string snapshot_name)
780 state_was_pending = false;
782 /* check for leftover pending state from a crashed capture attempt */
784 sys::path xmlpath(_session_dir->root_path());
785 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
787 if (sys::exists (xmlpath)) {
789 /* there is pending state from a crashed capture attempt */
791 if (*AskAboutPendingState()) {
792 state_was_pending = true;
796 if (!state_was_pending) {
797 xmlpath = _session_dir->root_path();
798 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
801 if (!sys::exists (xmlpath)) {
802 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
806 state_tree = new XMLTree;
810 /* writable() really reflects the whole folder, but if for any
811 reason the session state file can't be written to, still
815 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
819 if (!state_tree->read (xmlpath.to_string())) {
820 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
826 XMLNode& root (*state_tree->root());
828 if (root.name() != X_("Session")) {
829 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
835 const XMLProperty* prop;
837 if ((prop = root.property ("version")) == 0) {
838 /* no version implies very old version of Ardour */
839 Stateful::loading_state_version = 1000;
845 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
846 Stateful::loading_state_version = (major * 1000) + minor;
849 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
851 sys::path backup_path(_session_dir->root_path());
853 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
855 // only create a backup once
856 if (sys::exists (backup_path)) {
860 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
861 xmlpath.to_string(), backup_path.to_string())
866 sys::copy_file (xmlpath, backup_path);
868 catch(sys::filesystem_error& ex)
870 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
871 xmlpath.to_string(), ex.what())
881 Session::load_options (const XMLNode& node)
883 LocaleGuard lg (X_("POSIX"));
884 config.set_variables (node);
895 Session::get_template()
897 /* if we don't disable rec-enable, diskstreams
898 will believe they need to store their capture
899 sources in their state node.
902 disable_record (false);
908 Session::state(bool full_state)
910 XMLNode* node = new XMLNode("Session");
913 // store libardour version, just in case
915 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
916 node->add_property("version", string(buf));
918 /* store configuration settings */
922 node->add_property ("name", _name);
923 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
924 node->add_property ("sample-rate", buf);
926 if (session_dirs.size() > 1) {
930 vector<space_and_path>::iterator i = session_dirs.begin();
931 vector<space_and_path>::iterator next;
933 ++i; /* skip the first one */
937 while (i != session_dirs.end()) {
941 if (next != session_dirs.end()) {
951 child = node->add_child ("Path");
952 child->add_content (p);
956 /* save the ID counter */
958 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
959 node->add_property ("id-counter", buf);
961 /* various options */
963 node->add_child_nocopy (config.get_variables ());
965 node->add_child_nocopy (_metadata->get_state());
967 child = node->add_child ("Sources");
970 Glib::Mutex::Lock sl (source_lock);
972 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
974 /* Don't save information about non-destructive file sources that are empty */
975 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
977 boost::shared_ptr<AudioFileSource> fs;
978 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
979 if (!fs->destructive()) {
980 if (fs->length(fs->timeline_position()) == 0) {
986 child->add_child_nocopy (siter->second->get_state());
990 child = node->add_child ("Regions");
993 Glib::Mutex::Lock rl (region_lock);
995 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
997 /* only store regions not attached to playlists */
999 if (i->second->playlist() == 0) {
1000 child->add_child_nocopy (i->second->state (true));
1005 child = node->add_child ("DiskStreams");
1008 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1009 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1010 if (!(*i)->hidden()) {
1011 child->add_child_nocopy ((*i)->get_state());
1017 node->add_child_nocopy (_locations.get_state());
1019 // for a template, just create a new Locations, populate it
1020 // with the default start and end, and get the state for that.
1022 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1023 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1026 end->set_end(compute_initial_length());
1028 node->add_child_nocopy (loc.get_state());
1031 child = node->add_child ("Bundles");
1033 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1034 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1035 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1037 child->add_child_nocopy (b->get_state());
1042 child = node->add_child ("Routes");
1044 boost::shared_ptr<RouteList> r = routes.reader ();
1046 RoutePublicOrderSorter cmp;
1047 RouteList public_order (*r);
1048 public_order.sort (cmp);
1050 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1051 if (!(*i)->is_hidden()) {
1053 child->add_child_nocopy ((*i)->get_state());
1055 child->add_child_nocopy ((*i)->get_template());
1061 playlists->add_state (node, full_state);
1063 child = node->add_child ("RouteGroups");
1064 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1065 child->add_child_nocopy ((*i)->get_state());
1069 child = node->add_child ("Click");
1070 child->add_child_nocopy (_click_io->state (full_state));
1074 child = node->add_child ("NamedSelections");
1075 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1077 child->add_child_nocopy ((*i)->get_state());
1082 node->add_child_nocopy (_tempo_map->get_state());
1084 node->add_child_nocopy (get_control_protocol_state());
1087 node->add_child_copy (*_extra_xml);
1094 Session::get_control_protocol_state ()
1096 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1097 return cpm.get_state();
1101 Session::set_state (const XMLNode& node, int version)
1105 const XMLProperty* prop;
1108 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1110 if (node.name() != X_("Session")){
1111 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1115 if ((prop = node.property ("version")) != 0) {
1116 version = atoi (prop->value ()) * 1000;
1119 if ((prop = node.property ("name")) != 0) {
1120 _name = prop->value ();
1123 if ((prop = node.property (X_("sample-rate"))) != 0) {
1125 _nominal_frame_rate = atoi (prop->value());
1127 if (_nominal_frame_rate != _current_frame_rate) {
1128 if (*AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1134 setup_raid_path(_session_dir->root_path().to_string());
1136 if ((prop = node.property (X_("id-counter"))) != 0) {
1138 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1139 ID::init_counter (x);
1141 /* old sessions used a timebased counter, so fake
1142 the startup ID counter based on a standard
1147 ID::init_counter (now);
1151 IO::disable_connecting ();
1153 /* Object loading order:
1158 MIDI Control // relies on data from Options/Config
1172 if ((child = find_named_node (node, "Extra")) != 0) {
1173 _extra_xml = new XMLNode (*child);
1176 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1177 load_options (*child);
1178 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1179 load_options (*child);
1181 error << _("Session: XML state has no options section") << endmsg;
1184 if (use_config_midi_ports ()) {
1187 if (version >= 3000) {
1188 if ((child = find_named_node (node, "Metadata")) == 0) {
1189 warning << _("Session: XML state has no metadata section") << endmsg;
1190 } else if (_metadata->set_state (*child, version)) {
1195 if ((child = find_named_node (node, "Locations")) == 0) {
1196 error << _("Session: XML state has no locations section") << endmsg;
1198 } else if (_locations.set_state (*child, version)) {
1204 if ((location = _locations.auto_loop_location()) != 0) {
1205 set_auto_loop_location (location);
1208 if ((location = _locations.auto_punch_location()) != 0) {
1209 set_auto_punch_location (location);
1212 if ((location = _locations.end_location()) == 0) {
1213 _locations.add (end_location);
1215 delete end_location;
1216 end_location = location;
1219 if ((location = _locations.start_location()) == 0) {
1220 _locations.add (start_location);
1222 delete start_location;
1223 start_location = location;
1226 AudioFileSource::set_header_position_offset (start_location->start());
1228 if ((child = find_named_node (node, "Sources")) == 0) {
1229 error << _("Session: XML state has no sources section") << endmsg;
1231 } else if (load_sources (*child)) {
1235 if ((child = find_named_node (node, "Regions")) == 0) {
1236 error << _("Session: XML state has no Regions section") << endmsg;
1238 } else if (load_regions (*child)) {
1242 if ((child = find_named_node (node, "Playlists")) == 0) {
1243 error << _("Session: XML state has no playlists section") << endmsg;
1245 } else if (playlists->load (*this, *child)) {
1249 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1251 } else if (playlists->load_unused (*this, *child)) {
1255 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1256 if (load_named_selections (*child)) {
1261 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1262 error << _("Session: XML state has no diskstreams section") << endmsg;
1264 } else if (load_diskstreams (*child)) {
1268 if (version >= 3000) {
1269 if ((child = find_named_node (node, "Bundles")) == 0) {
1270 warning << _("Session: XML state has no bundles section") << endmsg;
1273 /* We can't load Bundles yet as they need to be able
1274 to convert from port names to Port objects, which can't happen until
1276 _bundle_xml_node = new XMLNode (*child);
1280 if ((child = find_named_node (node, "TempoMap")) == 0) {
1281 error << _("Session: XML state has no Tempo Map section") << endmsg;
1283 } else if (_tempo_map->set_state (*child, version)) {
1287 if ((child = find_named_node (node, "Routes")) == 0) {
1288 error << _("Session: XML state has no routes section") << endmsg;
1290 } else if (load_routes (*child, version)) {
1294 if (version >= 3000) {
1296 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1297 error << _("Session: XML state has no route groups section") << endmsg;
1299 } else if (load_route_groups (*child, version)) {
1303 } else if (version < 3000) {
1305 if ((child = find_named_node (node, "EditGroups")) == 0) {
1306 error << _("Session: XML state has no edit groups section") << endmsg;
1308 } else if (load_route_groups (*child, version)) {
1312 if ((child = find_named_node (node, "MixGroups")) == 0) {
1313 error << _("Session: XML state has no mix groups section") << endmsg;
1315 } else if (load_route_groups (*child, version)) {
1320 if ((child = find_named_node (node, "Click")) == 0) {
1321 warning << _("Session: XML state has no click section") << endmsg;
1322 } else if (_click_io) {
1323 _click_io->set_state (*child, version);
1326 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1327 ControlProtocolManager::instance().set_protocol_states (*child);
1330 /* here beginneth the second phase ... */
1332 StateReady (); /* EMIT SIGNAL */
1341 Session::load_routes (const XMLNode& node, int version)
1344 XMLNodeConstIterator niter;
1345 RouteList new_routes;
1347 nlist = node.children();
1351 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1353 boost::shared_ptr<Route> route (XMLRouteFactory (**niter, version));
1356 error << _("Session: cannot create Route from XML description.") << endmsg;
1360 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1362 new_routes.push_back (route);
1365 add_routes (new_routes, false);
1370 boost::shared_ptr<Route>
1371 Session::XMLRouteFactory (const XMLNode& node, int version)
1373 if (node.name() != "Route") {
1374 return boost::shared_ptr<Route> ((Route*) 0);
1377 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1379 DataType type = DataType::AUDIO;
1380 const XMLProperty* prop = node.property("default-type");
1383 type = DataType(prop->value());
1386 assert(type != DataType::NIL);
1388 if (has_diskstream) {
1389 if (type == DataType::AUDIO) {
1390 AudioTrack* at = new AudioTrack (*this, node, version);
1391 boost_debug_shared_ptr_mark_interesting (at, "Track");
1392 return boost::shared_ptr<Route> (at);
1395 boost::shared_ptr<Route> ret (new MidiTrack (*this, node, version));
1399 Route* rt = new Route (*this, node);
1400 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1401 return boost::shared_ptr<Route> (rt);
1406 Session::load_regions (const XMLNode& node)
1409 XMLNodeConstIterator niter;
1410 boost::shared_ptr<Region> region;
1412 nlist = node.children();
1416 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1417 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1418 error << _("Session: cannot create Region from XML description.");
1419 const XMLProperty *name = (**niter).property("name");
1422 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1432 boost::shared_ptr<Region>
1433 Session::XMLRegionFactory (const XMLNode& node, bool full)
1435 const XMLProperty* type = node.property("type");
1439 if ( !type || type->value() == "audio" ) {
1441 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1443 } else if (type->value() == "midi") {
1445 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1449 } catch (failed_constructor& err) {
1450 return boost::shared_ptr<Region> ();
1453 return boost::shared_ptr<Region> ();
1456 boost::shared_ptr<AudioRegion>
1457 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1459 const XMLProperty* prop;
1460 boost::shared_ptr<Source> source;
1461 boost::shared_ptr<AudioSource> as;
1463 SourceList master_sources;
1464 uint32_t nchans = 1;
1467 if (node.name() != X_("Region")) {
1468 return boost::shared_ptr<AudioRegion>();
1471 if ((prop = node.property (X_("channels"))) != 0) {
1472 nchans = atoi (prop->value().c_str());
1475 if ((prop = node.property ("name")) == 0) {
1476 cerr << "no name for this region\n";
1480 if ((prop = node.property (X_("source-0"))) == 0) {
1481 if ((prop = node.property ("source")) == 0) {
1482 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1483 return boost::shared_ptr<AudioRegion>();
1487 PBD::ID s_id (prop->value());
1489 if ((source = source_by_id (s_id)) == 0) {
1490 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1491 return boost::shared_ptr<AudioRegion>();
1494 as = boost::dynamic_pointer_cast<AudioSource>(source);
1496 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1497 return boost::shared_ptr<AudioRegion>();
1500 sources.push_back (as);
1502 /* pickup other channels */
1504 for (uint32_t n=1; n < nchans; ++n) {
1505 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1506 if ((prop = node.property (buf)) != 0) {
1508 PBD::ID id2 (prop->value());
1510 if ((source = source_by_id (id2)) == 0) {
1511 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1512 return boost::shared_ptr<AudioRegion>();
1515 as = boost::dynamic_pointer_cast<AudioSource>(source);
1517 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1518 return boost::shared_ptr<AudioRegion>();
1520 sources.push_back (as);
1524 for (uint32_t n = 0; n < nchans; ++n) {
1525 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1526 if ((prop = node.property (buf)) != 0) {
1528 PBD::ID id2 (prop->value());
1530 if ((source = source_by_id (id2)) == 0) {
1531 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1532 return boost::shared_ptr<AudioRegion>();
1535 as = boost::dynamic_pointer_cast<AudioSource>(source);
1537 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1538 return boost::shared_ptr<AudioRegion>();
1540 master_sources.push_back (as);
1545 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1547 /* a final detail: this is the one and only place that we know how long missing files are */
1549 if (region->whole_file()) {
1550 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1551 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1553 sfp->set_length (region->length());
1558 if (!master_sources.empty()) {
1559 if (master_sources.size() != nchans) {
1560 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1562 region->set_master_sources (master_sources);
1570 catch (failed_constructor& err) {
1571 return boost::shared_ptr<AudioRegion>();
1575 boost::shared_ptr<MidiRegion>
1576 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1578 const XMLProperty* prop;
1579 boost::shared_ptr<Source> source;
1580 boost::shared_ptr<MidiSource> ms;
1582 uint32_t nchans = 1;
1584 if (node.name() != X_("Region")) {
1585 return boost::shared_ptr<MidiRegion>();
1588 if ((prop = node.property (X_("channels"))) != 0) {
1589 nchans = atoi (prop->value().c_str());
1592 if ((prop = node.property ("name")) == 0) {
1593 cerr << "no name for this region\n";
1597 // Multiple midi channels? that's just crazy talk
1598 assert(nchans == 1);
1600 if ((prop = node.property (X_("source-0"))) == 0) {
1601 if ((prop = node.property ("source")) == 0) {
1602 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1603 return boost::shared_ptr<MidiRegion>();
1607 PBD::ID s_id (prop->value());
1609 if ((source = source_by_id (s_id)) == 0) {
1610 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1611 return boost::shared_ptr<MidiRegion>();
1614 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1616 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1617 return boost::shared_ptr<MidiRegion>();
1620 sources.push_back (ms);
1623 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1624 /* a final detail: this is the one and only place that we know how long missing files are */
1626 if (region->whole_file()) {
1627 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1628 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1630 sfp->set_length (region->length());
1638 catch (failed_constructor& err) {
1639 return boost::shared_ptr<MidiRegion>();
1644 Session::get_sources_as_xml ()
1647 XMLNode* node = new XMLNode (X_("Sources"));
1648 Glib::Mutex::Lock lm (source_lock);
1650 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1651 node->add_child_nocopy (i->second->get_state());
1658 Session::path_from_region_name (DataType type, string name, string identifier)
1660 char buf[PATH_MAX+1];
1662 SessionDirectory sdir(get_best_session_directory_for_new_source());
1663 sys::path source_dir = ((type == DataType::AUDIO)
1664 ? sdir.sound_path() : sdir.midi_path());
1666 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1668 for (n = 0; n < 999999; ++n) {
1669 if (identifier.length()) {
1670 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1671 identifier.c_str(), n, ext.c_str());
1673 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1677 sys::path source_path = source_dir / buf;
1679 if (!sys::exists (source_path)) {
1680 return source_path.to_string();
1684 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1693 Session::load_sources (const XMLNode& node)
1696 XMLNodeConstIterator niter;
1697 boost::shared_ptr<Source> source;
1699 nlist = node.children();
1703 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1705 if ((source = XMLSourceFactory (**niter)) == 0) {
1706 error << _("Session: cannot create Source from XML description.") << endmsg;
1708 } catch (MissingSource& err) {
1709 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1710 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1717 boost::shared_ptr<Source>
1718 Session::XMLSourceFactory (const XMLNode& node)
1720 if (node.name() != "Source") {
1721 return boost::shared_ptr<Source>();
1725 /* note: do peak building in another thread when loading session state */
1726 return SourceFactory::create (*this, node, true);
1729 catch (failed_constructor& err) {
1730 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1731 return boost::shared_ptr<Source>();
1736 Session::save_template (string template_name)
1740 if (_state_of_the_state & CannotSave) {
1744 sys::path user_template_dir(user_template_directory());
1748 sys::create_directories (user_template_dir);
1750 catch(sys::filesystem_error& ex)
1752 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1753 user_template_dir.to_string(), ex.what()) << endmsg;
1757 tree.set_root (&get_template());
1759 sys::path template_file_path(user_template_dir);
1760 template_file_path /= template_name + template_suffix;
1762 if (sys::exists (template_file_path))
1764 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1765 template_file_path.to_string()) << endmsg;
1769 if (!tree.write (template_file_path.to_string())) {
1770 error << _("mix template not saved") << endmsg;
1778 Session::rename_template (string old_name, string new_name)
1780 sys::path old_path (user_template_directory());
1781 old_path /= old_name + template_suffix;
1783 sys::path new_path(user_template_directory());
1784 new_path /= new_name + template_suffix;
1786 if (sys::exists (new_path)) {
1787 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1788 new_path.to_string()) << endmsg;
1793 sys::rename (old_path, new_path);
1801 Session::delete_template (string name)
1803 sys::path path = user_template_directory();
1804 path /= name + template_suffix;
1815 Session::refresh_disk_space ()
1818 struct statfs statfsbuf;
1819 vector<space_and_path>::iterator i;
1820 Glib::Mutex::Lock lm (space_lock);
1823 /* get freespace on every FS that is part of the session path */
1825 _total_free_4k_blocks = 0;
1827 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1828 statfs ((*i).path.c_str(), &statfsbuf);
1830 scale = statfsbuf.f_bsize/4096.0;
1832 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1833 _total_free_4k_blocks += (*i).blocks;
1839 Session::get_best_session_directory_for_new_source ()
1841 vector<space_and_path>::iterator i;
1842 string result = _session_dir->root_path().to_string();
1844 /* handle common case without system calls */
1846 if (session_dirs.size() == 1) {
1850 /* OK, here's the algorithm we're following here:
1852 We want to select which directory to use for
1853 the next file source to be created. Ideally,
1854 we'd like to use a round-robin process so as to
1855 get maximum performance benefits from splitting
1856 the files across multiple disks.
1858 However, in situations without much diskspace, an
1859 RR approach may end up filling up a filesystem
1860 with new files while others still have space.
1861 Its therefore important to pay some attention to
1862 the freespace in the filesystem holding each
1863 directory as well. However, if we did that by
1864 itself, we'd keep creating new files in the file
1865 system with the most space until it was as full
1866 as all others, thus negating any performance
1867 benefits of this RAID-1 like approach.
1869 So, we use a user-configurable space threshold. If
1870 there are at least 2 filesystems with more than this
1871 much space available, we use RR selection between them.
1872 If not, then we pick the filesystem with the most space.
1874 This gets a good balance between the two
1878 refresh_disk_space ();
1880 int free_enough = 0;
1882 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1883 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1888 if (free_enough >= 2) {
1889 /* use RR selection process, ensuring that the one
1893 i = last_rr_session_dir;
1896 if (++i == session_dirs.end()) {
1897 i = session_dirs.begin();
1900 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1901 if (create_session_directory ((*i).path)) {
1903 last_rr_session_dir = i;
1908 } while (i != last_rr_session_dir);
1912 /* pick FS with the most freespace (and that
1913 seems to actually work ...)
1916 vector<space_and_path> sorted;
1917 space_and_path_ascending_cmp cmp;
1919 sorted = session_dirs;
1920 sort (sorted.begin(), sorted.end(), cmp);
1922 for (i = sorted.begin(); i != sorted.end(); ++i) {
1923 if (create_session_directory ((*i).path)) {
1925 last_rr_session_dir = i;
1935 Session::load_named_selections (const XMLNode& node)
1938 XMLNodeConstIterator niter;
1941 nlist = node.children();
1945 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1947 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1948 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1956 Session::XMLNamedSelectionFactory (const XMLNode& node)
1959 return new NamedSelection (*this, node);
1962 catch (failed_constructor& err) {
1968 Session::automation_dir () const
1970 return Glib::build_filename (_path, "automation");
1974 Session::analysis_dir () const
1976 return Glib::build_filename (_path, "analysis");
1980 Session::load_bundles (XMLNode const & node)
1982 XMLNodeList nlist = node.children();
1983 XMLNodeConstIterator niter;
1987 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1988 if ((*niter)->name() == "InputBundle") {
1989 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
1990 } else if ((*niter)->name() == "OutputBundle") {
1991 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
1993 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2002 Session::load_route_groups (const XMLNode& node, int version)
2004 XMLNodeList nlist = node.children();
2005 XMLNodeConstIterator niter;
2009 if (version >= 3000) {
2011 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2012 if ((*niter)->name() == "RouteGroup") {
2013 RouteGroup* rg = new RouteGroup (*this, "");
2014 add_route_group (rg);
2015 rg->set_state (**niter, version);
2019 } else if (version < 3000) {
2021 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2022 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2023 RouteGroup* rg = new RouteGroup (*this, "");
2024 add_route_group (rg);
2025 rg->set_state (**niter, version);
2034 Session::auto_save()
2036 save_state (_current_snapshot_name);
2040 state_file_filter (const string &str, void */*arg*/)
2042 return (str.length() > strlen(statefile_suffix) &&
2043 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2047 bool operator()(const string* a, const string* b) {
2053 remove_end(string* state)
2055 string statename(*state);
2057 string::size_type start,end;
2058 if ((start = statename.find_last_of ('/')) != string::npos) {
2059 statename = statename.substr (start+1);
2062 if ((end = statename.rfind(".ardour")) == string::npos) {
2063 end = statename.length();
2066 return new string(statename.substr (0, end));
2070 Session::possible_states (string path)
2072 PathScanner scanner;
2073 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2075 transform(states->begin(), states->end(), states->begin(), remove_end);
2078 sort (states->begin(), states->end(), cmp);
2084 Session::possible_states () const
2086 return possible_states(_path);
2090 Session::add_route_group (RouteGroup* g)
2092 _route_groups.push_back (g);
2093 route_group_added (g); /* EMIT SIGNAL */
2098 Session::remove_route_group (RouteGroup& rg)
2100 list<RouteGroup*>::iterator i;
2102 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2103 _route_groups.erase (i);
2106 route_group_removed (); /* EMIT SIGNAL */
2112 Session::route_group_by_name (string name)
2114 list<RouteGroup *>::iterator i;
2116 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2117 if ((*i)->name() == name) {
2125 Session::start_reversible_command (const string& name)
2127 UndoTransaction* trans = new UndoTransaction();
2128 trans->set_name(name);
2133 Session::finish_reversible_command (UndoTransaction& ut)
2136 gettimeofday(&now, 0);
2137 ut.set_timestamp(now);
2142 Session::begin_reversible_command(const string& name)
2144 UndoTransaction* trans = new UndoTransaction();
2145 trans->set_name(name);
2147 if (!_current_trans.empty()) {
2148 _current_trans.top()->add_command (trans);
2150 _current_trans.push(trans);
2155 Session::commit_reversible_command(Command *cmd)
2157 assert(!_current_trans.empty());
2161 _current_trans.top()->add_command(cmd);
2164 if (_current_trans.top()->empty()) {
2165 _current_trans.pop();
2169 gettimeofday(&now, 0);
2170 _current_trans.top()->set_timestamp(now);
2172 _history.add(_current_trans.top());
2173 _current_trans.pop();
2177 accept_all_non_peak_files (const string& path, void */*arg*/)
2179 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2183 accept_all_state_files (const string& path, void */*arg*/)
2185 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2189 Session::find_all_sources (string path, set<string>& result)
2194 if (!tree.read (path)) {
2198 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2203 XMLNodeConstIterator niter;
2205 nlist = node->children();
2209 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2213 if ((prop = (*niter)->property (X_("type"))) == 0) {
2217 DataType type (prop->value());
2219 if ((prop = (*niter)->property (X_("name"))) == 0) {
2223 if (prop->value()[0] == '/') {
2224 /* external file, ignore */
2228 Glib::ustring found_path;
2232 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2233 result.insert (found_path);
2241 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2243 PathScanner scanner;
2244 vector<string*>* state_files;
2246 string this_snapshot_path;
2252 if (ripped[ripped.length()-1] == '/') {
2253 ripped = ripped.substr (0, ripped.length() - 1);
2256 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2258 if (state_files == 0) {
2263 this_snapshot_path = _path;
2264 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2265 this_snapshot_path += statefile_suffix;
2267 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2269 if (exclude_this_snapshot && **i == this_snapshot_path) {
2273 if (find_all_sources (**i, result) < 0) {
2281 struct RegionCounter {
2282 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2283 AudioSourceList::iterator iter;
2284 boost::shared_ptr<Region> region;
2287 RegionCounter() : count (0) {}
2291 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2293 return *AskAboutPlaylistDeletion (p);
2297 Session::cleanup_sources (CleanupReport& rep)
2299 // FIXME: needs adaptation to midi
2301 vector<boost::shared_ptr<Source> > dead_sources;
2302 PathScanner scanner;
2304 vector<space_and_path>::iterator i;
2305 vector<space_and_path>::iterator nexti;
2306 vector<string*>* soundfiles;
2307 vector<string> unused;
2308 set<string> all_sources;
2313 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2315 /* step 1: consider deleting all unused playlists */
2317 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2322 /* step 2: find all un-used sources */
2327 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2329 SourceMap::iterator tmp;
2334 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2338 if (!playlists->source_use_count(i->second) && i->second->length(i->second->timeline_position()) > 0) {
2339 dead_sources.push_back (i->second);
2340 i->second->drop_references ();
2346 /* build a list of all the possible sound directories for the session */
2348 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2353 SessionDirectory sdir ((*i).path);
2354 sound_path += sdir.sound_path().to_string();
2356 if (nexti != session_dirs.end()) {
2363 /* now do the same thing for the files that ended up in the sounds dir(s)
2364 but are not referenced as sources in any snapshot.
2367 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2369 if (soundfiles == 0) {
2373 /* find all sources, but don't use this snapshot because the
2374 state file on disk still references sources we may have already
2378 find_all_sources_across_snapshots (all_sources, true);
2380 /* add our current source list
2383 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2384 boost::shared_ptr<FileSource> fs;
2386 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2387 all_sources.insert (fs->path());
2391 char tmppath1[PATH_MAX+1];
2392 char tmppath2[PATH_MAX+1];
2394 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2399 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2401 realpath(spath.c_str(), tmppath1);
2402 realpath((*i).c_str(), tmppath2);
2404 if (strcmp(tmppath1, tmppath2) == 0) {
2411 unused.push_back (spath);
2415 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2417 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2418 struct stat statbuf;
2420 rep.paths.push_back (*x);
2421 if (stat ((*x).c_str(), &statbuf) == 0) {
2422 rep.space += statbuf.st_size;
2427 /* don't move the file across filesystems, just
2428 stick it in the `dead_sound_dir_name' directory
2429 on whichever filesystem it was already on.
2432 if ((*x).find ("/sounds/") != string::npos) {
2434 /* old school, go up 1 level */
2436 newpath = Glib::path_get_dirname (*x); // "sounds"
2437 newpath = Glib::path_get_dirname (newpath); // "session-name"
2441 /* new school, go up 4 levels */
2443 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2444 newpath = Glib::path_get_dirname (newpath); // "session-name"
2445 newpath = Glib::path_get_dirname (newpath); // "interchange"
2446 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2450 newpath += dead_sound_dir_name;
2452 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2453 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2458 newpath += Glib::path_get_basename ((*x));
2460 if (access (newpath.c_str(), F_OK) == 0) {
2462 /* the new path already exists, try versioning */
2464 char buf[PATH_MAX+1];
2468 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2471 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2472 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2476 if (version == 999) {
2477 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2481 newpath = newpath_v;
2486 /* it doesn't exist, or we can't read it or something */
2490 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2491 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2492 (*x), newpath, strerror (errno))
2497 /* see if there an easy to find peakfile for this file, and remove it.
2500 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2501 peakpath += peakfile_suffix;
2503 if (access (peakpath.c_str(), W_OK) == 0) {
2504 if (::unlink (peakpath.c_str()) != 0) {
2505 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2506 peakpath, _path, strerror (errno))
2508 /* try to back out */
2509 rename (newpath.c_str(), _path.c_str());
2517 /* dump the history list */
2521 /* save state so we don't end up a session file
2522 referring to non-existent sources.
2528 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2534 Session::cleanup_trash_sources (CleanupReport& rep)
2536 // FIXME: needs adaptation for MIDI
2538 vector<space_and_path>::iterator i;
2539 string dead_sound_dir;
2540 struct dirent* dentry;
2541 struct stat statbuf;
2547 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2549 dead_sound_dir = (*i).path;
2550 dead_sound_dir += dead_sound_dir_name;
2552 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2556 while ((dentry = readdir (dead)) != 0) {
2558 /* avoid '.' and '..' */
2560 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2561 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2567 fullpath = dead_sound_dir;
2569 fullpath += dentry->d_name;
2571 if (stat (fullpath.c_str(), &statbuf)) {
2575 if (!S_ISREG (statbuf.st_mode)) {
2579 if (unlink (fullpath.c_str())) {
2580 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2581 fullpath, strerror (errno))
2585 rep.paths.push_back (dentry->d_name);
2586 rep.space += statbuf.st_size;
2597 Session::set_dirty ()
2599 bool was_dirty = dirty();
2601 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2605 DirtyChanged(); /* EMIT SIGNAL */
2611 Session::set_clean ()
2613 bool was_dirty = dirty();
2615 _state_of_the_state = Clean;
2619 DirtyChanged(); /* EMIT SIGNAL */
2624 Session::set_deletion_in_progress ()
2626 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2630 Session::clear_deletion_in_progress ()
2632 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2636 Session::add_controllable (boost::shared_ptr<Controllable> c)
2638 /* this adds a controllable to the list managed by the Session.
2639 this is a subset of those managed by the Controllable class
2640 itself, and represents the only ones whose state will be saved
2641 as part of the session.
2644 Glib::Mutex::Lock lm (controllables_lock);
2645 controllables.insert (c);
2648 struct null_deleter { void operator()(void const *) const {} };
2651 Session::remove_controllable (Controllable* c)
2653 if (_state_of_the_state | Deletion) {
2657 Glib::Mutex::Lock lm (controllables_lock);
2659 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2661 if (x != controllables.end()) {
2662 controllables.erase (x);
2666 boost::shared_ptr<Controllable>
2667 Session::controllable_by_id (const PBD::ID& id)
2669 Glib::Mutex::Lock lm (controllables_lock);
2671 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2672 if ((*i)->id() == id) {
2677 return boost::shared_ptr<Controllable>();
2681 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2684 Stateful::add_instant_xml (node, _path);
2687 if (write_to_config) {
2688 Config->add_instant_xml (node);
2693 Session::instant_xml (const string& node_name)
2695 return Stateful::instant_xml (node_name, _path);
2699 Session::save_history (string snapshot_name)
2707 if (snapshot_name.empty()) {
2708 snapshot_name = _current_snapshot_name;
2711 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2712 const string backup_filename = history_filename + backup_suffix;
2713 const sys::path xml_path = _session_dir->root_path() / history_filename;
2714 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2716 if (sys::exists (xml_path)) {
2719 sys::rename (xml_path, backup_path);
2721 catch (const sys::filesystem_error& err)
2723 error << _("could not backup old history file, current history not saved") << endmsg;
2728 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2732 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2734 if (!tree.write (xml_path.to_string()))
2736 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2740 sys::remove (xml_path);
2741 sys::rename (backup_path, xml_path);
2743 catch (const sys::filesystem_error& err)
2745 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2746 backup_path.to_string(), err.what()) << endmsg;
2756 Session::restore_history (string snapshot_name)
2760 if (snapshot_name.empty()) {
2761 snapshot_name = _current_snapshot_name;
2764 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
2765 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2767 info << "Loading history from " << xml_path.to_string() << endmsg;
2769 if (!sys::exists (xml_path)) {
2770 info << string_compose (_("%1: no history file \"%2\" for this session."),
2771 _name, xml_path.to_string()) << endmsg;
2775 if (!tree.read (xml_path.to_string())) {
2776 error << string_compose (_("Could not understand session history file \"%1\""),
2777 xml_path.to_string()) << endmsg;
2784 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2787 UndoTransaction* ut = new UndoTransaction ();
2790 ut->set_name(t->property("name")->value());
2791 stringstream ss(t->property("tv-sec")->value());
2793 ss.str(t->property("tv-usec")->value());
2795 ut->set_timestamp(tv);
2797 for (XMLNodeConstIterator child_it = t->children().begin();
2798 child_it != t->children().end(); child_it++)
2800 XMLNode *n = *child_it;
2803 if (n->name() == "MementoCommand" ||
2804 n->name() == "MementoUndoCommand" ||
2805 n->name() == "MementoRedoCommand") {
2807 if ((c = memento_command_factory(n))) {
2811 } else if (n->name() == "DeltaCommand") {
2812 PBD::ID id(n->property("midi-source")->value());
2813 boost::shared_ptr<MidiSource> midi_source =
2814 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2816 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
2818 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
2821 } else if (n->name() == "DiffCommand") {
2822 PBD::ID id(n->property("midi-source")->value());
2823 boost::shared_ptr<MidiSource> midi_source =
2824 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2826 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
2828 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
2832 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2843 Session::config_changed (std::string p, bool ours)
2849 if (p == "seamless-loop") {
2851 } else if (p == "rf-speed") {
2853 } else if (p == "auto-loop") {
2855 } else if (p == "auto-input") {
2857 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2858 /* auto-input only makes a difference if we're rolling */
2860 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2862 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2863 if ((*i)->record_enabled ()) {
2864 (*i)->monitor_input (!config.get_auto_input());
2869 } else if (p == "punch-in") {
2873 if ((location = _locations.auto_punch_location()) != 0) {
2875 if (config.get_punch_in ()) {
2876 replace_event (SessionEvent::PunchIn, location->start());
2878 remove_event (location->start(), SessionEvent::PunchIn);
2882 } else if (p == "punch-out") {
2886 if ((location = _locations.auto_punch_location()) != 0) {
2888 if (config.get_punch_out()) {
2889 replace_event (SessionEvent::PunchOut, location->end());
2891 clear_events (SessionEvent::PunchOut);
2895 } else if (p == "edit-mode") {
2897 Glib::Mutex::Lock lm (playlists->lock);
2899 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
2900 (*i)->set_edit_mode (Config->get_edit_mode ());
2903 } else if (p == "use-video-sync") {
2905 waiting_for_sync_offset = config.get_use_video_sync();
2907 } else if (p == "mmc-control") {
2909 //poke_midi_thread ();
2911 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
2914 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
2917 } else if (p == "mmc-send-id") {
2920 mmc->set_send_device_id (Config->get_mmc_send_device_id());
2923 } else if (p == "midi-control") {
2925 //poke_midi_thread ();
2927 } else if (p == "raid-path") {
2929 setup_raid_path (config.get_raid_path());
2931 } else if (p == "timecode-format") {
2935 } else if (p == "video-pullup") {
2939 } else if (p == "seamless-loop") {
2941 if (play_loop && transport_rolling()) {
2942 // to reset diskstreams etc
2943 request_play_loop (true);
2946 } else if (p == "rf-speed") {
2948 cumulative_rf_motion = 0;
2951 } else if (p == "click-sound") {
2953 setup_click_sounds (1);
2955 } else if (p == "click-emphasis-sound") {
2957 setup_click_sounds (-1);
2959 } else if (p == "clicking") {
2961 if (Config->get_clicking()) {
2962 if (_click_io && click_data) { // don't require emphasis data
2969 } else if (p == "send-mtc") {
2971 /* only set the internal flag if we have
2975 if (_mtc_port != 0) {
2976 session_send_mtc = Config->get_send_mtc();
2977 if (session_send_mtc) {
2978 /* mark us ready to send */
2979 next_quarter_frame_to_send = 0;
2982 session_send_mtc = false;
2985 } else if (p == "send-mmc") {
2987 /* only set the internal flag if we have
2991 if (_mmc_port != 0) {
2992 session_send_mmc = Config->get_send_mmc();
2995 session_send_mmc = false;
2998 } else if (p == "midi-feedback") {
3000 /* only set the internal flag if we have
3004 if (_mtc_port != 0) {
3005 session_midi_feedback = Config->get_midi_feedback();
3008 } else if (p == "jack-time-master") {
3010 engine().reset_timebase ();
3012 } else if (p == "native-file-header-format") {
3014 if (!first_file_header_format_reset) {
3015 reset_native_file_format ();
3018 first_file_header_format_reset = false;
3020 } else if (p == "native-file-data-format") {
3022 if (!first_file_data_format_reset) {
3023 reset_native_file_format ();
3026 first_file_data_format_reset = false;
3028 } else if (p == "external-sync") {
3029 if (!config.get_external_sync()) {
3030 drop_sync_source ();
3032 switch_to_sync_source (config.get_sync_source());
3034 } else if (p == "remote-model") {
3035 set_remote_control_ids ();
3036 } else if (p == "denormal-model") {
3038 } else if (p == "history-depth") {
3039 set_history_depth (Config->get_history_depth());
3040 } else if (p == "sync-all-route-ordering") {
3041 sync_order_keys ("session");
3042 } else if (p == "initial-program-change") {
3044 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3047 buf[0] = MIDI::program; // channel zero by default
3048 buf[1] = (Config->get_initial_program_change() & 0x7f);
3050 _mmc_port->midimsg (buf, sizeof (buf), 0);
3052 } else if (p == "initial-program-change") {
3054 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3055 MIDI::byte* buf = new MIDI::byte[2];
3057 buf[0] = MIDI::program; // channel zero by default
3058 buf[1] = (Config->get_initial_program_change() & 0x7f);
3059 // deliver_midi (_mmc_port, buf, 2);
3061 } else if (p == "solo-mute-override") {
3062 // catch_up_on_solo_mute_override ();
3063 } else if (p == "listen-position") {
3064 listen_position_changed ();
3065 } else if (p == "solo-control-is-listen-control") {
3066 solo_control_mode_changed ();
3074 Session::set_history_depth (uint32_t d)
3076 _history.set_depth (d);