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 (*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 (*this, boost::bind (&Session::graph_reordered, this));
271 /* These are all static "per-class" signals */
273 RegionFactory::CheckNewRegion.connect (*this, boost::bind (&Session::add_region, this, _1));
274 SourceFactory::SourceCreated.connect (*this, boost::bind (&Session::add_source, this, _1));
275 PlaylistFactory::PlaylistCreated.connect (*this, boost::bind (&Session::add_playlist, this, _1, _2));
276 Processor::ProcessorCreated.connect (*this, boost::bind (&Session::add_processor, this, _1));
277 NamedSelection::NamedSelectionCreated.connect (*this, boost::bind (&Session::add_named_selection, this, _1));
278 AutomationList::AutomationListCreated.connect (*this, boost::bind (&Session::add_automation_list, this, _1));
281 // Controllable::Destroyed.connect (*this, boost::bind (&Session::remove_controllable, this, _1));
283 IO::PortCountChanged.connect (*this, boost::bind (&Session::ensure_buffers, this, _1));
285 /* stop IO objects from doing stuff until we're ready for them */
287 Delivery::disable_panners ();
288 IO::disable_connecting ();
292 Session::second_stage_init (bool new_session)
294 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
297 if (load_state (_current_snapshot_name)) {
300 remove_empty_sounds ();
303 if (_butler->start_thread()) {
307 if (start_midi_thread ()) {
311 // set_state() will call setup_raid_path(), but if it's a new session we need
312 // to call setup_raid_path() here.
315 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
319 setup_raid_path(_path);
322 /* we can't save till after ::when_engine_running() is called,
323 because otherwise we save state with no connections made.
324 therefore, we reset _state_of_the_state because ::set_state()
325 will have cleared it.
327 we also have to include Loading so that any events that get
328 generated between here and the end of ::when_engine_running()
329 will be processed directly rather than queued.
332 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
335 _locations.changed.connect (*this, boost::bind (&Session::locations_changed, this));
336 _locations.added.connect (*this, boost::bind (&Session::locations_added, this, _1));
337 setup_click_sounds (0);
338 setup_midi_control ();
340 /* Pay attention ... */
342 _engine.Halted.connect (*this, boost::bind (&Session::engine_halted, this));
343 _engine.Xrun.connect (*this, boost::bind (&Session::xrun_recovery, this));
346 when_engine_running();
349 /* handle this one in a different way than all others, so that its clear what happened */
351 catch (AudioEngine::PortRegistrationFailure& err) {
352 error << err.what() << endmsg;
360 BootMessage (_("Reset Remote Controls"));
362 send_full_time_code (0);
363 _engine.transport_locate (0);
364 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
365 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
367 MidiClockTicker::instance().set_session (this);
368 MIDI::Name::MidiPatchManager::instance().set_session (this);
370 /* initial program change will be delivered later; see ::config_changed() */
372 BootMessage (_("Reset Control Protocols"));
374 ControlProtocolManager::instance().set_session (this);
376 config.set_end_marker_is_free (new_session);
378 _state_of_the_state = Clean;
380 DirtyChanged (); /* EMIT SIGNAL */
382 if (state_was_pending) {
383 save_state (_current_snapshot_name);
384 remove_pending_capture_state ();
385 state_was_pending = false;
388 BootMessage (_("Session loading complete"));
394 Session::raid_path () const
396 SearchPath raid_search_path;
398 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
399 raid_search_path += sys::path((*i).path);
402 return raid_search_path.to_string ();
406 Session::setup_raid_path (string path)
415 session_dirs.clear ();
417 SearchPath search_path(path);
418 SearchPath sound_search_path;
419 SearchPath midi_search_path;
421 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
422 sp.path = (*i).to_string ();
423 sp.blocks = 0; // not needed
424 session_dirs.push_back (sp);
426 SessionDirectory sdir(sp.path);
428 sound_search_path += sdir.sound_path ();
429 midi_search_path += sdir.midi_path ();
432 // set the search path for each data type
433 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
434 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
436 // reset the round-robin soundfile path thingie
437 last_rr_session_dir = session_dirs.begin();
441 Session::path_is_within_session (const std::string& path)
443 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
444 if (path.find ((*i).path) == 0) {
452 Session::ensure_subdirs ()
456 dir = session_directory().peak_path().to_string();
458 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
459 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
463 dir = session_directory().sound_path().to_string();
465 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
466 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
470 dir = session_directory().midi_path().to_string();
472 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
473 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
477 dir = session_directory().dead_sound_path().to_string();
479 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
480 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
484 dir = session_directory().export_path().to_string();
486 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
487 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
491 dir = analysis_dir ();
493 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
494 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
502 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
505 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
506 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
510 if (ensure_subdirs ()) {
514 /* check new_session so we don't overwrite an existing one */
516 if (!mix_template.empty()) {
517 std::string in_path = mix_template;
519 ifstream in(in_path.c_str());
522 string out_path = _path;
524 out_path += statefile_suffix;
526 ofstream out(out_path.c_str());
531 // okay, session is set up. Treat like normal saved
532 // session from now on.
538 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
544 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
551 /* Instantiate metadata */
553 _metadata = new SessionMetadata ();
555 /* set initial start + end point */
557 start_location->set_end (0);
558 _locations.add (start_location);
560 end_location->set_end (initial_length);
561 _locations.add (end_location);
563 _state_of_the_state = Clean;
572 Session::load_diskstreams (const XMLNode& node)
575 XMLNodeConstIterator citer;
577 clist = node.children();
579 for (citer = clist.begin(); citer != clist.end(); ++citer) {
582 /* diskstreams added automatically by DiskstreamCreated handler */
583 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
584 AudioDiskstream* dsp (new AudioDiskstream (*this, **citer));
585 boost::shared_ptr<AudioDiskstream> dstream (dsp);
586 add_diskstream (dstream);
587 } else if ((*citer)->name() == "MidiDiskstream") {
588 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
589 add_diskstream (dstream);
591 error << _("Session: unknown diskstream type in XML") << endmsg;
595 catch (failed_constructor& err) {
596 error << _("Session: could not load diskstream via XML state") << endmsg;
605 Session::maybe_write_autosave()
607 if (dirty() && record_status() != Recording) {
608 save_state("", true);
613 Session::remove_pending_capture_state ()
615 sys::path pending_state_file_path(_session_dir->root_path());
617 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
621 sys::remove (pending_state_file_path);
623 catch(sys::filesystem_error& ex)
625 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
626 pending_state_file_path.to_string(), ex.what()) << endmsg;
630 /** Rename a state file.
631 * @param snapshot_name Snapshot name.
634 Session::rename_state (string old_name, string new_name)
636 if (old_name == _current_snapshot_name || old_name == _name) {
637 /* refuse to rename the current snapshot or the "main" one */
641 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
642 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
644 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
645 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
649 sys::rename (old_xml_path, new_xml_path);
651 catch (const sys::filesystem_error& err)
653 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
654 old_name, new_name, err.what()) << endmsg;
658 /** Remove a state file.
659 * @param snapshot_name Snapshot name.
662 Session::remove_state (string snapshot_name)
664 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
665 // refuse to remove the current snapshot or the "main" one
669 sys::path xml_path(_session_dir->root_path());
671 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
673 if (!create_backup_file (xml_path)) {
674 // don't remove it if a backup can't be made
675 // create_backup_file will log the error.
680 sys::remove (xml_path);
684 Session::save_state (string snapshot_name, bool pending)
687 sys::path xml_path(_session_dir->root_path());
689 if (!_writable || (_state_of_the_state & CannotSave)) {
693 if (!_engine.connected ()) {
694 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
699 /* tell sources we're saving first, in case they write out to a new file
700 * which should be saved with the state rather than the old one */
701 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
702 i->second->session_saved();
704 tree.set_root (&get_state());
706 if (snapshot_name.empty()) {
707 snapshot_name = _current_snapshot_name;
712 /* proper save: use statefile_suffix (.ardour in English) */
714 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
716 /* make a backup copy of the old file */
718 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
719 // create_backup_file will log the error
725 /* pending save: use pending_suffix (.pending in English) */
726 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
729 sys::path tmp_path(_session_dir->root_path());
731 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
733 // cerr << "actually writing state to " << xml_path.to_string() << endl;
735 if (!tree.write (tmp_path.to_string())) {
736 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
737 sys::remove (tmp_path);
742 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
743 error << string_compose (_("could not rename temporary session file %1 to %2"),
744 tmp_path.to_string(), xml_path.to_string()) << endmsg;
745 sys::remove (tmp_path);
752 save_history (snapshot_name);
754 bool was_dirty = dirty();
756 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
759 DirtyChanged (); /* EMIT SIGNAL */
762 StateSaved (snapshot_name); /* EMIT SIGNAL */
769 Session::restore_state (string snapshot_name)
771 if (load_state (snapshot_name) == 0) {
772 set_state (*state_tree->root(), Stateful::loading_state_version);
779 Session::load_state (string snapshot_name)
784 state_was_pending = false;
786 /* check for leftover pending state from a crashed capture attempt */
788 sys::path xmlpath(_session_dir->root_path());
789 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
791 if (sys::exists (xmlpath)) {
793 /* there is pending state from a crashed capture attempt */
795 if (AskAboutPendingState()) {
796 state_was_pending = true;
800 if (!state_was_pending) {
801 xmlpath = _session_dir->root_path();
802 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
805 if (!sys::exists (xmlpath)) {
806 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
810 state_tree = new XMLTree;
814 /* writable() really reflects the whole folder, but if for any
815 reason the session state file can't be written to, still
819 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
823 if (!state_tree->read (xmlpath.to_string())) {
824 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
830 XMLNode& root (*state_tree->root());
832 if (root.name() != X_("Session")) {
833 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
839 const XMLProperty* prop;
841 if ((prop = root.property ("version")) == 0) {
842 /* no version implies very old version of Ardour */
843 Stateful::loading_state_version = 1000;
849 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
850 Stateful::loading_state_version = (major * 1000) + minor;
853 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
855 sys::path backup_path(_session_dir->root_path());
857 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
859 // only create a backup once
860 if (sys::exists (backup_path)) {
864 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
865 xmlpath.to_string(), backup_path.to_string())
870 sys::copy_file (xmlpath, backup_path);
872 catch(sys::filesystem_error& ex)
874 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
875 xmlpath.to_string(), ex.what())
885 Session::load_options (const XMLNode& node)
887 LocaleGuard lg (X_("POSIX"));
888 config.set_variables (node);
899 Session::get_template()
901 /* if we don't disable rec-enable, diskstreams
902 will believe they need to store their capture
903 sources in their state node.
906 disable_record (false);
912 Session::state(bool full_state)
914 XMLNode* node = new XMLNode("Session");
917 // store libardour version, just in case
919 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
920 node->add_property("version", string(buf));
922 /* store configuration settings */
926 node->add_property ("name", _name);
927 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
928 node->add_property ("sample-rate", buf);
930 if (session_dirs.size() > 1) {
934 vector<space_and_path>::iterator i = session_dirs.begin();
935 vector<space_and_path>::iterator next;
937 ++i; /* skip the first one */
941 while (i != session_dirs.end()) {
945 if (next != session_dirs.end()) {
955 child = node->add_child ("Path");
956 child->add_content (p);
960 /* save the ID counter */
962 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
963 node->add_property ("id-counter", buf);
965 /* various options */
967 node->add_child_nocopy (config.get_variables ());
969 node->add_child_nocopy (_metadata->get_state());
971 child = node->add_child ("Sources");
974 Glib::Mutex::Lock sl (source_lock);
976 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
978 /* Don't save information about non-destructive file sources that are empty */
979 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
981 boost::shared_ptr<AudioFileSource> fs;
982 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
983 if (!fs->destructive()) {
984 if (fs->length(fs->timeline_position()) == 0) {
990 child->add_child_nocopy (siter->second->get_state());
994 child = node->add_child ("Regions");
997 Glib::Mutex::Lock rl (region_lock);
999 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
1001 /* only store regions not attached to playlists */
1003 if (i->second->playlist() == 0) {
1004 child->add_child_nocopy (i->second->state (true));
1009 child = node->add_child ("DiskStreams");
1012 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1013 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1014 if (!(*i)->hidden()) {
1015 child->add_child_nocopy ((*i)->get_state());
1021 node->add_child_nocopy (_locations.get_state());
1023 // for a template, just create a new Locations, populate it
1024 // with the default start and end, and get the state for that.
1026 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1027 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1030 end->set_end(compute_initial_length());
1032 node->add_child_nocopy (loc.get_state());
1035 child = node->add_child ("Bundles");
1037 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1038 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1039 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1041 child->add_child_nocopy (b->get_state());
1046 child = node->add_child ("Routes");
1048 boost::shared_ptr<RouteList> r = routes.reader ();
1050 RoutePublicOrderSorter cmp;
1051 RouteList public_order (*r);
1052 public_order.sort (cmp);
1054 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1055 if (!(*i)->is_hidden()) {
1057 child->add_child_nocopy ((*i)->get_state());
1059 child->add_child_nocopy ((*i)->get_template());
1065 playlists->add_state (node, full_state);
1067 child = node->add_child ("RouteGroups");
1068 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1069 child->add_child_nocopy ((*i)->get_state());
1073 child = node->add_child ("Click");
1074 child->add_child_nocopy (_click_io->state (full_state));
1078 child = node->add_child ("NamedSelections");
1079 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1081 child->add_child_nocopy ((*i)->get_state());
1086 node->add_child_nocopy (_tempo_map->get_state());
1088 node->add_child_nocopy (get_control_protocol_state());
1091 node->add_child_copy (*_extra_xml);
1098 Session::get_control_protocol_state ()
1100 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1101 return cpm.get_state();
1105 Session::set_state (const XMLNode& node, int version)
1109 const XMLProperty* prop;
1112 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1114 if (node.name() != X_("Session")){
1115 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1119 if ((prop = node.property ("version")) != 0) {
1120 version = atoi (prop->value ()) * 1000;
1123 if ((prop = node.property ("name")) != 0) {
1124 _name = prop->value ();
1127 if ((prop = node.property (X_("sample-rate"))) != 0) {
1129 _nominal_frame_rate = atoi (prop->value());
1131 if (_nominal_frame_rate != _current_frame_rate) {
1132 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1138 setup_raid_path(_session_dir->root_path().to_string());
1140 if ((prop = node.property (X_("id-counter"))) != 0) {
1142 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1143 ID::init_counter (x);
1145 /* old sessions used a timebased counter, so fake
1146 the startup ID counter based on a standard
1151 ID::init_counter (now);
1155 IO::disable_connecting ();
1157 /* Object loading order:
1162 MIDI Control // relies on data from Options/Config
1176 if ((child = find_named_node (node, "Extra")) != 0) {
1177 _extra_xml = new XMLNode (*child);
1180 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1181 load_options (*child);
1182 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1183 load_options (*child);
1185 error << _("Session: XML state has no options section") << endmsg;
1188 if (use_config_midi_ports ()) {
1191 if (version >= 3000) {
1192 if ((child = find_named_node (node, "Metadata")) == 0) {
1193 warning << _("Session: XML state has no metadata section") << endmsg;
1194 } else if (_metadata->set_state (*child, version)) {
1199 if ((child = find_named_node (node, "Locations")) == 0) {
1200 error << _("Session: XML state has no locations section") << endmsg;
1202 } else if (_locations.set_state (*child, version)) {
1208 if ((location = _locations.auto_loop_location()) != 0) {
1209 set_auto_loop_location (location);
1212 if ((location = _locations.auto_punch_location()) != 0) {
1213 set_auto_punch_location (location);
1216 if ((location = _locations.end_location()) == 0) {
1217 _locations.add (end_location);
1219 delete end_location;
1220 end_location = location;
1223 if ((location = _locations.start_location()) == 0) {
1224 _locations.add (start_location);
1226 delete start_location;
1227 start_location = location;
1230 AudioFileSource::set_header_position_offset (start_location->start());
1232 if ((child = find_named_node (node, "Sources")) == 0) {
1233 error << _("Session: XML state has no sources section") << endmsg;
1235 } else if (load_sources (*child)) {
1239 if ((child = find_named_node (node, "Regions")) == 0) {
1240 error << _("Session: XML state has no Regions section") << endmsg;
1242 } else if (load_regions (*child)) {
1246 if ((child = find_named_node (node, "Playlists")) == 0) {
1247 error << _("Session: XML state has no playlists section") << endmsg;
1249 } else if (playlists->load (*this, *child)) {
1253 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1255 } else if (playlists->load_unused (*this, *child)) {
1259 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1260 if (load_named_selections (*child)) {
1265 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1266 error << _("Session: XML state has no diskstreams section") << endmsg;
1268 } else if (load_diskstreams (*child)) {
1272 if (version >= 3000) {
1273 if ((child = find_named_node (node, "Bundles")) == 0) {
1274 warning << _("Session: XML state has no bundles section") << endmsg;
1277 /* We can't load Bundles yet as they need to be able
1278 to convert from port names to Port objects, which can't happen until
1280 _bundle_xml_node = new XMLNode (*child);
1284 if ((child = find_named_node (node, "TempoMap")) == 0) {
1285 error << _("Session: XML state has no Tempo Map section") << endmsg;
1287 } else if (_tempo_map->set_state (*child, version)) {
1291 if ((child = find_named_node (node, "Routes")) == 0) {
1292 error << _("Session: XML state has no routes section") << endmsg;
1294 } else if (load_routes (*child, version)) {
1298 if (version >= 3000) {
1300 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1301 error << _("Session: XML state has no route groups section") << endmsg;
1303 } else if (load_route_groups (*child, version)) {
1307 } else if (version < 3000) {
1309 if ((child = find_named_node (node, "EditGroups")) == 0) {
1310 error << _("Session: XML state has no edit groups section") << endmsg;
1312 } else if (load_route_groups (*child, version)) {
1316 if ((child = find_named_node (node, "MixGroups")) == 0) {
1317 error << _("Session: XML state has no mix groups section") << endmsg;
1319 } else if (load_route_groups (*child, version)) {
1324 if ((child = find_named_node (node, "Click")) == 0) {
1325 warning << _("Session: XML state has no click section") << endmsg;
1326 } else if (_click_io) {
1327 _click_io->set_state (*child, version);
1330 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1331 ControlProtocolManager::instance().set_protocol_states (*child);
1334 /* here beginneth the second phase ... */
1336 StateReady (); /* EMIT SIGNAL */
1345 Session::load_routes (const XMLNode& node, int version)
1348 XMLNodeConstIterator niter;
1349 RouteList new_routes;
1351 nlist = node.children();
1355 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1357 boost::shared_ptr<Route> route (XMLRouteFactory (**niter, version));
1360 error << _("Session: cannot create Route from XML description.") << endmsg;
1364 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1366 new_routes.push_back (route);
1369 add_routes (new_routes, false);
1374 boost::shared_ptr<Route>
1375 Session::XMLRouteFactory (const XMLNode& node, int version)
1377 if (node.name() != "Route") {
1378 return boost::shared_ptr<Route> ((Route*) 0);
1381 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1383 DataType type = DataType::AUDIO;
1384 const XMLProperty* prop = node.property("default-type");
1387 type = DataType(prop->value());
1390 assert(type != DataType::NIL);
1392 if (has_diskstream) {
1393 if (type == DataType::AUDIO) {
1394 AudioTrack* at = new AudioTrack (*this, node, version);
1395 // boost_debug_shared_ptr_mark_interesting (at, typeid (at).name());
1396 boost::shared_ptr<Route> ret (at);
1399 boost::shared_ptr<Route> ret (new MidiTrack (*this, node, version));
1403 boost::shared_ptr<Route> ret (new Route (*this, node));
1409 Session::load_regions (const XMLNode& node)
1412 XMLNodeConstIterator niter;
1413 boost::shared_ptr<Region> region;
1415 nlist = node.children();
1419 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1420 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1421 error << _("Session: cannot create Region from XML description.");
1422 const XMLProperty *name = (**niter).property("name");
1425 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1435 boost::shared_ptr<Region>
1436 Session::XMLRegionFactory (const XMLNode& node, bool full)
1438 const XMLProperty* type = node.property("type");
1442 if ( !type || type->value() == "audio" ) {
1444 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1446 } else if (type->value() == "midi") {
1448 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1452 } catch (failed_constructor& err) {
1453 return boost::shared_ptr<Region> ();
1456 return boost::shared_ptr<Region> ();
1459 boost::shared_ptr<AudioRegion>
1460 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1462 const XMLProperty* prop;
1463 boost::shared_ptr<Source> source;
1464 boost::shared_ptr<AudioSource> as;
1466 SourceList master_sources;
1467 uint32_t nchans = 1;
1470 if (node.name() != X_("Region")) {
1471 return boost::shared_ptr<AudioRegion>();
1474 if ((prop = node.property (X_("channels"))) != 0) {
1475 nchans = atoi (prop->value().c_str());
1478 if ((prop = node.property ("name")) == 0) {
1479 cerr << "no name for this region\n";
1483 if ((prop = node.property (X_("source-0"))) == 0) {
1484 if ((prop = node.property ("source")) == 0) {
1485 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1486 return boost::shared_ptr<AudioRegion>();
1490 PBD::ID s_id (prop->value());
1492 if ((source = source_by_id (s_id)) == 0) {
1493 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1494 return boost::shared_ptr<AudioRegion>();
1497 as = boost::dynamic_pointer_cast<AudioSource>(source);
1499 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1500 return boost::shared_ptr<AudioRegion>();
1503 sources.push_back (as);
1505 /* pickup other channels */
1507 for (uint32_t n=1; n < nchans; ++n) {
1508 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1509 if ((prop = node.property (buf)) != 0) {
1511 PBD::ID id2 (prop->value());
1513 if ((source = source_by_id (id2)) == 0) {
1514 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1515 return boost::shared_ptr<AudioRegion>();
1518 as = boost::dynamic_pointer_cast<AudioSource>(source);
1520 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1521 return boost::shared_ptr<AudioRegion>();
1523 sources.push_back (as);
1527 for (uint32_t n = 0; n < nchans; ++n) {
1528 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1529 if ((prop = node.property (buf)) != 0) {
1531 PBD::ID id2 (prop->value());
1533 if ((source = source_by_id (id2)) == 0) {
1534 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1535 return boost::shared_ptr<AudioRegion>();
1538 as = boost::dynamic_pointer_cast<AudioSource>(source);
1540 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1541 return boost::shared_ptr<AudioRegion>();
1543 master_sources.push_back (as);
1548 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1550 /* a final detail: this is the one and only place that we know how long missing files are */
1552 if (region->whole_file()) {
1553 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1554 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1556 sfp->set_length (region->length());
1561 if (!master_sources.empty()) {
1562 if (master_sources.size() != nchans) {
1563 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1565 region->set_master_sources (master_sources);
1573 catch (failed_constructor& err) {
1574 return boost::shared_ptr<AudioRegion>();
1578 boost::shared_ptr<MidiRegion>
1579 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1581 const XMLProperty* prop;
1582 boost::shared_ptr<Source> source;
1583 boost::shared_ptr<MidiSource> ms;
1585 uint32_t nchans = 1;
1587 if (node.name() != X_("Region")) {
1588 return boost::shared_ptr<MidiRegion>();
1591 if ((prop = node.property (X_("channels"))) != 0) {
1592 nchans = atoi (prop->value().c_str());
1595 if ((prop = node.property ("name")) == 0) {
1596 cerr << "no name for this region\n";
1600 // Multiple midi channels? that's just crazy talk
1601 assert(nchans == 1);
1603 if ((prop = node.property (X_("source-0"))) == 0) {
1604 if ((prop = node.property ("source")) == 0) {
1605 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1606 return boost::shared_ptr<MidiRegion>();
1610 PBD::ID s_id (prop->value());
1612 if ((source = source_by_id (s_id)) == 0) {
1613 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1614 return boost::shared_ptr<MidiRegion>();
1617 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1619 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1620 return boost::shared_ptr<MidiRegion>();
1623 sources.push_back (ms);
1626 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1627 /* a final detail: this is the one and only place that we know how long missing files are */
1629 if (region->whole_file()) {
1630 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1631 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1633 sfp->set_length (region->length());
1641 catch (failed_constructor& err) {
1642 return boost::shared_ptr<MidiRegion>();
1647 Session::get_sources_as_xml ()
1650 XMLNode* node = new XMLNode (X_("Sources"));
1651 Glib::Mutex::Lock lm (source_lock);
1653 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1654 node->add_child_nocopy (i->second->get_state());
1661 Session::path_from_region_name (DataType type, string name, string identifier)
1663 char buf[PATH_MAX+1];
1665 SessionDirectory sdir(get_best_session_directory_for_new_source());
1666 sys::path source_dir = ((type == DataType::AUDIO)
1667 ? sdir.sound_path() : sdir.midi_path());
1669 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1671 for (n = 0; n < 999999; ++n) {
1672 if (identifier.length()) {
1673 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1674 identifier.c_str(), n, ext.c_str());
1676 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1680 sys::path source_path = source_dir / buf;
1682 if (!sys::exists (source_path)) {
1683 return source_path.to_string();
1687 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1696 Session::load_sources (const XMLNode& node)
1699 XMLNodeConstIterator niter;
1700 boost::shared_ptr<Source> source;
1702 nlist = node.children();
1706 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1708 if ((source = XMLSourceFactory (**niter)) == 0) {
1709 error << _("Session: cannot create Source from XML description.") << endmsg;
1711 } catch (MissingSource& err) {
1712 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1713 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1720 boost::shared_ptr<Source>
1721 Session::XMLSourceFactory (const XMLNode& node)
1723 if (node.name() != "Source") {
1724 return boost::shared_ptr<Source>();
1728 /* note: do peak building in another thread when loading session state */
1729 return SourceFactory::create (*this, node, true);
1732 catch (failed_constructor& err) {
1733 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1734 return boost::shared_ptr<Source>();
1739 Session::save_template (string template_name)
1743 if (_state_of_the_state & CannotSave) {
1747 sys::path user_template_dir(user_template_directory());
1751 sys::create_directories (user_template_dir);
1753 catch(sys::filesystem_error& ex)
1755 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1756 user_template_dir.to_string(), ex.what()) << endmsg;
1760 tree.set_root (&get_template());
1762 sys::path template_file_path(user_template_dir);
1763 template_file_path /= template_name + template_suffix;
1765 if (sys::exists (template_file_path))
1767 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1768 template_file_path.to_string()) << endmsg;
1772 if (!tree.write (template_file_path.to_string())) {
1773 error << _("mix template not saved") << endmsg;
1781 Session::rename_template (string old_name, string new_name)
1783 sys::path old_path (user_template_directory());
1784 old_path /= old_name + template_suffix;
1786 sys::path new_path(user_template_directory());
1787 new_path /= new_name + template_suffix;
1789 if (sys::exists (new_path)) {
1790 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1791 new_path.to_string()) << endmsg;
1796 sys::rename (old_path, new_path);
1804 Session::delete_template (string name)
1806 sys::path path = user_template_directory();
1807 path /= name + template_suffix;
1818 Session::refresh_disk_space ()
1821 struct statfs statfsbuf;
1822 vector<space_and_path>::iterator i;
1823 Glib::Mutex::Lock lm (space_lock);
1826 /* get freespace on every FS that is part of the session path */
1828 _total_free_4k_blocks = 0;
1830 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1831 statfs ((*i).path.c_str(), &statfsbuf);
1833 scale = statfsbuf.f_bsize/4096.0;
1835 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1836 _total_free_4k_blocks += (*i).blocks;
1842 Session::get_best_session_directory_for_new_source ()
1844 vector<space_and_path>::iterator i;
1845 string result = _session_dir->root_path().to_string();
1847 /* handle common case without system calls */
1849 if (session_dirs.size() == 1) {
1853 /* OK, here's the algorithm we're following here:
1855 We want to select which directory to use for
1856 the next file source to be created. Ideally,
1857 we'd like to use a round-robin process so as to
1858 get maximum performance benefits from splitting
1859 the files across multiple disks.
1861 However, in situations without much diskspace, an
1862 RR approach may end up filling up a filesystem
1863 with new files while others still have space.
1864 Its therefore important to pay some attention to
1865 the freespace in the filesystem holding each
1866 directory as well. However, if we did that by
1867 itself, we'd keep creating new files in the file
1868 system with the most space until it was as full
1869 as all others, thus negating any performance
1870 benefits of this RAID-1 like approach.
1872 So, we use a user-configurable space threshold. If
1873 there are at least 2 filesystems with more than this
1874 much space available, we use RR selection between them.
1875 If not, then we pick the filesystem with the most space.
1877 This gets a good balance between the two
1881 refresh_disk_space ();
1883 int free_enough = 0;
1885 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1886 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1891 if (free_enough >= 2) {
1892 /* use RR selection process, ensuring that the one
1896 i = last_rr_session_dir;
1899 if (++i == session_dirs.end()) {
1900 i = session_dirs.begin();
1903 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1904 if (create_session_directory ((*i).path)) {
1906 last_rr_session_dir = i;
1911 } while (i != last_rr_session_dir);
1915 /* pick FS with the most freespace (and that
1916 seems to actually work ...)
1919 vector<space_and_path> sorted;
1920 space_and_path_ascending_cmp cmp;
1922 sorted = session_dirs;
1923 sort (sorted.begin(), sorted.end(), cmp);
1925 for (i = sorted.begin(); i != sorted.end(); ++i) {
1926 if (create_session_directory ((*i).path)) {
1928 last_rr_session_dir = i;
1938 Session::load_named_selections (const XMLNode& node)
1941 XMLNodeConstIterator niter;
1944 nlist = node.children();
1948 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1950 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1951 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1959 Session::XMLNamedSelectionFactory (const XMLNode& node)
1962 return new NamedSelection (*this, node);
1965 catch (failed_constructor& err) {
1971 Session::automation_dir () const
1973 return Glib::build_filename (_path, "automation");
1977 Session::analysis_dir () const
1979 return Glib::build_filename (_path, "analysis");
1983 Session::load_bundles (XMLNode const & node)
1985 XMLNodeList nlist = node.children();
1986 XMLNodeConstIterator niter;
1990 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1991 if ((*niter)->name() == "InputBundle") {
1992 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
1993 } else if ((*niter)->name() == "OutputBundle") {
1994 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
1996 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2005 Session::load_route_groups (const XMLNode& node, int version)
2007 XMLNodeList nlist = node.children();
2008 XMLNodeConstIterator niter;
2012 if (version >= 3000) {
2014 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2015 if ((*niter)->name() == "RouteGroup") {
2016 RouteGroup* rg = new RouteGroup (*this, "");
2017 add_route_group (rg);
2018 rg->set_state (**niter, version);
2022 } else if (version < 3000) {
2024 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2025 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2026 RouteGroup* rg = new RouteGroup (*this, "");
2027 add_route_group (rg);
2028 rg->set_state (**niter, version);
2037 Session::auto_save()
2039 save_state (_current_snapshot_name);
2043 state_file_filter (const string &str, void */*arg*/)
2045 return (str.length() > strlen(statefile_suffix) &&
2046 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2050 bool operator()(const string* a, const string* b) {
2056 remove_end(string* state)
2058 string statename(*state);
2060 string::size_type start,end;
2061 if ((start = statename.find_last_of ('/')) != string::npos) {
2062 statename = statename.substr (start+1);
2065 if ((end = statename.rfind(".ardour")) == string::npos) {
2066 end = statename.length();
2069 return new string(statename.substr (0, end));
2073 Session::possible_states (string path)
2075 PathScanner scanner;
2076 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2078 transform(states->begin(), states->end(), states->begin(), remove_end);
2081 sort (states->begin(), states->end(), cmp);
2087 Session::possible_states () const
2089 return possible_states(_path);
2093 Session::add_route_group (RouteGroup* g)
2095 _route_groups.push_back (g);
2096 route_group_added (g); /* EMIT SIGNAL */
2101 Session::remove_route_group (RouteGroup& rg)
2103 list<RouteGroup*>::iterator i;
2105 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2106 _route_groups.erase (i);
2109 route_group_removed (); /* EMIT SIGNAL */
2115 Session::route_group_by_name (string name)
2117 list<RouteGroup *>::iterator i;
2119 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2120 if ((*i)->name() == name) {
2128 Session::start_reversible_command (const string& name)
2130 UndoTransaction* trans = new UndoTransaction();
2131 trans->set_name(name);
2136 Session::finish_reversible_command (UndoTransaction& ut)
2139 gettimeofday(&now, 0);
2140 ut.set_timestamp(now);
2145 Session::begin_reversible_command(const string& name)
2147 UndoTransaction* trans = new UndoTransaction();
2148 trans->set_name(name);
2150 if (!_current_trans.empty()) {
2151 _current_trans.top()->add_command (trans);
2153 _current_trans.push(trans);
2158 Session::commit_reversible_command(Command *cmd)
2160 assert(!_current_trans.empty());
2164 _current_trans.top()->add_command(cmd);
2167 if (_current_trans.top()->empty()) {
2168 _current_trans.pop();
2172 gettimeofday(&now, 0);
2173 _current_trans.top()->set_timestamp(now);
2175 _history.add(_current_trans.top());
2176 _current_trans.pop();
2180 accept_all_non_peak_files (const string& path, void */*arg*/)
2182 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2186 accept_all_state_files (const string& path, void */*arg*/)
2188 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2192 Session::find_all_sources (string path, set<string>& result)
2197 if (!tree.read (path)) {
2201 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2206 XMLNodeConstIterator niter;
2208 nlist = node->children();
2212 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2216 if ((prop = (*niter)->property (X_("type"))) == 0) {
2220 DataType type (prop->value());
2222 if ((prop = (*niter)->property (X_("name"))) == 0) {
2226 if (prop->value()[0] == '/') {
2227 /* external file, ignore */
2231 Glib::ustring found_path;
2235 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2236 result.insert (found_path);
2244 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2246 PathScanner scanner;
2247 vector<string*>* state_files;
2249 string this_snapshot_path;
2255 if (ripped[ripped.length()-1] == '/') {
2256 ripped = ripped.substr (0, ripped.length() - 1);
2259 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2261 if (state_files == 0) {
2266 this_snapshot_path = _path;
2267 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2268 this_snapshot_path += statefile_suffix;
2270 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2272 if (exclude_this_snapshot && **i == this_snapshot_path) {
2276 if (find_all_sources (**i, result) < 0) {
2284 struct RegionCounter {
2285 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2286 AudioSourceList::iterator iter;
2287 boost::shared_ptr<Region> region;
2290 RegionCounter() : count (0) {}
2294 Session::cleanup_sources (CleanupReport& rep)
2296 // FIXME: needs adaptation to midi
2298 vector<boost::shared_ptr<Source> > dead_sources;
2299 PathScanner scanner;
2301 vector<space_and_path>::iterator i;
2302 vector<space_and_path>::iterator nexti;
2303 vector<string*>* soundfiles;
2304 vector<string> unused;
2305 set<string> all_sources;
2310 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2312 /* step 1: consider deleting all unused playlists */
2315 if (playlists->maybe_delete_unused (boost::bind (AskAboutPlaylistDeletion, _1));
2320 /* step 2: find all un-used sources */
2325 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2327 SourceMap::iterator tmp;
2332 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2336 if (!playlists->source_use_count(i->second) && i->second->length(i->second->timeline_position()) > 0) {
2337 dead_sources.push_back (i->second);
2338 i->second->drop_references ();
2344 /* build a list of all the possible sound directories for the session */
2346 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2351 SessionDirectory sdir ((*i).path);
2352 sound_path += sdir.sound_path().to_string();
2354 if (nexti != session_dirs.end()) {
2361 /* now do the same thing for the files that ended up in the sounds dir(s)
2362 but are not referenced as sources in any snapshot.
2365 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2367 if (soundfiles == 0) {
2371 /* find all sources, but don't use this snapshot because the
2372 state file on disk still references sources we may have already
2376 find_all_sources_across_snapshots (all_sources, true);
2378 /* add our current source list
2381 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2382 boost::shared_ptr<FileSource> fs;
2384 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2385 all_sources.insert (fs->path());
2389 char tmppath1[PATH_MAX+1];
2390 char tmppath2[PATH_MAX+1];
2392 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2397 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2399 realpath(spath.c_str(), tmppath1);
2400 realpath((*i).c_str(), tmppath2);
2402 if (strcmp(tmppath1, tmppath2) == 0) {
2409 unused.push_back (spath);
2413 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2415 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2416 struct stat statbuf;
2418 rep.paths.push_back (*x);
2419 if (stat ((*x).c_str(), &statbuf) == 0) {
2420 rep.space += statbuf.st_size;
2425 /* don't move the file across filesystems, just
2426 stick it in the `dead_sound_dir_name' directory
2427 on whichever filesystem it was already on.
2430 if ((*x).find ("/sounds/") != string::npos) {
2432 /* old school, go up 1 level */
2434 newpath = Glib::path_get_dirname (*x); // "sounds"
2435 newpath = Glib::path_get_dirname (newpath); // "session-name"
2439 /* new school, go up 4 levels */
2441 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2442 newpath = Glib::path_get_dirname (newpath); // "session-name"
2443 newpath = Glib::path_get_dirname (newpath); // "interchange"
2444 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2448 newpath += dead_sound_dir_name;
2450 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2451 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2456 newpath += Glib::path_get_basename ((*x));
2458 if (access (newpath.c_str(), F_OK) == 0) {
2460 /* the new path already exists, try versioning */
2462 char buf[PATH_MAX+1];
2466 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2469 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2470 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2474 if (version == 999) {
2475 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2479 newpath = newpath_v;
2484 /* it doesn't exist, or we can't read it or something */
2488 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2489 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2490 (*x), newpath, strerror (errno))
2495 /* see if there an easy to find peakfile for this file, and remove it.
2498 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2499 peakpath += peakfile_suffix;
2501 if (access (peakpath.c_str(), W_OK) == 0) {
2502 if (::unlink (peakpath.c_str()) != 0) {
2503 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2504 peakpath, _path, strerror (errno))
2506 /* try to back out */
2507 rename (newpath.c_str(), _path.c_str());
2515 /* dump the history list */
2519 /* save state so we don't end up a session file
2520 referring to non-existent sources.
2526 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2532 Session::cleanup_trash_sources (CleanupReport& rep)
2534 // FIXME: needs adaptation for MIDI
2536 vector<space_and_path>::iterator i;
2537 string dead_sound_dir;
2538 struct dirent* dentry;
2539 struct stat statbuf;
2545 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2547 dead_sound_dir = (*i).path;
2548 dead_sound_dir += dead_sound_dir_name;
2550 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2554 while ((dentry = readdir (dead)) != 0) {
2556 /* avoid '.' and '..' */
2558 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2559 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2565 fullpath = dead_sound_dir;
2567 fullpath += dentry->d_name;
2569 if (stat (fullpath.c_str(), &statbuf)) {
2573 if (!S_ISREG (statbuf.st_mode)) {
2577 if (unlink (fullpath.c_str())) {
2578 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2579 fullpath, strerror (errno))
2583 rep.paths.push_back (dentry->d_name);
2584 rep.space += statbuf.st_size;
2595 Session::set_dirty ()
2597 bool was_dirty = dirty();
2599 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2603 DirtyChanged(); /* EMIT SIGNAL */
2609 Session::set_clean ()
2611 bool was_dirty = dirty();
2613 _state_of_the_state = Clean;
2617 DirtyChanged(); /* EMIT SIGNAL */
2622 Session::set_deletion_in_progress ()
2624 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2628 Session::clear_deletion_in_progress ()
2630 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2634 Session::add_controllable (boost::shared_ptr<Controllable> c)
2636 /* this adds a controllable to the list managed by the Session.
2637 this is a subset of those managed by the Controllable class
2638 itself, and represents the only ones whose state will be saved
2639 as part of the session.
2642 Glib::Mutex::Lock lm (controllables_lock);
2643 controllables.insert (c);
2646 struct null_deleter { void operator()(void const *) const {} };
2649 Session::remove_controllable (Controllable* c)
2651 if (_state_of_the_state | Deletion) {
2655 Glib::Mutex::Lock lm (controllables_lock);
2657 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2659 if (x != controllables.end()) {
2660 controllables.erase (x);
2664 boost::shared_ptr<Controllable>
2665 Session::controllable_by_id (const PBD::ID& id)
2667 Glib::Mutex::Lock lm (controllables_lock);
2669 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2670 if ((*i)->id() == id) {
2675 return boost::shared_ptr<Controllable>();
2679 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2682 Stateful::add_instant_xml (node, _path);
2685 if (write_to_config) {
2686 Config->add_instant_xml (node);
2691 Session::instant_xml (const string& node_name)
2693 return Stateful::instant_xml (node_name, _path);
2697 Session::save_history (string snapshot_name)
2705 if (snapshot_name.empty()) {
2706 snapshot_name = _current_snapshot_name;
2709 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2710 const string backup_filename = history_filename + backup_suffix;
2711 const sys::path xml_path = _session_dir->root_path() / history_filename;
2712 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2714 if (sys::exists (xml_path)) {
2717 sys::rename (xml_path, backup_path);
2719 catch (const sys::filesystem_error& err)
2721 error << _("could not backup old history file, current history not saved") << endmsg;
2726 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2730 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2732 if (!tree.write (xml_path.to_string()))
2734 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2738 sys::remove (xml_path);
2739 sys::rename (backup_path, xml_path);
2741 catch (const sys::filesystem_error& err)
2743 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2744 backup_path.to_string(), err.what()) << endmsg;
2754 Session::restore_history (string snapshot_name)
2758 if (snapshot_name.empty()) {
2759 snapshot_name = _current_snapshot_name;
2762 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
2763 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2765 info << "Loading history from " << xml_path.to_string() << endmsg;
2767 if (!sys::exists (xml_path)) {
2768 info << string_compose (_("%1: no history file \"%2\" for this session."),
2769 _name, xml_path.to_string()) << endmsg;
2773 if (!tree.read (xml_path.to_string())) {
2774 error << string_compose (_("Could not understand session history file \"%1\""),
2775 xml_path.to_string()) << endmsg;
2782 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2785 UndoTransaction* ut = new UndoTransaction ();
2788 ut->set_name(t->property("name")->value());
2789 stringstream ss(t->property("tv-sec")->value());
2791 ss.str(t->property("tv-usec")->value());
2793 ut->set_timestamp(tv);
2795 for (XMLNodeConstIterator child_it = t->children().begin();
2796 child_it != t->children().end(); child_it++)
2798 XMLNode *n = *child_it;
2801 if (n->name() == "MementoCommand" ||
2802 n->name() == "MementoUndoCommand" ||
2803 n->name() == "MementoRedoCommand") {
2805 if ((c = memento_command_factory(n))) {
2809 } else if (n->name() == "DeltaCommand") {
2810 PBD::ID id(n->property("midi-source")->value());
2811 boost::shared_ptr<MidiSource> midi_source =
2812 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2814 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
2816 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
2819 } else if (n->name() == "DiffCommand") {
2820 PBD::ID id(n->property("midi-source")->value());
2821 boost::shared_ptr<MidiSource> midi_source =
2822 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2824 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
2826 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
2830 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2841 Session::config_changed (std::string p, bool ours)
2847 if (p == "seamless-loop") {
2849 } else if (p == "rf-speed") {
2851 } else if (p == "auto-loop") {
2853 } else if (p == "auto-input") {
2855 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2856 /* auto-input only makes a difference if we're rolling */
2858 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2860 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2861 if ((*i)->record_enabled ()) {
2862 (*i)->monitor_input (!config.get_auto_input());
2867 } else if (p == "punch-in") {
2871 if ((location = _locations.auto_punch_location()) != 0) {
2873 if (config.get_punch_in ()) {
2874 replace_event (SessionEvent::PunchIn, location->start());
2876 remove_event (location->start(), SessionEvent::PunchIn);
2880 } else if (p == "punch-out") {
2884 if ((location = _locations.auto_punch_location()) != 0) {
2886 if (config.get_punch_out()) {
2887 replace_event (SessionEvent::PunchOut, location->end());
2889 clear_events (SessionEvent::PunchOut);
2893 } else if (p == "edit-mode") {
2895 Glib::Mutex::Lock lm (playlists->lock);
2897 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
2898 (*i)->set_edit_mode (Config->get_edit_mode ());
2901 } else if (p == "use-video-sync") {
2903 waiting_for_sync_offset = config.get_use_video_sync();
2905 } else if (p == "mmc-control") {
2907 //poke_midi_thread ();
2909 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
2912 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
2915 } else if (p == "mmc-send-id") {
2918 mmc->set_send_device_id (Config->get_mmc_send_device_id());
2921 } else if (p == "midi-control") {
2923 //poke_midi_thread ();
2925 } else if (p == "raid-path") {
2927 setup_raid_path (config.get_raid_path());
2929 } else if (p == "timecode-format") {
2933 } else if (p == "video-pullup") {
2937 } else if (p == "seamless-loop") {
2939 if (play_loop && transport_rolling()) {
2940 // to reset diskstreams etc
2941 request_play_loop (true);
2944 } else if (p == "rf-speed") {
2946 cumulative_rf_motion = 0;
2949 } else if (p == "click-sound") {
2951 setup_click_sounds (1);
2953 } else if (p == "click-emphasis-sound") {
2955 setup_click_sounds (-1);
2957 } else if (p == "clicking") {
2959 if (Config->get_clicking()) {
2960 if (_click_io && click_data) { // don't require emphasis data
2967 } else if (p == "send-mtc") {
2969 /* only set the internal flag if we have
2973 if (_mtc_port != 0) {
2974 session_send_mtc = Config->get_send_mtc();
2975 if (session_send_mtc) {
2976 /* mark us ready to send */
2977 next_quarter_frame_to_send = 0;
2980 session_send_mtc = false;
2983 } else if (p == "send-mmc") {
2985 /* only set the internal flag if we have
2989 if (_mmc_port != 0) {
2990 session_send_mmc = Config->get_send_mmc();
2993 session_send_mmc = false;
2996 } else if (p == "midi-feedback") {
2998 /* only set the internal flag if we have
3002 if (_mtc_port != 0) {
3003 session_midi_feedback = Config->get_midi_feedback();
3006 } else if (p == "jack-time-master") {
3008 engine().reset_timebase ();
3010 } else if (p == "native-file-header-format") {
3012 if (!first_file_header_format_reset) {
3013 reset_native_file_format ();
3016 first_file_header_format_reset = false;
3018 } else if (p == "native-file-data-format") {
3020 if (!first_file_data_format_reset) {
3021 reset_native_file_format ();
3024 first_file_data_format_reset = false;
3026 } else if (p == "external-sync") {
3027 if (!config.get_external_sync()) {
3028 drop_sync_source ();
3030 switch_to_sync_source (config.get_sync_source());
3032 } else if (p == "remote-model") {
3033 set_remote_control_ids ();
3034 } else if (p == "denormal-model") {
3036 } else if (p == "history-depth") {
3037 set_history_depth (Config->get_history_depth());
3038 } else if (p == "sync-all-route-ordering") {
3039 sync_order_keys ("session");
3040 } else if (p == "initial-program-change") {
3042 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3045 buf[0] = MIDI::program; // channel zero by default
3046 buf[1] = (Config->get_initial_program_change() & 0x7f);
3048 _mmc_port->midimsg (buf, sizeof (buf), 0);
3050 } else if (p == "initial-program-change") {
3052 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3053 MIDI::byte* buf = new MIDI::byte[2];
3055 buf[0] = MIDI::program; // channel zero by default
3056 buf[1] = (Config->get_initial_program_change() & 0x7f);
3057 // deliver_midi (_mmc_port, buf, 2);
3059 } else if (p == "solo-mute-override") {
3060 // catch_up_on_solo_mute_override ();
3061 } else if (p == "listen-position") {
3062 listen_position_changed ();
3063 } else if (p == "solo-control-is-listen-control") {
3064 solo_control_mode_changed ();
3072 Session::set_history_depth (uint32_t d)
3074 _history.set_depth (d);