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"
31 #include <cstdio> /* snprintf(3) ... grrr */
45 #include <sys/param.h>
46 #include <sys/mount.h>
52 #include <glibmm/thread.h>
54 #include <boost/algorithm/string.hpp>
56 #include "midi++/mmc.h"
57 #include "midi++/port.h"
58 #include "midi++/manager.h"
60 #include "pbd/boost_debug.h"
61 #include "pbd/basename.h"
62 #include "pbd/controllable_descriptor.h"
63 #include "pbd/enumwriter.h"
64 #include "pbd/error.h"
65 #include "pbd/pathscanner.h"
66 #include "pbd/pthread_utils.h"
67 #include "pbd/search_path.h"
68 #include "pbd/stacktrace.h"
69 #include "pbd/convert.h"
70 #include "pbd/clear_dir.h"
72 #include "ardour/amp.h"
73 #include "ardour/audio_diskstream.h"
74 #include "ardour/audio_playlist_source.h"
75 #include "ardour/audio_track.h"
76 #include "ardour/audioengine.h"
77 #include "ardour/audiofilesource.h"
78 #include "ardour/audioplaylist.h"
79 #include "ardour/audioregion.h"
80 #include "ardour/auditioner.h"
81 #include "ardour/automation_control.h"
82 #include "ardour/buffer.h"
83 #include "ardour/butler.h"
84 #include "ardour/configuration.h"
85 #include "ardour/control_protocol_manager.h"
86 #include "ardour/crossfade.h"
87 #include "ardour/cycle_timer.h"
88 #include "ardour/directory_names.h"
89 #include "ardour/filename_extensions.h"
90 #include "ardour/io_processor.h"
91 #include "ardour/location.h"
92 #include "ardour/midi_diskstream.h"
93 #include "ardour/midi_model.h"
94 #include "ardour/midi_patch_manager.h"
95 #include "ardour/midi_playlist.h"
96 #include "ardour/midi_region.h"
97 #include "ardour/midi_source.h"
98 #include "ardour/midi_track.h"
99 #include "ardour/named_selection.h"
100 #include "ardour/pannable.h"
101 #include "ardour/processor.h"
102 #include "ardour/port.h"
103 #include "ardour/proxy_controllable.h"
104 #include "ardour/recent_sessions.h"
105 #include "ardour/region_factory.h"
106 #include "ardour/route_group.h"
107 #include "ardour/send.h"
108 #include "ardour/session.h"
109 #include "ardour/session_directory.h"
110 #include "ardour/session_metadata.h"
111 #include "ardour/session_state_utils.h"
112 #include "ardour/session_playlists.h"
113 #include "ardour/session_utils.h"
114 #include "ardour/silentfilesource.h"
115 #include "ardour/slave.h"
116 #include "ardour/smf_source.h"
117 #include "ardour/sndfile_helpers.h"
118 #include "ardour/sndfilesource.h"
119 #include "ardour/source_factory.h"
120 #include "ardour/speakers.h"
121 #include "ardour/template_utils.h"
122 #include "ardour/tempo.h"
123 #include "ardour/ticker.h"
124 #include "ardour/user_bundle.h"
125 #include "ardour/utils.h"
126 #include "ardour/utils.h"
127 #include "ardour/version.h"
128 #include "ardour/playlist_factory.h"
130 #include "control_protocol/control_protocol.h"
136 using namespace ARDOUR;
139 /** @param snapshot_name Snapshot name, without the .ardour prefix */
141 Session::first_stage_init (string fullpath, string snapshot_name)
143 if (fullpath.length() == 0) {
145 throw failed_constructor();
148 char buf[PATH_MAX+1];
149 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
150 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
152 throw failed_constructor();
157 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
158 _path += G_DIR_SEPARATOR;
161 /* these two are just provisional settings. set_state()
162 will likely override them.
165 _name = _current_snapshot_name = snapshot_name;
167 set_history_depth (Config->get_history_depth());
169 _current_frame_rate = _engine.frame_rate ();
170 _nominal_frame_rate = _current_frame_rate;
171 _base_frame_rate = _current_frame_rate;
173 _tempo_map = new TempoMap (_current_frame_rate);
174 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
177 _non_soloed_outs_muted = false;
179 _solo_isolated_cnt = 0;
180 g_atomic_int_set (&processing_prohibited, 0);
181 _transport_speed = 0;
182 _last_transport_speed = 0;
183 _target_transport_speed = 0;
184 auto_play_legal = false;
185 transport_sub_state = 0;
186 _transport_frame = 0;
187 _requested_return_frame = -1;
188 _session_range_location = 0;
189 g_atomic_int_set (&_record_status, Disabled);
190 loop_changing = false;
193 _last_roll_location = 0;
194 _last_roll_or_reversal_location = 0;
195 _last_record_location = 0;
196 pending_locate_frame = 0;
197 pending_locate_roll = false;
198 pending_locate_flush = false;
199 state_was_pending = false;
201 outbound_mtc_timecode_frame = 0;
202 next_quarter_frame_to_send = -1;
203 current_block_size = 0;
204 solo_update_disabled = false;
205 _have_captured = false;
206 _worst_output_latency = 0;
207 _worst_input_latency = 0;
208 _worst_track_latency = 0;
209 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
210 _was_seamless = Config->get_seamless_loop ();
212 _send_qf_mtc = false;
213 _pframes_since_last_mtc = 0;
214 g_atomic_int_set (&_playback_load, 100);
215 g_atomic_int_set (&_capture_load, 100);
218 pending_abort = false;
219 destructive_index = 0;
220 first_file_data_format_reset = true;
221 first_file_header_format_reset = true;
222 post_export_sync = false;
225 no_questions_about_missing_files = false;
226 _speakers.reset (new Speakers);
228 ignore_route_processor_changes = false;
229 _pre_export_mmc_enabled = false;
231 AudioDiskstream::allocate_working_buffers();
233 /* default short fade = 15ms */
235 Crossfade::set_short_xfade_length ((framecnt_t) floor (config.get_short_xfade_seconds() * frame_rate()));
236 SndFileSource::setup_standard_crossfades (*this, frame_rate());
238 last_mmc_step.tv_sec = 0;
239 last_mmc_step.tv_usec = 0;
242 /* click sounds are unset by default, which causes us to internal
243 waveforms for clicks.
247 click_emphasis_length = 0;
250 process_function = &Session::process_with_events;
252 if (config.get_use_video_sync()) {
253 waiting_for_sync_offset = true;
255 waiting_for_sync_offset = false;
258 last_timecode_when = 0;
259 last_timecode_valid = false;
263 last_rr_session_dir = session_dirs.begin();
264 refresh_disk_space ();
266 /* default: assume simple stereo speaker configuration */
268 _speakers->setup_default_speakers (2);
272 average_slave_delta = 1800; // !!! why 1800 ????
273 have_first_delta_accumulator = false;
274 delta_accumulator_cnt = 0;
275 _slave_state = Stopped;
277 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
278 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
279 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
280 add_controllable (_solo_cut_control);
282 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
284 /* These are all static "per-class" signals */
286 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
287 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
288 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
289 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
290 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
292 /* stop IO objects from doing stuff until we're ready for them */
294 Delivery::disable_panners ();
295 IO::disable_connecting ();
299 Session::second_stage_init ()
301 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
304 if (load_state (_current_snapshot_name)) {
309 if (_butler->start_thread()) {
313 if (start_midi_thread ()) {
317 setup_midi_machine_control ();
319 // set_state() will call setup_raid_path(), but if it's a new session we need
320 // to call setup_raid_path() here.
323 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
327 setup_raid_path(_path);
330 /* we can't save till after ::when_engine_running() is called,
331 because otherwise we save state with no connections made.
332 therefore, we reset _state_of_the_state because ::set_state()
333 will have cleared it.
335 we also have to include Loading so that any events that get
336 generated between here and the end of ::when_engine_running()
337 will be processed directly rather than queued.
340 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
342 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
343 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
344 setup_click_sounds (0);
345 setup_midi_control ();
347 /* Pay attention ... */
349 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
350 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
352 midi_clock = new MidiClockTicker ();
353 midi_clock->set_session (this);
356 when_engine_running ();
359 /* handle this one in a different way than all others, so that its clear what happened */
361 catch (AudioEngine::PortRegistrationFailure& err) {
362 error << err.what() << endmsg;
370 BootMessage (_("Reset Remote Controls"));
372 send_full_time_code (0);
373 _engine.transport_locate (0);
375 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
376 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
378 MIDI::Name::MidiPatchManager::instance().set_session (this);
380 /* initial program change will be delivered later; see ::config_changed() */
382 _state_of_the_state = Clean;
384 Port::set_connecting_blocked (false);
386 DirtyChanged (); /* EMIT SIGNAL */
388 if (state_was_pending) {
389 save_state (_current_snapshot_name);
390 remove_pending_capture_state ();
391 state_was_pending = false;
394 BootMessage (_("Session loading complete"));
400 Session::raid_path () const
402 SearchPath raid_search_path;
404 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
405 raid_search_path += sys::path((*i).path);
408 return raid_search_path.to_string ();
412 Session::setup_raid_path (string path)
421 session_dirs.clear ();
423 SearchPath search_path(path);
424 SearchPath sound_search_path;
425 SearchPath midi_search_path;
427 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
428 sp.path = (*i).to_string ();
429 sp.blocks = 0; // not needed
430 session_dirs.push_back (sp);
432 SessionDirectory sdir(sp.path);
434 sound_search_path += sdir.sound_path ();
435 midi_search_path += sdir.midi_path ();
438 // reset the round-robin soundfile path thingie
439 last_rr_session_dir = session_dirs.begin();
443 Session::path_is_within_session (const std::string& path)
445 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
446 if (path.find ((*i).path) == 0) {
454 Session::ensure_subdirs ()
458 dir = session_directory().peak_path().to_string();
460 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
461 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
465 dir = session_directory().sound_path().to_string();
467 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
468 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
472 dir = session_directory().midi_path().to_string();
474 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
475 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
479 dir = session_directory().dead_path().to_string();
481 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
482 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
486 dir = session_directory().export_path().to_string();
488 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
489 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
493 dir = analysis_dir ();
495 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
496 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
500 dir = plugins_dir ();
502 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
503 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
507 dir = externals_dir ();
509 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
510 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
517 /** @param session_template directory containing session template, or empty.
518 * Caller must not hold process lock.
521 Session::create (const string& session_template, BusProfile* bus_profile)
523 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
524 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
528 if (ensure_subdirs ()) {
532 _writable = exists_and_writable (sys::path (_path));
534 if (!session_template.empty()) {
535 std::string in_path = session_template_dir_to_file (session_template);
537 ifstream in(in_path.c_str());
540 string out_path = _path;
542 out_path += statefile_suffix;
544 ofstream out(out_path.c_str());
550 /* Copy plugin state files from template to new session */
551 sys::path template_plugins = session_template;
552 template_plugins /= X_("plugins");
553 sys::copy_files (template_plugins, plugins_dir ());
558 error << string_compose (_("Could not open %1 for writing session template"), out_path)
564 error << string_compose (_("Could not open session template %1 for reading"), in_path)
571 /* Instantiate metadata */
573 _metadata = new SessionMetadata ();
575 /* set initial start + end point */
577 _state_of_the_state = Clean;
579 /* set up Master Out and Control Out if necessary */
584 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
586 if (bus_profile->master_out_channels) {
587 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
591 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
592 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
595 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
596 r->input()->ensure_io (count, false, this);
597 r->output()->ensure_io (count, false, this);
603 /* prohibit auto-connect to master, because there isn't one */
604 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
608 add_routes (rl, false, false, false);
611 /* this allows the user to override settings with an environment variable.
614 if (no_auto_connect()) {
615 bus_profile->input_ac = AutoConnectOption (0);
616 bus_profile->output_ac = AutoConnectOption (0);
619 Config->set_input_auto_connect (bus_profile->input_ac);
620 Config->set_output_auto_connect (bus_profile->output_ac);
623 if (Config->get_use_monitor_bus() && bus_profile) {
624 add_monitor_section ();
633 Session::maybe_write_autosave()
635 if (dirty() && record_status() != Recording) {
636 save_state("", true);
641 Session::remove_pending_capture_state ()
643 sys::path pending_state_file_path(_session_dir->root_path());
645 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
649 sys::remove (pending_state_file_path);
651 catch(sys::filesystem_error& ex)
653 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
654 pending_state_file_path.to_string(), ex.what()) << endmsg;
658 /** Rename a state file.
659 * @param old_name Old snapshot name.
660 * @param new_name New snapshot name.
663 Session::rename_state (string old_name, string new_name)
665 if (old_name == _current_snapshot_name || old_name == _name) {
666 /* refuse to rename the current snapshot or the "main" one */
670 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
671 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
673 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
674 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
678 sys::rename (old_xml_path, new_xml_path);
680 catch (const sys::filesystem_error& err)
682 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
683 old_name, new_name, err.what()) << endmsg;
687 /** Remove a state file.
688 * @param snapshot_name Snapshot name.
691 Session::remove_state (string snapshot_name)
693 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
694 // refuse to remove the current snapshot or the "main" one
698 sys::path xml_path(_session_dir->root_path());
700 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
702 if (!create_backup_file (xml_path)) {
703 // don't remove it if a backup can't be made
704 // create_backup_file will log the error.
709 sys::remove (xml_path);
712 #ifdef HAVE_JACK_SESSION
714 Session::jack_session_event (jack_session_event_t * event)
718 struct tm local_time;
721 localtime_r (&n, &local_time);
722 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
724 if (event->type == JackSessionSaveTemplate)
726 if (save_template( timebuf )) {
727 event->flags = JackSessionSaveError;
729 string cmd ("ardour3 -P -U ");
730 cmd += event->client_uuid;
734 event->command_line = strdup (cmd.c_str());
739 if (save_state (timebuf)) {
740 event->flags = JackSessionSaveError;
742 sys::path xml_path (_session_dir->root_path());
743 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
745 string cmd ("ardour3 -P -U ");
746 cmd += event->client_uuid;
748 cmd += xml_path.to_string();
751 event->command_line = strdup (cmd.c_str());
755 jack_session_reply (_engine.jack(), event);
757 if (event->type == JackSessionSaveAndQuit) {
758 Quit (); /* EMIT SIGNAL */
761 jack_session_event_free( event );
765 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
767 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
770 sys::path xml_path(_session_dir->root_path());
772 if (!_writable || (_state_of_the_state & CannotSave)) {
776 if (!_engine.connected ()) {
777 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
783 /* tell sources we're saving first, in case they write out to a new file
784 * which should be saved with the state rather than the old one */
785 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
787 i->second->session_saved();
788 } catch (Evoral::SMF::FileError& e) {
789 error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
793 tree.set_root (&get_state());
795 if (snapshot_name.empty()) {
796 snapshot_name = _current_snapshot_name;
797 } else if (switch_to_snapshot) {
798 _current_snapshot_name = snapshot_name;
803 /* proper save: use statefile_suffix (.ardour in English) */
805 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
807 /* make a backup copy of the old file */
809 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
810 // create_backup_file will log the error
816 /* pending save: use pending_suffix (.pending in English) */
817 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
820 sys::path tmp_path(_session_dir->root_path());
822 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
824 // cerr << "actually writing state to " << xml_path.to_string() << endl;
826 if (!tree.write (tmp_path.to_string())) {
827 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
828 sys::remove (tmp_path);
833 if (::rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
834 error << string_compose (_("could not rename temporary session file %1 to %2"),
835 tmp_path.to_string(), xml_path.to_string()) << endmsg;
836 sys::remove (tmp_path);
843 save_history (snapshot_name);
845 bool was_dirty = dirty();
847 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
850 DirtyChanged (); /* EMIT SIGNAL */
853 StateSaved (snapshot_name); /* EMIT SIGNAL */
860 Session::restore_state (string snapshot_name)
862 if (load_state (snapshot_name) == 0) {
863 set_state (*state_tree->root(), Stateful::loading_state_version);
870 Session::load_state (string snapshot_name)
875 state_was_pending = false;
877 /* check for leftover pending state from a crashed capture attempt */
879 sys::path xmlpath(_session_dir->root_path());
880 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
882 if (sys::exists (xmlpath)) {
884 /* there is pending state from a crashed capture attempt */
886 boost::optional<int> r = AskAboutPendingState();
887 if (r.get_value_or (1)) {
888 state_was_pending = true;
892 if (!state_was_pending) {
893 xmlpath = _session_dir->root_path();
894 xmlpath /= snapshot_name;
897 if (!sys::exists (xmlpath)) {
898 xmlpath = _session_dir->root_path();
899 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
900 if (!sys::exists (xmlpath)) {
901 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
906 state_tree = new XMLTree;
910 _writable = exists_and_writable (xmlpath);
912 if (!state_tree->read (xmlpath.to_string())) {
913 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
919 XMLNode& root (*state_tree->root());
921 if (root.name() != X_("Session")) {
922 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
928 const XMLProperty* prop;
930 if ((prop = root.property ("version")) == 0) {
931 /* no version implies very old version of Ardour */
932 Stateful::loading_state_version = 1000;
938 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
939 Stateful::loading_state_version = (major * 1000) + minor;
942 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
944 sys::path backup_path(_session_dir->root_path());
946 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
948 // only create a backup once
949 if (sys::exists (backup_path)) {
953 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
954 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
959 sys::copy_file (xmlpath, backup_path);
961 catch(sys::filesystem_error& ex)
963 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
964 xmlpath.to_string(), ex.what())
974 Session::load_options (const XMLNode& node)
976 LocaleGuard lg (X_("POSIX"));
977 config.set_variables (node);
988 Session::get_template()
990 /* if we don't disable rec-enable, diskstreams
991 will believe they need to store their capture
992 sources in their state node.
995 disable_record (false);
1001 Session::state(bool full_state)
1003 XMLNode* node = new XMLNode("Session");
1006 // store libardour version, just in case
1008 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
1009 node->add_property("version", string(buf));
1011 /* store configuration settings */
1015 node->add_property ("name", _name);
1016 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1017 node->add_property ("sample-rate", buf);
1019 if (session_dirs.size() > 1) {
1023 vector<space_and_path>::iterator i = session_dirs.begin();
1024 vector<space_and_path>::iterator next;
1026 ++i; /* skip the first one */
1030 while (i != session_dirs.end()) {
1034 if (next != session_dirs.end()) {
1044 child = node->add_child ("Path");
1045 child->add_content (p);
1049 /* save the ID counter */
1051 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1052 node->add_property ("id-counter", buf);
1054 /* save the event ID counter */
1056 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1057 node->add_property ("event-counter", buf);
1059 /* various options */
1061 node->add_child_nocopy (config.get_variables ());
1063 node->add_child_nocopy (_metadata->get_state());
1065 child = node->add_child ("Sources");
1068 Glib::Mutex::Lock sl (source_lock);
1070 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1072 /* Don't save information about non-file Sources, or
1073 * about non-destructive file sources that are empty
1074 * and unused by any regions.
1077 boost::shared_ptr<FileSource> fs;
1079 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1081 if (!fs->destructive()) {
1082 if (fs->empty() && !fs->used()) {
1087 child->add_child_nocopy (siter->second->get_state());
1092 child = node->add_child ("Regions");
1095 Glib::Mutex::Lock rl (region_lock);
1096 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1097 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1098 boost::shared_ptr<Region> r = i->second;
1099 /* only store regions not attached to playlists */
1100 if (r->playlist() == 0) {
1101 child->add_child_nocopy (r->state ());
1105 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1107 if (!cassocs.empty()) {
1108 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1110 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1112 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1113 i->first->id().print (buf, sizeof (buf));
1114 can->add_property (X_("copy"), buf);
1115 i->second->id().print (buf, sizeof (buf));
1116 can->add_property (X_("original"), buf);
1117 ca->add_child_nocopy (*can);
1123 node->add_child_nocopy (_locations->get_state());
1125 // for a template, just create a new Locations, populate it
1126 // with the default start and end, and get the state for that.
1127 Locations loc (*this);
1128 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1129 range->set (max_framepos, 0);
1131 node->add_child_nocopy (loc.get_state());
1134 child = node->add_child ("Bundles");
1136 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1137 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1138 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1140 child->add_child_nocopy (b->get_state());
1145 child = node->add_child ("Routes");
1147 boost::shared_ptr<RouteList> r = routes.reader ();
1149 RoutePublicOrderSorter cmp;
1150 RouteList public_order (*r);
1151 public_order.sort (cmp);
1153 /* the sort should have put control outs first */
1156 assert (_monitor_out == public_order.front());
1159 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1160 if (!(*i)->is_hidden()) {
1162 child->add_child_nocopy ((*i)->get_state());
1164 child->add_child_nocopy ((*i)->get_template());
1170 playlists->add_state (node, full_state);
1172 child = node->add_child ("RouteGroups");
1173 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1174 child->add_child_nocopy ((*i)->get_state());
1178 XMLNode* gain_child = node->add_child ("Click");
1179 gain_child->add_child_nocopy (_click_io->state (full_state));
1180 gain_child->add_child_nocopy (_click_gain->state (full_state));
1184 XMLNode* ns_child = node->add_child ("NamedSelections");
1185 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1187 ns_child->add_child_nocopy ((*i)->get_state());
1192 node->add_child_nocopy (_speakers->get_state());
1193 node->add_child_nocopy (_tempo_map->get_state());
1194 node->add_child_nocopy (get_control_protocol_state());
1197 node->add_child_copy (*_extra_xml);
1204 Session::get_control_protocol_state ()
1206 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1207 return cpm.get_state();
1211 Session::set_state (const XMLNode& node, int version)
1215 const XMLProperty* prop;
1218 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1220 if (node.name() != X_("Session")) {
1221 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1225 if ((prop = node.property ("version")) != 0) {
1226 version = atoi (prop->value ()) * 1000;
1229 if ((prop = node.property ("name")) != 0) {
1230 _name = prop->value ();
1233 if ((prop = node.property (X_("sample-rate"))) != 0) {
1235 _nominal_frame_rate = atoi (prop->value());
1237 if (_nominal_frame_rate != _current_frame_rate) {
1238 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1239 if (r.get_value_or (0)) {
1245 setup_raid_path(_session_dir->root_path().to_string());
1247 if ((prop = node.property (X_("id-counter"))) != 0) {
1249 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1250 ID::init_counter (x);
1252 /* old sessions used a timebased counter, so fake
1253 the startup ID counter based on a standard
1258 ID::init_counter (now);
1261 if ((prop = node.property (X_("event-counter"))) != 0) {
1262 Evoral::init_event_id_counter (atoi (prop->value()));
1265 IO::disable_connecting ();
1267 Stateful::save_extra_xml (node);
1269 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1270 load_options (*child);
1271 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1272 load_options (*child);
1274 error << _("Session: XML state has no options section") << endmsg;
1277 if (version >= 3000) {
1278 if ((child = find_named_node (node, "Metadata")) == 0) {
1279 warning << _("Session: XML state has no metadata section") << endmsg;
1280 } else if (_metadata->set_state (*child, version)) {
1285 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1286 _speakers->set_state (*child, version);
1289 if ((child = find_named_node (node, "Sources")) == 0) {
1290 error << _("Session: XML state has no sources section") << endmsg;
1292 } else if (load_sources (*child)) {
1296 if ((child = find_named_node (node, "TempoMap")) == 0) {
1297 error << _("Session: XML state has no Tempo Map section") << endmsg;
1299 } else if (_tempo_map->set_state (*child, version)) {
1303 if ((child = find_named_node (node, "Locations")) == 0) {
1304 error << _("Session: XML state has no locations section") << endmsg;
1306 } else if (_locations->set_state (*child, version)) {
1312 if ((location = _locations->auto_loop_location()) != 0) {
1313 set_auto_loop_location (location);
1316 if ((location = _locations->auto_punch_location()) != 0) {
1317 set_auto_punch_location (location);
1320 if ((location = _locations->session_range_location()) != 0) {
1321 delete _session_range_location;
1322 _session_range_location = location;
1325 if (_session_range_location) {
1326 AudioFileSource::set_header_position_offset (_session_range_location->start());
1329 if ((child = find_named_node (node, "Regions")) == 0) {
1330 error << _("Session: XML state has no Regions section") << endmsg;
1332 } else if (load_regions (*child)) {
1336 if ((child = find_named_node (node, "Playlists")) == 0) {
1337 error << _("Session: XML state has no playlists section") << endmsg;
1339 } else if (playlists->load (*this, *child)) {
1343 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1345 } else if (playlists->load_unused (*this, *child)) {
1349 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1350 if (load_compounds (*child)) {
1355 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1356 if (load_named_selections (*child)) {
1361 if (version >= 3000) {
1362 if ((child = find_named_node (node, "Bundles")) == 0) {
1363 warning << _("Session: XML state has no bundles section") << endmsg;
1366 /* We can't load Bundles yet as they need to be able
1367 to convert from port names to Port objects, which can't happen until
1369 _bundle_xml_node = new XMLNode (*child);
1373 if (version < 3000) {
1374 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1375 error << _("Session: XML state has no diskstreams section") << endmsg;
1377 } else if (load_diskstreams_2X (*child, version)) {
1382 if ((child = find_named_node (node, "Routes")) == 0) {
1383 error << _("Session: XML state has no routes section") << endmsg;
1385 } else if (load_routes (*child, version)) {
1389 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1390 _diskstreams_2X.clear ();
1392 if (version >= 3000) {
1394 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1395 error << _("Session: XML state has no route groups section") << endmsg;
1397 } else if (load_route_groups (*child, version)) {
1401 } else if (version < 3000) {
1403 if ((child = find_named_node (node, "EditGroups")) == 0) {
1404 error << _("Session: XML state has no edit groups section") << endmsg;
1406 } else if (load_route_groups (*child, version)) {
1410 if ((child = find_named_node (node, "MixGroups")) == 0) {
1411 error << _("Session: XML state has no mix groups section") << endmsg;
1413 } else if (load_route_groups (*child, version)) {
1418 if ((child = find_named_node (node, "Click")) == 0) {
1419 warning << _("Session: XML state has no click section") << endmsg;
1420 } else if (_click_io) {
1421 const XMLNodeList& children (child->children());
1422 XMLNodeList::const_iterator i = children.begin();
1423 _click_io->set_state (**i, version);
1425 if (i != children.end()) {
1426 _click_gain->set_state (**i, version);
1430 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1431 ControlProtocolManager::instance().set_protocol_states (*child);
1434 update_have_rec_enabled_track ();
1436 /* here beginneth the second phase ... */
1438 StateReady (); /* EMIT SIGNAL */
1447 Session::load_routes (const XMLNode& node, int version)
1450 XMLNodeConstIterator niter;
1451 RouteList new_routes;
1453 nlist = node.children();
1457 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1459 boost::shared_ptr<Route> route;
1460 if (version < 3000) {
1461 route = XMLRouteFactory_2X (**niter, version);
1463 route = XMLRouteFactory (**niter, version);
1467 error << _("Session: cannot create Route from XML description.") << endmsg;
1471 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1473 new_routes.push_back (route);
1476 add_routes (new_routes, false, false, false);
1481 boost::shared_ptr<Route>
1482 Session::XMLRouteFactory (const XMLNode& node, int version)
1484 boost::shared_ptr<Route> ret;
1486 if (node.name() != "Route") {
1490 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1492 DataType type = DataType::AUDIO;
1493 const XMLProperty* prop = node.property("default-type");
1496 type = DataType (prop->value());
1499 assert (type != DataType::NIL);
1503 boost::shared_ptr<Track> track;
1505 if (type == DataType::AUDIO) {
1506 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1508 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1511 if (track->init()) {
1515 if (track->set_state (node, version)) {
1519 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1520 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1525 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1527 if (r->init () == 0 && r->set_state (node, version) == 0) {
1528 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1529 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1538 boost::shared_ptr<Route>
1539 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1541 boost::shared_ptr<Route> ret;
1543 if (node.name() != "Route") {
1547 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1549 ds_prop = node.property (X_("diskstream"));
1552 DataType type = DataType::AUDIO;
1553 const XMLProperty* prop = node.property("default-type");
1556 type = DataType (prop->value());
1559 assert (type != DataType::NIL);
1563 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1564 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1568 if (i == _diskstreams_2X.end()) {
1569 error << _("Could not find diskstream for route") << endmsg;
1570 return boost::shared_ptr<Route> ();
1573 boost::shared_ptr<Track> track;
1575 if (type == DataType::AUDIO) {
1576 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1578 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1581 if (track->init()) {
1585 if (track->set_state (node, version)) {
1589 track->set_diskstream (*i);
1591 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1592 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1597 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1599 if (r->init () == 0 && r->set_state (node, version) == 0) {
1600 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1601 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1611 Session::load_regions (const XMLNode& node)
1614 XMLNodeConstIterator niter;
1615 boost::shared_ptr<Region> region;
1617 nlist = node.children();
1621 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1622 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1623 error << _("Session: cannot create Region from XML description.");
1624 const XMLProperty *name = (**niter).property("name");
1627 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1638 Session::load_compounds (const XMLNode& node)
1640 XMLNodeList calist = node.children();
1641 XMLNodeConstIterator caiter;
1642 XMLProperty *caprop;
1644 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1645 XMLNode* ca = *caiter;
1649 if ((caprop = ca->property (X_("original"))) == 0) {
1652 orig_id = caprop->value();
1654 if ((caprop = ca->property (X_("copy"))) == 0) {
1657 copy_id = caprop->value();
1659 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1660 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1662 if (!orig || !copy) {
1663 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1669 RegionFactory::add_compound_association (orig, copy);
1676 Session::load_nested_sources (const XMLNode& node)
1679 XMLNodeConstIterator niter;
1681 nlist = node.children();
1683 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1684 if ((*niter)->name() == "Source") {
1686 /* it may already exist, so don't recreate it unnecessarily
1689 XMLProperty* prop = (*niter)->property (X_("id"));
1691 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1695 ID source_id (prop->value());
1697 if (!source_by_id (source_id)) {
1700 SourceFactory::create (*this, **niter, true);
1702 catch (failed_constructor& err) {
1703 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1710 boost::shared_ptr<Region>
1711 Session::XMLRegionFactory (const XMLNode& node, bool full)
1713 const XMLProperty* type = node.property("type");
1717 const XMLNodeList& nlist = node.children();
1719 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1720 XMLNode *child = (*niter);
1721 if (child->name() == "NestedSource") {
1722 load_nested_sources (*child);
1726 if (!type || type->value() == "audio") {
1727 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1728 } else if (type->value() == "midi") {
1729 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1732 } catch (failed_constructor& err) {
1733 return boost::shared_ptr<Region> ();
1736 return boost::shared_ptr<Region> ();
1739 boost::shared_ptr<AudioRegion>
1740 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1742 const XMLProperty* prop;
1743 boost::shared_ptr<Source> source;
1744 boost::shared_ptr<AudioSource> as;
1746 SourceList master_sources;
1747 uint32_t nchans = 1;
1750 if (node.name() != X_("Region")) {
1751 return boost::shared_ptr<AudioRegion>();
1754 if ((prop = node.property (X_("channels"))) != 0) {
1755 nchans = atoi (prop->value().c_str());
1758 if ((prop = node.property ("name")) == 0) {
1759 cerr << "no name for this region\n";
1763 if ((prop = node.property (X_("source-0"))) == 0) {
1764 if ((prop = node.property ("source")) == 0) {
1765 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1766 return boost::shared_ptr<AudioRegion>();
1770 PBD::ID s_id (prop->value());
1772 if ((source = source_by_id (s_id)) == 0) {
1773 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1774 return boost::shared_ptr<AudioRegion>();
1777 as = boost::dynamic_pointer_cast<AudioSource>(source);
1779 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1780 return boost::shared_ptr<AudioRegion>();
1783 sources.push_back (as);
1785 /* pickup other channels */
1787 for (uint32_t n=1; n < nchans; ++n) {
1788 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1789 if ((prop = node.property (buf)) != 0) {
1791 PBD::ID id2 (prop->value());
1793 if ((source = source_by_id (id2)) == 0) {
1794 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1795 return boost::shared_ptr<AudioRegion>();
1798 as = boost::dynamic_pointer_cast<AudioSource>(source);
1800 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1801 return boost::shared_ptr<AudioRegion>();
1803 sources.push_back (as);
1807 for (uint32_t n = 0; n < nchans; ++n) {
1808 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1809 if ((prop = node.property (buf)) != 0) {
1811 PBD::ID id2 (prop->value());
1813 if ((source = source_by_id (id2)) == 0) {
1814 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1815 return boost::shared_ptr<AudioRegion>();
1818 as = boost::dynamic_pointer_cast<AudioSource>(source);
1820 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1821 return boost::shared_ptr<AudioRegion>();
1823 master_sources.push_back (as);
1828 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1830 /* a final detail: this is the one and only place that we know how long missing files are */
1832 if (region->whole_file()) {
1833 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1834 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1836 sfp->set_length (region->length());
1841 if (!master_sources.empty()) {
1842 if (master_sources.size() != nchans) {
1843 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1845 region->set_master_sources (master_sources);
1853 catch (failed_constructor& err) {
1854 return boost::shared_ptr<AudioRegion>();
1858 boost::shared_ptr<MidiRegion>
1859 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1861 const XMLProperty* prop;
1862 boost::shared_ptr<Source> source;
1863 boost::shared_ptr<MidiSource> ms;
1866 if (node.name() != X_("Region")) {
1867 return boost::shared_ptr<MidiRegion>();
1870 if ((prop = node.property ("name")) == 0) {
1871 cerr << "no name for this region\n";
1875 if ((prop = node.property (X_("source-0"))) == 0) {
1876 if ((prop = node.property ("source")) == 0) {
1877 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1878 return boost::shared_ptr<MidiRegion>();
1882 PBD::ID s_id (prop->value());
1884 if ((source = source_by_id (s_id)) == 0) {
1885 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1886 return boost::shared_ptr<MidiRegion>();
1889 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1891 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1892 return boost::shared_ptr<MidiRegion>();
1895 sources.push_back (ms);
1898 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1899 /* a final detail: this is the one and only place that we know how long missing files are */
1901 if (region->whole_file()) {
1902 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1903 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1905 sfp->set_length (region->length());
1913 catch (failed_constructor& err) {
1914 return boost::shared_ptr<MidiRegion>();
1919 Session::get_sources_as_xml ()
1922 XMLNode* node = new XMLNode (X_("Sources"));
1923 Glib::Mutex::Lock lm (source_lock);
1925 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1926 node->add_child_nocopy (i->second->get_state());
1933 Session::path_from_region_name (DataType type, string name, string identifier)
1935 char buf[PATH_MAX+1];
1937 SessionDirectory sdir(get_best_session_directory_for_new_source());
1938 sys::path source_dir = ((type == DataType::AUDIO)
1939 ? sdir.sound_path() : sdir.midi_path());
1941 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1943 for (n = 0; n < 999999; ++n) {
1944 if (identifier.length()) {
1945 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1946 identifier.c_str(), n, ext.c_str());
1948 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1952 sys::path source_path = source_dir / buf;
1954 if (!sys::exists (source_path)) {
1955 return source_path.to_string();
1959 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1968 Session::load_sources (const XMLNode& node)
1971 XMLNodeConstIterator niter;
1972 boost::shared_ptr<Source> source;
1974 nlist = node.children();
1978 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1981 if ((source = XMLSourceFactory (**niter)) == 0) {
1982 error << _("Session: cannot create Source from XML description.") << endmsg;
1985 } catch (MissingSource& err) {
1989 if (!no_questions_about_missing_files) {
1990 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1995 switch (user_choice) {
1997 /* user added a new search location, so try again */
2002 /* user asked to quit the entire session load
2007 no_questions_about_missing_files = true;
2011 no_questions_about_missing_files = true;
2016 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
2017 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2026 boost::shared_ptr<Source>
2027 Session::XMLSourceFactory (const XMLNode& node)
2029 if (node.name() != "Source") {
2030 return boost::shared_ptr<Source>();
2034 /* note: do peak building in another thread when loading session state */
2035 return SourceFactory::create (*this, node, true);
2038 catch (failed_constructor& err) {
2039 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2040 return boost::shared_ptr<Source>();
2045 Session::save_template (string template_name)
2049 if (_state_of_the_state & CannotSave) {
2053 sys::path user_template_dir(user_template_directory());
2057 sys::create_directories (user_template_dir);
2059 catch(sys::filesystem_error& ex)
2061 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2062 user_template_dir.to_string(), ex.what()) << endmsg;
2066 tree.set_root (&get_template());
2068 sys::path template_dir_path(user_template_dir);
2070 /* directory to put the template in */
2071 template_dir_path /= template_name;
2072 if (sys::exists (template_dir_path))
2074 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2075 template_dir_path.to_string()) << endmsg;
2079 sys::create_directories (template_dir_path);
2082 sys::path template_file_path = template_dir_path;
2083 template_file_path /= template_name + template_suffix;
2085 if (!tree.write (template_file_path.to_string())) {
2086 error << _("template not saved") << endmsg;
2090 /* copy plugin state directory */
2092 sys::path template_plugin_state_path = template_dir_path;
2093 template_plugin_state_path /= X_("plugins");
2094 sys::create_directories (template_plugin_state_path);
2095 sys::copy_files (plugins_dir(), template_plugin_state_path);
2101 Session::refresh_disk_space ()
2104 struct statfs statfsbuf;
2105 vector<space_and_path>::iterator i;
2106 Glib::Mutex::Lock lm (space_lock);
2109 /* get freespace on every FS that is part of the session path */
2111 _total_free_4k_blocks = 0;
2113 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2114 statfs ((*i).path.c_str(), &statfsbuf);
2116 scale = statfsbuf.f_bsize/4096.0;
2118 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2119 _total_free_4k_blocks += (*i).blocks;
2125 Session::get_best_session_directory_for_new_source ()
2127 vector<space_and_path>::iterator i;
2128 string result = _session_dir->root_path().to_string();
2130 /* handle common case without system calls */
2132 if (session_dirs.size() == 1) {
2136 /* OK, here's the algorithm we're following here:
2138 We want to select which directory to use for
2139 the next file source to be created. Ideally,
2140 we'd like to use a round-robin process so as to
2141 get maximum performance benefits from splitting
2142 the files across multiple disks.
2144 However, in situations without much diskspace, an
2145 RR approach may end up filling up a filesystem
2146 with new files while others still have space.
2147 Its therefore important to pay some attention to
2148 the freespace in the filesystem holding each
2149 directory as well. However, if we did that by
2150 itself, we'd keep creating new files in the file
2151 system with the most space until it was as full
2152 as all others, thus negating any performance
2153 benefits of this RAID-1 like approach.
2155 So, we use a user-configurable space threshold. If
2156 there are at least 2 filesystems with more than this
2157 much space available, we use RR selection between them.
2158 If not, then we pick the filesystem with the most space.
2160 This gets a good balance between the two
2164 refresh_disk_space ();
2166 int free_enough = 0;
2168 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2169 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2174 if (free_enough >= 2) {
2175 /* use RR selection process, ensuring that the one
2179 i = last_rr_session_dir;
2182 if (++i == session_dirs.end()) {
2183 i = session_dirs.begin();
2186 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2187 if (create_session_directory ((*i).path)) {
2189 last_rr_session_dir = i;
2194 } while (i != last_rr_session_dir);
2198 /* pick FS with the most freespace (and that
2199 seems to actually work ...)
2202 vector<space_and_path> sorted;
2203 space_and_path_ascending_cmp cmp;
2205 sorted = session_dirs;
2206 sort (sorted.begin(), sorted.end(), cmp);
2208 for (i = sorted.begin(); i != sorted.end(); ++i) {
2209 if (create_session_directory ((*i).path)) {
2211 last_rr_session_dir = i;
2221 Session::load_named_selections (const XMLNode& node)
2224 XMLNodeConstIterator niter;
2227 nlist = node.children();
2231 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2233 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2234 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2242 Session::XMLNamedSelectionFactory (const XMLNode& node)
2245 return new NamedSelection (*this, node);
2248 catch (failed_constructor& err) {
2254 Session::automation_dir () const
2256 return Glib::build_filename (_path, "automation");
2260 Session::analysis_dir () const
2262 return Glib::build_filename (_path, "analysis");
2266 Session::plugins_dir () const
2268 return Glib::build_filename (_path, "plugins");
2272 Session::externals_dir () const
2274 return Glib::build_filename (_path, "externals");
2278 Session::load_bundles (XMLNode const & node)
2280 XMLNodeList nlist = node.children();
2281 XMLNodeConstIterator niter;
2285 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2286 if ((*niter)->name() == "InputBundle") {
2287 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2288 } else if ((*niter)->name() == "OutputBundle") {
2289 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2291 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2300 Session::load_route_groups (const XMLNode& node, int version)
2302 XMLNodeList nlist = node.children();
2303 XMLNodeConstIterator niter;
2307 if (version >= 3000) {
2309 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2310 if ((*niter)->name() == "RouteGroup") {
2311 RouteGroup* rg = new RouteGroup (*this, "");
2312 add_route_group (rg);
2313 rg->set_state (**niter, version);
2317 } else if (version < 3000) {
2319 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2320 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2321 RouteGroup* rg = new RouteGroup (*this, "");
2322 add_route_group (rg);
2323 rg->set_state (**niter, version);
2332 Session::auto_save()
2334 save_state (_current_snapshot_name);
2338 state_file_filter (const string &str, void */*arg*/)
2340 return (str.length() > strlen(statefile_suffix) &&
2341 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2345 bool operator()(const string* a, const string* b) {
2351 remove_end(string* state)
2353 string statename(*state);
2355 string::size_type start,end;
2356 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2357 statename = statename.substr (start+1);
2360 if ((end = statename.rfind(".ardour")) == string::npos) {
2361 end = statename.length();
2364 return new string(statename.substr (0, end));
2368 Session::possible_states (string path)
2370 PathScanner scanner;
2371 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2373 transform(states->begin(), states->end(), states->begin(), remove_end);
2376 sort (states->begin(), states->end(), cmp);
2382 Session::possible_states () const
2384 return possible_states(_path);
2388 Session::add_route_group (RouteGroup* g)
2390 _route_groups.push_back (g);
2391 route_group_added (g); /* EMIT SIGNAL */
2393 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2394 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2395 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2401 Session::remove_route_group (RouteGroup& rg)
2403 list<RouteGroup*>::iterator i;
2405 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2406 _route_groups.erase (i);
2409 route_group_removed (); /* EMIT SIGNAL */
2413 /** Set a new order for our route groups, without adding or removing any.
2414 * @param groups Route group list in the new order.
2417 Session::reorder_route_groups (list<RouteGroup*> groups)
2419 _route_groups = groups;
2421 route_groups_reordered (); /* EMIT SIGNAL */
2427 Session::route_group_by_name (string name)
2429 list<RouteGroup *>::iterator i;
2431 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2432 if ((*i)->name() == name) {
2440 Session::all_route_group() const
2442 return *_all_route_group;
2446 Session::add_commands (vector<Command*> const & cmds)
2448 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2454 Session::begin_reversible_command (const string& name)
2456 begin_reversible_command (g_quark_from_string (name.c_str ()));
2459 /** Begin a reversible command using a GQuark to identify it.
2460 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2461 * but there must be as many begin...()s as there are commit...()s.
2464 Session::begin_reversible_command (GQuark q)
2466 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2467 to hold all the commands that are committed. This keeps the order of
2468 commands correct in the history.
2471 if (_current_trans == 0) {
2472 /* start a new transaction */
2473 assert (_current_trans_quarks.empty ());
2474 _current_trans = new UndoTransaction();
2475 _current_trans->set_name (g_quark_to_string (q));
2478 _current_trans_quarks.push_front (q);
2482 Session::commit_reversible_command (Command *cmd)
2484 assert (_current_trans);
2485 assert (!_current_trans_quarks.empty ());
2490 _current_trans->add_command (cmd);
2493 _current_trans_quarks.pop_front ();
2495 if (!_current_trans_quarks.empty ()) {
2496 /* the transaction we're committing is not the top-level one */
2500 if (_current_trans->empty()) {
2501 /* no commands were added to the transaction, so just get rid of it */
2502 delete _current_trans;
2507 gettimeofday (&now, 0);
2508 _current_trans->set_timestamp (now);
2510 _history.add (_current_trans);
2515 accept_all_audio_files (const string& path, void */*arg*/)
2517 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2521 if (!AudioFileSource::safe_audio_file_extension (path)) {
2529 accept_all_midi_files (const string& path, void */*arg*/)
2531 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2535 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2536 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2537 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2541 accept_all_state_files (const string& path, void */*arg*/)
2543 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2547 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2551 Session::find_all_sources (string path, set<string>& result)
2556 if (!tree.read (path)) {
2560 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2565 XMLNodeConstIterator niter;
2567 nlist = node->children();
2571 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2575 if ((prop = (*niter)->property (X_("type"))) == 0) {
2579 DataType type (prop->value());
2581 if ((prop = (*niter)->property (X_("name"))) == 0) {
2585 if (Glib::path_is_absolute (prop->value())) {
2586 /* external file, ignore */
2594 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2595 result.insert (found_path);
2603 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2605 PathScanner scanner;
2606 vector<string*>* state_files;
2608 string this_snapshot_path;
2614 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2615 ripped = ripped.substr (0, ripped.length() - 1);
2618 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2620 if (state_files == 0) {
2625 this_snapshot_path = _path;
2626 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2627 this_snapshot_path += statefile_suffix;
2629 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2631 if (exclude_this_snapshot && **i == this_snapshot_path) {
2635 if (find_all_sources (**i, result) < 0) {
2643 struct RegionCounter {
2644 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2645 AudioSourceList::iterator iter;
2646 boost::shared_ptr<Region> region;
2649 RegionCounter() : count (0) {}
2653 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2655 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2656 return r.get_value_or (1);
2660 Session::cleanup_regions ()
2662 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2664 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2666 uint32_t used = playlists->region_use_count (i->second);
2668 if (used == 0 && !i->second->automatic ()) {
2669 RegionFactory::map_remove (i->second);
2673 /* dump the history list */
2680 Session::cleanup_sources (CleanupReport& rep)
2682 // FIXME: needs adaptation to midi
2684 vector<boost::shared_ptr<Source> > dead_sources;
2685 PathScanner scanner;
2688 vector<space_and_path>::iterator i;
2689 vector<space_and_path>::iterator nexti;
2690 vector<string*>* candidates;
2691 vector<string*>* candidates2;
2692 vector<string> unused;
2693 set<string> all_sources;
2698 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2700 /* consider deleting all unused playlists */
2702 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2707 /* sync the "all regions" property of each playlist with its current state
2710 playlists->sync_all_regions_with_regions ();
2712 /* find all un-used sources */
2717 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2719 SourceMap::iterator tmp;
2724 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2728 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2729 dead_sources.push_back (i->second);
2730 i->second->drop_references ();
2736 /* build a list of all the possible audio directories for the session */
2738 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2743 SessionDirectory sdir ((*i).path);
2744 audio_path += sdir.sound_path().to_string();
2746 if (nexti != session_dirs.end()) {
2754 /* build a list of all the possible midi directories for the session */
2756 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2761 SessionDirectory sdir ((*i).path);
2762 midi_path += sdir.midi_path().to_string();
2764 if (nexti != session_dirs.end()) {
2771 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2772 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2778 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2779 candidates->push_back (*i);
2784 candidates = candidates2; // might still be null
2787 /* find all sources, but don't use this snapshot because the
2788 state file on disk still references sources we may have already
2792 find_all_sources_across_snapshots (all_sources, true);
2794 /* add our current source list
2797 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2798 boost::shared_ptr<FileSource> fs;
2799 SourceMap::iterator tmp = i;
2802 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2803 if (playlists->source_use_count (fs) != 0) {
2804 all_sources.insert (fs->path());
2807 /* we might not remove this source from disk, because it may be used
2808 by other snapshots, but its not being used in this version
2809 so lets get rid of it now, along with any representative regions
2813 RegionFactory::remove_regions_using_source (i->second);
2821 char tmppath1[PATH_MAX+1];
2822 char tmppath2[PATH_MAX+1];
2825 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2830 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2832 if (realpath(spath.c_str(), tmppath1) == 0) {
2833 error << string_compose (_("Cannot expand path %1 (%2)"),
2834 spath, strerror (errno)) << endmsg;
2838 if (realpath((*i).c_str(), tmppath2) == 0) {
2839 error << string_compose (_("Cannot expand path %1 (%2)"),
2840 (*i), strerror (errno)) << endmsg;
2844 if (strcmp(tmppath1, tmppath2) == 0) {
2851 unused.push_back (spath);
2860 /* now try to move all unused files into the "dead" directory(ies) */
2862 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2863 struct stat statbuf;
2867 /* don't move the file across filesystems, just
2868 stick it in the `dead_dir_name' directory
2869 on whichever filesystem it was already on.
2872 if ((*x).find ("/sounds/") != string::npos) {
2874 /* old school, go up 1 level */
2876 newpath = Glib::path_get_dirname (*x); // "sounds"
2877 newpath = Glib::path_get_dirname (newpath); // "session-name"
2881 /* new school, go up 4 levels */
2883 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2884 newpath = Glib::path_get_dirname (newpath); // "session-name"
2885 newpath = Glib::path_get_dirname (newpath); // "interchange"
2886 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2889 newpath = Glib::build_filename (newpath, dead_dir_name);
2891 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2892 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2896 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2898 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2900 /* the new path already exists, try versioning */
2902 char buf[PATH_MAX+1];
2906 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2909 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2910 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2914 if (version == 999) {
2915 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2919 newpath = newpath_v;
2924 /* it doesn't exist, or we can't read it or something */
2928 stat ((*x).c_str(), &statbuf);
2930 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2931 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2932 (*x), newpath, strerror (errno))
2937 /* see if there an easy to find peakfile for this file, and remove it.
2940 string base = basename_nosuffix (*x);
2941 base += "%A"; /* this is what we add for the channel suffix of all native files,
2942 or for the first channel of embedded files. it will miss
2943 some peakfiles for other channels
2945 string peakpath = peak_path (base);
2947 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2948 if (::unlink (peakpath.c_str()) != 0) {
2949 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2950 peakpath, _path, strerror (errno))
2952 /* try to back out */
2953 ::rename (newpath.c_str(), _path.c_str());
2958 rep.paths.push_back (*x);
2959 rep.space += statbuf.st_size;
2962 /* dump the history list */
2966 /* save state so we don't end up a session file
2967 referring to non-existent sources.
2974 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2980 Session::cleanup_trash_sources (CleanupReport& rep)
2982 // FIXME: needs adaptation for MIDI
2984 vector<space_and_path>::iterator i;
2990 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2992 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2994 clear_directory (dead_dir, &rep.space, &rep.paths);
3001 Session::set_dirty ()
3003 bool was_dirty = dirty();
3005 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3009 DirtyChanged(); /* EMIT SIGNAL */
3015 Session::set_clean ()
3017 bool was_dirty = dirty();
3019 _state_of_the_state = Clean;
3023 DirtyChanged(); /* EMIT SIGNAL */
3028 Session::set_deletion_in_progress ()
3030 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3034 Session::clear_deletion_in_progress ()
3036 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3040 Session::add_controllable (boost::shared_ptr<Controllable> c)
3042 /* this adds a controllable to the list managed by the Session.
3043 this is a subset of those managed by the Controllable class
3044 itself, and represents the only ones whose state will be saved
3045 as part of the session.
3048 Glib::Mutex::Lock lm (controllables_lock);
3049 controllables.insert (c);
3052 struct null_deleter { void operator()(void const *) const {} };
3055 Session::remove_controllable (Controllable* c)
3057 if (_state_of_the_state & Deletion) {
3061 Glib::Mutex::Lock lm (controllables_lock);
3063 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3065 if (x != controllables.end()) {
3066 controllables.erase (x);
3070 boost::shared_ptr<Controllable>
3071 Session::controllable_by_id (const PBD::ID& id)
3073 Glib::Mutex::Lock lm (controllables_lock);
3075 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3076 if ((*i)->id() == id) {
3081 return boost::shared_ptr<Controllable>();
3084 boost::shared_ptr<Controllable>
3085 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3087 boost::shared_ptr<Controllable> c;
3088 boost::shared_ptr<Route> r;
3090 switch (desc.top_level_type()) {
3091 case ControllableDescriptor::NamedRoute:
3093 std::string str = desc.top_level_name();
3094 if (str == "master") {
3096 } else if (str == "control" || str == "listen") {
3099 r = route_by_name (desc.top_level_name());
3104 case ControllableDescriptor::RemoteControlID:
3105 r = route_by_remote_id (desc.rid());
3113 switch (desc.subtype()) {
3114 case ControllableDescriptor::Gain:
3115 c = r->gain_control ();
3118 case ControllableDescriptor::Solo:
3119 c = r->solo_control();
3122 case ControllableDescriptor::Mute:
3123 c = r->mute_control();
3126 case ControllableDescriptor::Recenable:
3128 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3131 c = t->rec_enable_control ();
3136 case ControllableDescriptor::PanDirection:
3138 c = r->pannable()->pan_azimuth_control;
3142 case ControllableDescriptor::PanWidth:
3144 c = r->pannable()->pan_width_control;
3148 case ControllableDescriptor::PanElevation:
3150 c = r->pannable()->pan_elevation_control;
3154 case ControllableDescriptor::Balance:
3155 /* XXX simple pan control */
3158 case ControllableDescriptor::PluginParameter:
3160 uint32_t plugin = desc.target (0);
3161 uint32_t parameter_index = desc.target (1);
3163 /* revert to zero based counting */
3169 if (parameter_index > 0) {
3173 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3176 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3177 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3182 case ControllableDescriptor::SendGain:
3184 uint32_t send = desc.target (0);
3186 /* revert to zero-based counting */
3192 boost::shared_ptr<Processor> p = r->nth_send (send);
3195 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3196 boost::shared_ptr<Amp> a = s->amp();
3199 c = s->amp()->gain_control();
3206 /* relax and return a null pointer */
3214 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3217 Stateful::add_instant_xml (node, _path);
3220 if (write_to_config) {
3221 Config->add_instant_xml (node);
3226 Session::instant_xml (const string& node_name)
3228 return Stateful::instant_xml (node_name, _path);
3232 Session::save_history (string snapshot_name)
3240 if (snapshot_name.empty()) {
3241 snapshot_name = _current_snapshot_name;
3244 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3245 const string backup_filename = history_filename + backup_suffix;
3246 const sys::path xml_path = _session_dir->root_path() / history_filename;
3247 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3249 if (sys::exists (xml_path)) {
3252 sys::rename (xml_path, backup_path);
3254 catch (const sys::filesystem_error& err)
3256 error << _("could not backup old history file, current history not saved") << endmsg;
3261 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3265 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3267 if (!tree.write (xml_path.to_string()))
3269 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3273 sys::remove (xml_path);
3274 sys::rename (backup_path, xml_path);
3276 catch (const sys::filesystem_error& err)
3278 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3279 backup_path.to_string(), err.what()) << endmsg;
3289 Session::restore_history (string snapshot_name)
3293 if (snapshot_name.empty()) {
3294 snapshot_name = _current_snapshot_name;
3297 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3298 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3300 info << "Loading history from " << xml_path.to_string() << endmsg;
3302 if (!sys::exists (xml_path)) {
3303 info << string_compose (_("%1: no history file \"%2\" for this session."),
3304 _name, xml_path.to_string()) << endmsg;
3308 if (!tree.read (xml_path.to_string())) {
3309 error << string_compose (_("Could not understand session history file \"%1\""),
3310 xml_path.to_string()) << endmsg;
3317 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3320 UndoTransaction* ut = new UndoTransaction ();
3323 ut->set_name(t->property("name")->value());
3324 stringstream ss(t->property("tv-sec")->value());
3326 ss.str(t->property("tv-usec")->value());
3328 ut->set_timestamp(tv);
3330 for (XMLNodeConstIterator child_it = t->children().begin();
3331 child_it != t->children().end(); child_it++)
3333 XMLNode *n = *child_it;
3336 if (n->name() == "MementoCommand" ||
3337 n->name() == "MementoUndoCommand" ||
3338 n->name() == "MementoRedoCommand") {
3340 if ((c = memento_command_factory(n))) {
3344 } else if (n->name() == "NoteDiffCommand") {
3345 PBD::ID id (n->property("midi-source")->value());
3346 boost::shared_ptr<MidiSource> midi_source =
3347 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3349 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3351 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3354 } else if (n->name() == "SysExDiffCommand") {
3356 PBD::ID id (n->property("midi-source")->value());
3357 boost::shared_ptr<MidiSource> midi_source =
3358 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3360 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3362 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3365 } else if (n->name() == "PatchChangeDiffCommand") {
3367 PBD::ID id (n->property("midi-source")->value());
3368 boost::shared_ptr<MidiSource> midi_source =
3369 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3371 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3373 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3376 } else if (n->name() == "StatefulDiffCommand") {
3377 if ((c = stateful_diff_command_factory (n))) {
3378 ut->add_command (c);
3381 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3392 Session::config_changed (std::string p, bool ours)
3398 if (p == "seamless-loop") {
3400 } else if (p == "rf-speed") {
3402 } else if (p == "auto-loop") {
3404 } else if (p == "auto-input") {
3406 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3407 /* auto-input only makes a difference if we're rolling */
3408 set_track_monitor_input_status (!config.get_auto_input());
3411 } else if (p == "punch-in") {
3415 if ((location = _locations->auto_punch_location()) != 0) {
3417 if (config.get_punch_in ()) {
3418 replace_event (SessionEvent::PunchIn, location->start());
3420 remove_event (location->start(), SessionEvent::PunchIn);
3424 } else if (p == "punch-out") {
3428 if ((location = _locations->auto_punch_location()) != 0) {
3430 if (config.get_punch_out()) {
3431 replace_event (SessionEvent::PunchOut, location->end());
3433 clear_events (SessionEvent::PunchOut);
3437 } else if (p == "edit-mode") {
3439 Glib::Mutex::Lock lm (playlists->lock);
3441 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3442 (*i)->set_edit_mode (Config->get_edit_mode ());
3445 } else if (p == "use-video-sync") {
3447 waiting_for_sync_offset = config.get_use_video_sync();
3449 } else if (p == "mmc-control") {
3451 //poke_midi_thread ();
3453 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3455 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3457 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3459 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3461 } else if (p == "midi-control") {
3463 //poke_midi_thread ();
3465 } else if (p == "raid-path") {
3467 setup_raid_path (config.get_raid_path());
3469 } else if (p == "timecode-format") {
3473 } else if (p == "video-pullup") {
3477 } else if (p == "seamless-loop") {
3479 if (play_loop && transport_rolling()) {
3480 // to reset diskstreams etc
3481 request_play_loop (true);
3484 } else if (p == "rf-speed") {
3486 cumulative_rf_motion = 0;
3489 } else if (p == "click-sound") {
3491 setup_click_sounds (1);
3493 } else if (p == "click-emphasis-sound") {
3495 setup_click_sounds (-1);
3497 } else if (p == "clicking") {
3499 if (Config->get_clicking()) {
3500 if (_click_io && click_data) { // don't require emphasis data
3507 } else if (p == "click-gain") {
3510 _click_gain->set_gain (Config->get_click_gain(), this);
3513 } else if (p == "send-mtc") {
3515 if (Config->get_send_mtc ()) {
3516 /* mark us ready to send */
3517 next_quarter_frame_to_send = 0;
3520 } else if (p == "send-mmc") {
3522 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3524 } else if (p == "midi-feedback") {
3526 session_midi_feedback = Config->get_midi_feedback();
3528 } else if (p == "jack-time-master") {
3530 engine().reset_timebase ();
3532 } else if (p == "native-file-header-format") {
3534 if (!first_file_header_format_reset) {
3535 reset_native_file_format ();
3538 first_file_header_format_reset = false;
3540 } else if (p == "native-file-data-format") {
3542 if (!first_file_data_format_reset) {
3543 reset_native_file_format ();
3546 first_file_data_format_reset = false;
3548 } else if (p == "external-sync") {
3549 if (!config.get_external_sync()) {
3550 drop_sync_source ();
3552 switch_to_sync_source (config.get_sync_source());
3554 } else if (p == "remote-model") {
3555 set_remote_control_ids ();
3556 } else if (p == "denormal-model") {
3558 } else if (p == "history-depth") {
3559 set_history_depth (Config->get_history_depth());
3560 } else if (p == "sync-all-route-ordering") {
3561 sync_order_keys ("session");
3562 } else if (p == "initial-program-change") {
3564 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3567 buf[0] = MIDI::program; // channel zero by default
3568 buf[1] = (Config->get_initial_program_change() & 0x7f);
3570 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3572 } else if (p == "solo-mute-override") {
3573 // catch_up_on_solo_mute_override ();
3574 } else if (p == "listen-position" || p == "pfl-position") {
3575 listen_position_changed ();
3576 } else if (p == "solo-control-is-listen-control") {
3577 solo_control_mode_changed ();
3578 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3579 last_timecode_valid = false;
3580 } else if (p == "playback-buffer-seconds") {
3581 AudioSource::allocate_working_buffers (frame_rate());
3582 } else if (p == "automation-thinning-factor") {
3583 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3590 Session::set_history_depth (uint32_t d)
3592 _history.set_depth (d);
3596 Session::load_diskstreams_2X (XMLNode const & node, int)
3599 XMLNodeConstIterator citer;
3601 clist = node.children();
3603 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3606 /* diskstreams added automatically by DiskstreamCreated handler */
3607 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3608 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3609 _diskstreams_2X.push_back (dsp);
3611 error << _("Session: unknown diskstream type in XML") << endmsg;
3615 catch (failed_constructor& err) {
3616 error << _("Session: could not load diskstream via XML state") << endmsg;
3624 /** Connect things to the MMC object */
3626 Session::setup_midi_machine_control ()
3628 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3630 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3631 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3632 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3633 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3634 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3635 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3636 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3637 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3638 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3639 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3640 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3641 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3642 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3644 /* also handle MIDI SPP because its so common */
3646 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3647 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3648 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));
3651 boost::shared_ptr<Controllable>
3652 Session::solo_cut_control() const
3654 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3655 controls in Ardour that currently get presented to the user in the GUI that require
3656 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3658 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3659 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3663 return _solo_cut_control;
3667 Session::rename (const std::string& new_name)
3669 string legal_name = legalize_for_path (new_name);
3675 string const old_sources_root = _session_dir->sources_root().to_string ();
3677 #define RENAME ::rename
3682 * interchange subdirectory
3686 * Backup files are left unchanged and not renamed.
3689 /* pass one: not 100% safe check that the new directory names don't
3693 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3698 /* this is a stupid hack because Glib::path_get_dirname() is
3699 * lexical-only, and so passing it /a/b/c/ gives a different
3700 * result than passing it /a/b/c ...
3703 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3704 oldstr = oldstr.substr (0, oldstr.length() - 1);
3707 string base = Glib::path_get_dirname (oldstr);
3708 string p = Glib::path_get_basename (oldstr);
3710 newstr = Glib::build_filename (base, legal_name);
3712 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3719 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3724 /* this is a stupid hack because Glib::path_get_dirname() is
3725 * lexical-only, and so passing it /a/b/c/ gives a different
3726 * result than passing it /a/b/c ...
3729 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3730 oldstr = oldstr.substr (0, oldstr.length() - 1);
3733 string base = Glib::path_get_dirname (oldstr);
3734 string p = Glib::path_get_basename (oldstr);
3736 newstr = Glib::build_filename (base, legal_name);
3738 cerr << "Rename " << oldstr << " => " << newstr << endl;
3740 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3745 (*_session_dir) = newstr;
3750 /* directory below interchange */
3752 v.push_back (newstr);
3753 v.push_back (interchange_dir_name);
3756 oldstr = Glib::build_filename (v);
3759 v.push_back (newstr);
3760 v.push_back (interchange_dir_name);
3761 v.push_back (legal_name);
3763 newstr = Glib::build_filename (v);
3765 cerr << "Rename " << oldstr << " => " << newstr << endl;
3767 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3774 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3775 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3777 cerr << "Rename " << oldstr << " => " << newstr << endl;
3779 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3786 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3788 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3789 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3791 cerr << "Rename " << oldstr << " => " << newstr << endl;
3793 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3798 /* update file source paths */
3800 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3801 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3803 string p = fs->path ();
3804 boost::replace_all (p, old_sources_root, _session_dir->sources_root().to_string ());
3809 /* remove old name from recent sessions */
3811 remove_recent_sessions (_path);
3814 _current_snapshot_name = new_name;
3819 /* save state again to get everything just right */
3821 save_state (_current_snapshot_name);
3824 /* add to recent sessions */
3826 store_recent_sessions (new_name, _path);