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));
279 Controllable::Destroyed.connect (*this, boost::bind (&Session::remove_controllable, this, _1));
280 IO::PortCountChanged.connect (*this, boost::bind (&Session::ensure_buffers, this, _1));
282 /* stop IO objects from doing stuff until we're ready for them */
284 Delivery::disable_panners ();
285 IO::disable_connecting ();
289 Session::second_stage_init (bool new_session)
291 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
294 if (load_state (_current_snapshot_name)) {
297 remove_empty_sounds ();
300 if (_butler->start_thread()) {
304 if (start_midi_thread ()) {
308 // set_state() will call setup_raid_path(), but if it's a new session we need
309 // to call setup_raid_path() here.
312 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
316 setup_raid_path(_path);
319 /* we can't save till after ::when_engine_running() is called,
320 because otherwise we save state with no connections made.
321 therefore, we reset _state_of_the_state because ::set_state()
322 will have cleared it.
324 we also have to include Loading so that any events that get
325 generated between here and the end of ::when_engine_running()
326 will be processed directly rather than queued.
329 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
332 _locations.changed.connect (*this, boost::bind (&Session::locations_changed, this));
333 _locations.added.connect (*this, boost::bind (&Session::locations_added, this, _1));
334 setup_click_sounds (0);
335 setup_midi_control ();
337 /* Pay attention ... */
339 _engine.Halted.connect (*this, boost::bind (&Session::engine_halted, this));
340 _engine.Xrun.connect (*this, boost::bind (&Session::xrun_recovery, this));
343 when_engine_running();
346 /* handle this one in a different way than all others, so that its clear what happened */
348 catch (AudioEngine::PortRegistrationFailure& err) {
349 error << err.what() << endmsg;
357 BootMessage (_("Reset Remote Controls"));
359 send_full_time_code (0);
360 _engine.transport_locate (0);
361 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
362 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
364 MidiClockTicker::instance().set_session (this);
365 MIDI::Name::MidiPatchManager::instance().set_session (this);
367 /* initial program change will be delivered later; see ::config_changed() */
369 BootMessage (_("Reset Control Protocols"));
371 ControlProtocolManager::instance().set_session (this);
373 config.set_end_marker_is_free (new_session);
375 _state_of_the_state = Clean;
377 DirtyChanged (); /* EMIT SIGNAL */
379 if (state_was_pending) {
380 save_state (_current_snapshot_name);
381 remove_pending_capture_state ();
382 state_was_pending = false;
385 BootMessage (_("Session loading complete"));
391 Session::raid_path () const
393 SearchPath raid_search_path;
395 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
396 raid_search_path += sys::path((*i).path);
399 return raid_search_path.to_string ();
403 Session::setup_raid_path (string path)
412 session_dirs.clear ();
414 SearchPath search_path(path);
415 SearchPath sound_search_path;
416 SearchPath midi_search_path;
418 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
419 sp.path = (*i).to_string ();
420 sp.blocks = 0; // not needed
421 session_dirs.push_back (sp);
423 SessionDirectory sdir(sp.path);
425 sound_search_path += sdir.sound_path ();
426 midi_search_path += sdir.midi_path ();
429 // set the search path for each data type
430 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
431 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
433 // reset the round-robin soundfile path thingie
434 last_rr_session_dir = session_dirs.begin();
438 Session::path_is_within_session (const std::string& path)
440 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
441 if (path.find ((*i).path) == 0) {
449 Session::ensure_subdirs ()
453 dir = session_directory().peak_path().to_string();
455 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
456 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
460 dir = session_directory().sound_path().to_string();
462 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
463 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
467 dir = session_directory().midi_path().to_string();
469 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
470 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
474 dir = session_directory().dead_sound_path().to_string();
476 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
477 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
481 dir = session_directory().export_path().to_string();
483 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
484 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
488 dir = analysis_dir ();
490 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
491 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
499 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
502 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
503 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
507 if (ensure_subdirs ()) {
511 /* check new_session so we don't overwrite an existing one */
513 if (!mix_template.empty()) {
514 std::string in_path = mix_template;
516 ifstream in(in_path.c_str());
519 string out_path = _path;
521 out_path += statefile_suffix;
523 ofstream out(out_path.c_str());
528 // okay, session is set up. Treat like normal saved
529 // session from now on.
535 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
541 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
548 /* Instantiate metadata */
550 _metadata = new SessionMetadata ();
552 /* set initial start + end point */
554 start_location->set_end (0);
555 _locations.add (start_location);
557 end_location->set_end (initial_length);
558 _locations.add (end_location);
560 _state_of_the_state = Clean;
569 Session::load_diskstreams (const XMLNode& node)
572 XMLNodeConstIterator citer;
574 clist = node.children();
576 for (citer = clist.begin(); citer != clist.end(); ++citer) {
579 /* diskstreams added automatically by DiskstreamCreated handler */
580 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
581 AudioDiskstream* dsp (new AudioDiskstream (*this, **citer));
582 boost::shared_ptr<AudioDiskstream> dstream (dsp);
583 add_diskstream (dstream);
584 } else if ((*citer)->name() == "MidiDiskstream") {
585 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
586 add_diskstream (dstream);
588 error << _("Session: unknown diskstream type in XML") << endmsg;
592 catch (failed_constructor& err) {
593 error << _("Session: could not load diskstream via XML state") << endmsg;
602 Session::maybe_write_autosave()
604 if (dirty() && record_status() != Recording) {
605 save_state("", true);
610 Session::remove_pending_capture_state ()
612 sys::path pending_state_file_path(_session_dir->root_path());
614 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
618 sys::remove (pending_state_file_path);
620 catch(sys::filesystem_error& ex)
622 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
623 pending_state_file_path.to_string(), ex.what()) << endmsg;
627 /** Rename a state file.
628 * @param snapshot_name Snapshot name.
631 Session::rename_state (string old_name, string new_name)
633 if (old_name == _current_snapshot_name || old_name == _name) {
634 /* refuse to rename the current snapshot or the "main" one */
638 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
639 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
641 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
642 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
646 sys::rename (old_xml_path, new_xml_path);
648 catch (const sys::filesystem_error& err)
650 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
651 old_name, new_name, err.what()) << endmsg;
655 /** Remove a state file.
656 * @param snapshot_name Snapshot name.
659 Session::remove_state (string snapshot_name)
661 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
662 // refuse to remove the current snapshot or the "main" one
666 sys::path xml_path(_session_dir->root_path());
668 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
670 if (!create_backup_file (xml_path)) {
671 // don't remove it if a backup can't be made
672 // create_backup_file will log the error.
677 sys::remove (xml_path);
681 Session::save_state (string snapshot_name, bool pending)
684 sys::path xml_path(_session_dir->root_path());
686 if (!_writable || (_state_of_the_state & CannotSave)) {
690 if (!_engine.connected ()) {
691 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
696 /* tell sources we're saving first, in case they write out to a new file
697 * which should be saved with the state rather than the old one */
698 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
699 i->second->session_saved();
701 tree.set_root (&get_state());
703 if (snapshot_name.empty()) {
704 snapshot_name = _current_snapshot_name;
709 /* proper save: use statefile_suffix (.ardour in English) */
711 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
713 /* make a backup copy of the old file */
715 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
716 // create_backup_file will log the error
722 /* pending save: use pending_suffix (.pending in English) */
723 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
726 sys::path tmp_path(_session_dir->root_path());
728 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
730 // cerr << "actually writing state to " << xml_path.to_string() << endl;
732 if (!tree.write (tmp_path.to_string())) {
733 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
734 sys::remove (tmp_path);
739 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
740 error << string_compose (_("could not rename temporary session file %1 to %2"),
741 tmp_path.to_string(), xml_path.to_string()) << endmsg;
742 sys::remove (tmp_path);
749 save_history (snapshot_name);
751 bool was_dirty = dirty();
753 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
756 DirtyChanged (); /* EMIT SIGNAL */
759 StateSaved (snapshot_name); /* EMIT SIGNAL */
766 Session::restore_state (string snapshot_name)
768 if (load_state (snapshot_name) == 0) {
769 set_state (*state_tree->root(), Stateful::loading_state_version);
776 Session::load_state (string snapshot_name)
781 state_was_pending = false;
783 /* check for leftover pending state from a crashed capture attempt */
785 sys::path xmlpath(_session_dir->root_path());
786 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
788 if (sys::exists (xmlpath)) {
790 /* there is pending state from a crashed capture attempt */
792 if (AskAboutPendingState()) {
793 state_was_pending = true;
797 if (!state_was_pending) {
798 xmlpath = _session_dir->root_path();
799 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
802 if (!sys::exists (xmlpath)) {
803 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
807 state_tree = new XMLTree;
811 /* writable() really reflects the whole folder, but if for any
812 reason the session state file can't be written to, still
816 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
820 if (!state_tree->read (xmlpath.to_string())) {
821 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
827 XMLNode& root (*state_tree->root());
829 if (root.name() != X_("Session")) {
830 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
836 const XMLProperty* prop;
838 if ((prop = root.property ("version")) == 0) {
839 /* no version implies very old version of Ardour */
840 Stateful::loading_state_version = 1000;
846 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
847 Stateful::loading_state_version = (major * 1000) + minor;
850 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
852 sys::path backup_path(_session_dir->root_path());
854 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
856 // only create a backup once
857 if (sys::exists (backup_path)) {
861 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
862 xmlpath.to_string(), backup_path.to_string())
867 sys::copy_file (xmlpath, backup_path);
869 catch(sys::filesystem_error& ex)
871 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
872 xmlpath.to_string(), ex.what())
882 Session::load_options (const XMLNode& node)
884 LocaleGuard lg (X_("POSIX"));
885 config.set_variables (node);
896 Session::get_template()
898 /* if we don't disable rec-enable, diskstreams
899 will believe they need to store their capture
900 sources in their state node.
903 disable_record (false);
909 Session::state(bool full_state)
911 XMLNode* node = new XMLNode("Session");
914 // store libardour version, just in case
916 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
917 node->add_property("version", string(buf));
919 /* store configuration settings */
923 node->add_property ("name", _name);
924 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
925 node->add_property ("sample-rate", buf);
927 if (session_dirs.size() > 1) {
931 vector<space_and_path>::iterator i = session_dirs.begin();
932 vector<space_and_path>::iterator next;
934 ++i; /* skip the first one */
938 while (i != session_dirs.end()) {
942 if (next != session_dirs.end()) {
952 child = node->add_child ("Path");
953 child->add_content (p);
957 /* save the ID counter */
959 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
960 node->add_property ("id-counter", buf);
962 /* various options */
964 node->add_child_nocopy (config.get_variables ());
966 node->add_child_nocopy (_metadata->get_state());
968 child = node->add_child ("Sources");
971 Glib::Mutex::Lock sl (source_lock);
973 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
975 /* Don't save information about non-destructive file sources that are empty */
976 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
978 boost::shared_ptr<AudioFileSource> fs;
979 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
980 if (!fs->destructive()) {
981 if (fs->length(fs->timeline_position()) == 0) {
987 child->add_child_nocopy (siter->second->get_state());
991 child = node->add_child ("Regions");
994 Glib::Mutex::Lock rl (region_lock);
996 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
998 /* only store regions not attached to playlists */
1000 if (i->second->playlist() == 0) {
1001 child->add_child_nocopy (i->second->state (true));
1006 child = node->add_child ("DiskStreams");
1009 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1010 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1011 if (!(*i)->hidden()) {
1012 child->add_child_nocopy ((*i)->get_state());
1018 node->add_child_nocopy (_locations.get_state());
1020 // for a template, just create a new Locations, populate it
1021 // with the default start and end, and get the state for that.
1023 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1024 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1027 end->set_end(compute_initial_length());
1029 node->add_child_nocopy (loc.get_state());
1032 child = node->add_child ("Bundles");
1034 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1035 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1036 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1038 child->add_child_nocopy (b->get_state());
1043 child = node->add_child ("Routes");
1045 boost::shared_ptr<RouteList> r = routes.reader ();
1047 RoutePublicOrderSorter cmp;
1048 RouteList public_order (*r);
1049 public_order.sort (cmp);
1051 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1052 if (!(*i)->is_hidden()) {
1054 child->add_child_nocopy ((*i)->get_state());
1056 child->add_child_nocopy ((*i)->get_template());
1062 playlists->add_state (node, full_state);
1064 child = node->add_child ("RouteGroups");
1065 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1066 child->add_child_nocopy ((*i)->get_state());
1070 child = node->add_child ("Click");
1071 child->add_child_nocopy (_click_io->state (full_state));
1075 child = node->add_child ("NamedSelections");
1076 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1078 child->add_child_nocopy ((*i)->get_state());
1083 node->add_child_nocopy (_tempo_map->get_state());
1085 node->add_child_nocopy (get_control_protocol_state());
1088 node->add_child_copy (*_extra_xml);
1095 Session::get_control_protocol_state ()
1097 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1098 return cpm.get_state();
1102 Session::set_state (const XMLNode& node, int version)
1106 const XMLProperty* prop;
1109 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1111 if (node.name() != X_("Session")){
1112 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1116 if ((prop = node.property ("version")) != 0) {
1117 version = atoi (prop->value ()) * 1000;
1120 if ((prop = node.property ("name")) != 0) {
1121 _name = prop->value ();
1124 if ((prop = node.property (X_("sample-rate"))) != 0) {
1126 _nominal_frame_rate = atoi (prop->value());
1128 if (_nominal_frame_rate != _current_frame_rate) {
1129 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1135 setup_raid_path(_session_dir->root_path().to_string());
1137 if ((prop = node.property (X_("id-counter"))) != 0) {
1139 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1140 ID::init_counter (x);
1142 /* old sessions used a timebased counter, so fake
1143 the startup ID counter based on a standard
1148 ID::init_counter (now);
1152 IO::disable_connecting ();
1154 /* Object loading order:
1159 MIDI Control // relies on data from Options/Config
1173 if ((child = find_named_node (node, "Extra")) != 0) {
1174 _extra_xml = new XMLNode (*child);
1177 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1178 load_options (*child);
1179 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1180 load_options (*child);
1182 error << _("Session: XML state has no options section") << endmsg;
1185 if (use_config_midi_ports ()) {
1188 if (version >= 3000) {
1189 if ((child = find_named_node (node, "Metadata")) == 0) {
1190 warning << _("Session: XML state has no metadata section") << endmsg;
1191 } else if (_metadata->set_state (*child, version)) {
1196 if ((child = find_named_node (node, "Locations")) == 0) {
1197 error << _("Session: XML state has no locations section") << endmsg;
1199 } else if (_locations.set_state (*child, version)) {
1205 if ((location = _locations.auto_loop_location()) != 0) {
1206 set_auto_loop_location (location);
1209 if ((location = _locations.auto_punch_location()) != 0) {
1210 set_auto_punch_location (location);
1213 if ((location = _locations.end_location()) == 0) {
1214 _locations.add (end_location);
1216 delete end_location;
1217 end_location = location;
1220 if ((location = _locations.start_location()) == 0) {
1221 _locations.add (start_location);
1223 delete start_location;
1224 start_location = location;
1227 AudioFileSource::set_header_position_offset (start_location->start());
1229 if ((child = find_named_node (node, "Sources")) == 0) {
1230 error << _("Session: XML state has no sources section") << endmsg;
1232 } else if (load_sources (*child)) {
1236 if ((child = find_named_node (node, "Regions")) == 0) {
1237 error << _("Session: XML state has no Regions section") << endmsg;
1239 } else if (load_regions (*child)) {
1243 if ((child = find_named_node (node, "Playlists")) == 0) {
1244 error << _("Session: XML state has no playlists section") << endmsg;
1246 } else if (playlists->load (*this, *child)) {
1250 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1252 } else if (playlists->load_unused (*this, *child)) {
1256 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1257 if (load_named_selections (*child)) {
1262 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1263 error << _("Session: XML state has no diskstreams section") << endmsg;
1265 } else if (load_diskstreams (*child)) {
1269 if (version >= 3000) {
1270 if ((child = find_named_node (node, "Bundles")) == 0) {
1271 warning << _("Session: XML state has no bundles section") << endmsg;
1274 /* We can't load Bundles yet as they need to be able
1275 to convert from port names to Port objects, which can't happen until
1277 _bundle_xml_node = new XMLNode (*child);
1281 if ((child = find_named_node (node, "TempoMap")) == 0) {
1282 error << _("Session: XML state has no Tempo Map section") << endmsg;
1284 } else if (_tempo_map->set_state (*child, version)) {
1288 if ((child = find_named_node (node, "Routes")) == 0) {
1289 error << _("Session: XML state has no routes section") << endmsg;
1291 } else if (load_routes (*child, version)) {
1295 if (version >= 3000) {
1297 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1298 error << _("Session: XML state has no route groups section") << endmsg;
1300 } else if (load_route_groups (*child, version)) {
1304 } else if (version < 3000) {
1306 if ((child = find_named_node (node, "EditGroups")) == 0) {
1307 error << _("Session: XML state has no edit groups section") << endmsg;
1309 } else if (load_route_groups (*child, version)) {
1313 if ((child = find_named_node (node, "MixGroups")) == 0) {
1314 error << _("Session: XML state has no mix groups section") << endmsg;
1316 } else if (load_route_groups (*child, version)) {
1321 if ((child = find_named_node (node, "Click")) == 0) {
1322 warning << _("Session: XML state has no click section") << endmsg;
1323 } else if (_click_io) {
1324 _click_io->set_state (*child, version);
1327 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1328 ControlProtocolManager::instance().set_protocol_states (*child);
1331 /* here beginneth the second phase ... */
1333 StateReady (); /* EMIT SIGNAL */
1342 Session::load_routes (const XMLNode& node, int version)
1345 XMLNodeConstIterator niter;
1346 RouteList new_routes;
1348 nlist = node.children();
1352 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1354 boost::shared_ptr<Route> route (XMLRouteFactory (**niter, version));
1357 error << _("Session: cannot create Route from XML description.") << endmsg;
1361 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1363 new_routes.push_back (route);
1366 add_routes (new_routes, false);
1371 boost::shared_ptr<Route>
1372 Session::XMLRouteFactory (const XMLNode& node, int version)
1374 if (node.name() != "Route") {
1375 return boost::shared_ptr<Route> ((Route*) 0);
1378 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1380 DataType type = DataType::AUDIO;
1381 const XMLProperty* prop = node.property("default-type");
1384 type = DataType(prop->value());
1387 assert(type != DataType::NIL);
1389 if (has_diskstream) {
1390 if (type == DataType::AUDIO) {
1391 AudioTrack* at = new AudioTrack (*this, node, version);
1392 // boost_debug_shared_ptr_mark_interesting (at, typeid (at).name());
1393 boost::shared_ptr<Route> ret (at);
1396 boost::shared_ptr<Route> ret (new MidiTrack (*this, node, version));
1400 boost::shared_ptr<Route> ret (new Route (*this, node));
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);