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>
49 #ifdef HAVE_SYS_STATVFS_H
50 #include <sys/statvfs.h>
54 #include <glib/gstdio.h>
57 #include <glibmm/thread.h>
59 #include <boost/algorithm/string.hpp>
61 #include "midi++/mmc.h"
62 #include "midi++/port.h"
63 #include "midi++/manager.h"
65 #include "evoral/SMF.hpp"
67 #include "pbd/boost_debug.h"
68 #include "pbd/basename.h"
69 #include "pbd/controllable_descriptor.h"
70 #include "pbd/enumwriter.h"
71 #include "pbd/error.h"
72 #include "pbd/filesystem.h"
73 #include "pbd/file_utils.h"
74 #include "pbd/pathscanner.h"
75 #include "pbd/pthread_utils.h"
76 #include "pbd/search_path.h"
77 #include "pbd/stacktrace.h"
78 #include "pbd/convert.h"
79 #include "pbd/clear_dir.h"
81 #include "ardour/amp.h"
82 #include "ardour/audio_diskstream.h"
83 #include "ardour/audio_track.h"
84 #include "ardour/audioengine.h"
85 #include "ardour/audiofilesource.h"
86 #include "ardour/audioregion.h"
87 #include "ardour/automation_control.h"
88 #include "ardour/butler.h"
89 #include "ardour/control_protocol_manager.h"
90 #include "ardour/directory_names.h"
91 #include "ardour/filename_extensions.h"
92 #include "ardour/location.h"
93 #include "ardour/midi_model.h"
94 #include "ardour/midi_patch_manager.h"
95 #include "ardour/midi_region.h"
96 #include "ardour/midi_source.h"
97 #include "ardour/midi_track.h"
98 #include "ardour/named_selection.h"
99 #include "ardour/pannable.h"
100 #include "ardour/playlist_factory.h"
101 #include "ardour/port.h"
102 #include "ardour/processor.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_playlists.h"
112 #include "ardour/session_state_utils.h"
113 #include "ardour/session_utils.h"
114 #include "ardour/silentfilesource.h"
115 #include "ardour/sndfilesource.h"
116 #include "ardour/source_factory.h"
117 #include "ardour/speakers.h"
118 #include "ardour/template_utils.h"
119 #include "ardour/tempo.h"
120 #include "ardour/ticker.h"
121 #include "ardour/user_bundle.h"
123 #include "control_protocol/control_protocol.h"
129 using namespace ARDOUR;
132 /** @param snapshot_name Snapshot name, without the .ardour prefix */
134 Session::first_stage_init (string fullpath, string snapshot_name)
136 if (fullpath.length() == 0) {
138 throw failed_constructor();
141 char buf[PATH_MAX+1];
142 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
143 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
145 throw failed_constructor();
150 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
151 _path += G_DIR_SEPARATOR;
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->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
170 _non_soloed_outs_muted = false;
172 _solo_isolated_cnt = 0;
173 g_atomic_int_set (&processing_prohibited, 0);
174 _transport_speed = 0;
175 _default_transport_speed = 1.0;
176 _last_transport_speed = 0;
177 _target_transport_speed = 0;
178 auto_play_legal = false;
179 transport_sub_state = 0;
180 _transport_frame = 0;
181 _requested_return_frame = -1;
182 _session_range_location = 0;
183 g_atomic_int_set (&_record_status, Disabled);
184 loop_changing = false;
187 _last_roll_location = 0;
188 _last_roll_or_reversal_location = 0;
189 _last_record_location = 0;
190 pending_locate_frame = 0;
191 pending_locate_roll = false;
192 pending_locate_flush = false;
193 state_was_pending = false;
195 outbound_mtc_timecode_frame = 0;
196 next_quarter_frame_to_send = -1;
197 current_block_size = 0;
198 solo_update_disabled = false;
199 _have_captured = false;
200 _worst_output_latency = 0;
201 _worst_input_latency = 0;
202 _worst_track_latency = 0;
203 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
204 _was_seamless = Config->get_seamless_loop ();
206 _send_qf_mtc = false;
207 _pframes_since_last_mtc = 0;
208 g_atomic_int_set (&_playback_load, 100);
209 g_atomic_int_set (&_capture_load, 100);
212 pending_abort = false;
213 destructive_index = 0;
214 first_file_data_format_reset = true;
215 first_file_header_format_reset = true;
216 post_export_sync = false;
219 no_questions_about_missing_files = false;
220 _speakers.reset (new Speakers);
222 ignore_route_processor_changes = false;
223 _pre_export_mmc_enabled = false;
225 AudioDiskstream::allocate_working_buffers();
227 /* default short fade = 15ms */
229 SndFileSource::setup_standard_crossfades (*this, frame_rate());
231 last_mmc_step.tv_sec = 0;
232 last_mmc_step.tv_usec = 0;
235 /* click sounds are unset by default, which causes us to internal
236 waveforms for clicks.
240 click_emphasis_length = 0;
243 process_function = &Session::process_with_events;
245 if (config.get_use_video_sync()) {
246 waiting_for_sync_offset = true;
248 waiting_for_sync_offset = false;
251 last_timecode_when = 0;
252 last_timecode_valid = false;
256 last_rr_session_dir = session_dirs.begin();
257 refresh_disk_space ();
259 /* default: assume simple stereo speaker configuration */
261 _speakers->setup_default_speakers (2);
265 average_slave_delta = 1800; // !!! why 1800 ????
266 have_first_delta_accumulator = false;
267 delta_accumulator_cnt = 0;
268 _slave_state = Stopped;
270 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
271 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
272 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
273 add_controllable (_solo_cut_control);
275 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
277 /* These are all static "per-class" signals */
279 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
280 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
281 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
282 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
283 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
285 /* stop IO objects from doing stuff until we're ready for them */
287 Delivery::disable_panners ();
288 IO::disable_connecting ();
292 Session::second_stage_init ()
294 AudioFileSource::set_peak_dir (_session_dir->peak_path());
297 if (load_state (_current_snapshot_name)) {
302 if (_butler->start_thread()) {
306 if (start_midi_thread ()) {
310 setup_midi_machine_control ();
312 // set_state() will call setup_raid_path(), but if it's a new session we need
313 // to call setup_raid_path() here.
316 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
320 setup_raid_path(_path);
323 /* we can't save till after ::when_engine_running() is called,
324 because otherwise we save state with no connections made.
325 therefore, we reset _state_of_the_state because ::set_state()
326 will have cleared it.
328 we also have to include Loading so that any events that get
329 generated between here and the end of ::when_engine_running()
330 will be processed directly rather than queued.
333 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
335 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
336 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
337 setup_click_sounds (0);
338 setup_midi_control ();
340 /* Pay attention ... */
342 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
343 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
345 midi_clock = new MidiClockTicker ();
346 midi_clock->set_session (this);
349 when_engine_running ();
352 /* handle this one in a different way than all others, so that its clear what happened */
354 catch (AudioEngine::PortRegistrationFailure& err) {
355 error << err.what() << endmsg;
363 BootMessage (_("Reset Remote Controls"));
365 send_full_time_code (0);
366 _engine.transport_locate (0);
368 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
369 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
371 MIDI::Name::MidiPatchManager::instance().set_session (this);
373 /* initial program change will be delivered later; see ::config_changed() */
375 _state_of_the_state = Clean;
377 Port::set_connecting_blocked (false);
379 DirtyChanged (); /* EMIT SIGNAL */
381 if (state_was_pending) {
382 save_state (_current_snapshot_name);
383 remove_pending_capture_state ();
384 state_was_pending = false;
387 BootMessage (_("Session loading complete"));
393 Session::raid_path () const
395 SearchPath raid_search_path;
397 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
398 raid_search_path += (*i).path;
401 return raid_search_path.to_string ();
405 Session::setup_raid_path (string path)
414 session_dirs.clear ();
416 SearchPath search_path(path);
417 SearchPath sound_search_path;
418 SearchPath midi_search_path;
420 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
422 sp.blocks = 0; // not needed
423 session_dirs.push_back (sp);
425 SessionDirectory sdir(sp.path);
427 sound_search_path += sdir.sound_path ();
428 midi_search_path += sdir.midi_path ();
431 // reset the round-robin soundfile path thingie
432 last_rr_session_dir = session_dirs.begin();
436 Session::path_is_within_session (const std::string& path)
438 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
439 if (PBD::path_is_within (i->path, path)) {
447 Session::ensure_subdirs ()
451 dir = session_directory().peak_path();
453 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
454 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
458 dir = session_directory().sound_path();
460 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
461 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
465 dir = session_directory().midi_path();
467 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
468 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
472 dir = session_directory().dead_path();
474 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
475 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
479 dir = session_directory().export_path();
481 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
482 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
486 dir = analysis_dir ();
488 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
489 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
493 dir = plugins_dir ();
495 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
496 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
500 dir = externals_dir ();
502 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
503 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
510 /** @param session_template directory containing session template, or empty.
511 * Caller must not hold process lock.
514 Session::create (const string& session_template, BusProfile* bus_profile)
516 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
517 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
521 if (ensure_subdirs ()) {
525 _writable = exists_and_writable (_path);
527 if (!session_template.empty()) {
528 std::string in_path = session_template_dir_to_file (session_template);
530 ifstream in(in_path.c_str());
533 string out_path = _path;
535 out_path += statefile_suffix;
537 ofstream out(out_path.c_str());
543 /* Copy plugin state files from template to new session */
544 std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
545 copy_files (template_plugins, plugins_dir ());
550 error << string_compose (_("Could not open %1 for writing session template"), out_path)
556 error << string_compose (_("Could not open session template %1 for reading"), in_path)
563 /* set initial start + end point */
565 _state_of_the_state = Clean;
567 /* set up Master Out and Control Out if necessary */
572 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
574 if (bus_profile->master_out_channels) {
575 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
579 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
580 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
583 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
584 r->input()->ensure_io (count, false, this);
585 r->output()->ensure_io (count, false, this);
591 /* prohibit auto-connect to master, because there isn't one */
592 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
596 add_routes (rl, false, false, false);
599 /* this allows the user to override settings with an environment variable.
602 if (no_auto_connect()) {
603 bus_profile->input_ac = AutoConnectOption (0);
604 bus_profile->output_ac = AutoConnectOption (0);
607 Config->set_input_auto_connect (bus_profile->input_ac);
608 Config->set_output_auto_connect (bus_profile->output_ac);
611 if (Config->get_use_monitor_bus() && bus_profile) {
612 add_monitor_section ();
621 Session::maybe_write_autosave()
623 if (dirty() && record_status() != Recording) {
624 save_state("", true);
629 Session::remove_pending_capture_state ()
631 std::string pending_state_file_path(_session_dir->root_path());
633 pending_state_file_path = Glib::build_filename (pending_state_file_path, legalize_for_path (_current_snapshot_name) + pending_suffix);
635 if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS)) return;
637 if (g_remove (pending_state_file_path.c_str()) != 0) {
638 error << string_compose(_("Could not remove pending capture state at path \"%1\" (%2)"),
639 pending_state_file_path, g_strerror (errno)) << endmsg;
643 /** Rename a state file.
644 * @param old_name Old snapshot name.
645 * @param new_name New snapshot name.
648 Session::rename_state (string old_name, string new_name)
650 if (old_name == _current_snapshot_name || old_name == _name) {
651 /* refuse to rename the current snapshot or the "main" one */
655 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
656 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
658 const sys::path old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
659 const sys::path new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
663 sys::rename (old_xml_path, new_xml_path);
665 catch (const sys::filesystem_error& err)
667 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
668 old_name, new_name, err.what()) << endmsg;
672 /** Remove a state file.
673 * @param snapshot_name Snapshot name.
676 Session::remove_state (string snapshot_name)
678 if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
679 // refuse to remove the current snapshot or the "main" one
683 std::string xml_path(_session_dir->root_path());
685 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
687 if (!create_backup_file (xml_path)) {
688 // don't remove it if a backup can't be made
689 // create_backup_file will log the error.
694 sys::remove (xml_path);
697 #ifdef HAVE_JACK_SESSION
699 Session::jack_session_event (jack_session_event_t * event)
703 struct tm local_time;
706 localtime_r (&n, &local_time);
707 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
709 if (event->type == JackSessionSaveTemplate)
711 if (save_template( timebuf )) {
712 event->flags = JackSessionSaveError;
714 string cmd ("ardour3 -P -U ");
715 cmd += event->client_uuid;
719 event->command_line = strdup (cmd.c_str());
724 if (save_state (timebuf)) {
725 event->flags = JackSessionSaveError;
727 sys::path xml_path (_session_dir->root_path());
728 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
730 string cmd ("ardour3 -P -U ");
731 cmd += event->client_uuid;
733 cmd += xml_path.to_string();
736 event->command_line = strdup (cmd.c_str());
740 jack_session_reply (_engine.jack(), event);
742 if (event->type == JackSessionSaveAndQuit) {
743 Quit (); /* EMIT SIGNAL */
746 jack_session_event_free( event );
750 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
752 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
755 std::string xml_path(_session_dir->root_path());
757 if (!_writable || (_state_of_the_state & CannotSave)) {
761 if (!_engine.connected ()) {
762 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
768 /* tell sources we're saving first, in case they write out to a new file
769 * which should be saved with the state rather than the old one */
770 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
772 i->second->session_saved();
773 } catch (Evoral::SMF::FileError& e) {
774 error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
778 tree.set_root (&get_state());
780 if (snapshot_name.empty()) {
781 snapshot_name = _current_snapshot_name;
782 } else if (switch_to_snapshot) {
783 _current_snapshot_name = snapshot_name;
788 /* proper save: use statefile_suffix (.ardour in English) */
790 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
792 /* make a backup copy of the old file */
794 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
795 // create_backup_file will log the error
801 /* pending save: use pending_suffix (.pending in English) */
802 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
805 sys::path tmp_path(_session_dir->root_path());
807 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
809 // cerr << "actually writing state to " << xml_path.to_string() << endl;
811 if (!tree.write (tmp_path.to_string())) {
812 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
813 sys::remove (tmp_path);
818 if (::rename (tmp_path.to_string().c_str(), xml_path.c_str()) != 0) {
819 error << string_compose (_("could not rename temporary session file %1 to %2"),
820 tmp_path.to_string(), xml_path) << endmsg;
821 sys::remove (tmp_path);
828 save_history (snapshot_name);
830 bool was_dirty = dirty();
832 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
835 DirtyChanged (); /* EMIT SIGNAL */
838 StateSaved (snapshot_name); /* EMIT SIGNAL */
845 Session::restore_state (string snapshot_name)
847 if (load_state (snapshot_name) == 0) {
848 set_state (*state_tree->root(), Stateful::loading_state_version);
855 Session::load_state (string snapshot_name)
860 state_was_pending = false;
862 /* check for leftover pending state from a crashed capture attempt */
864 sys::path xmlpath(_session_dir->root_path());
865 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
867 if (sys::exists (xmlpath)) {
869 /* there is pending state from a crashed capture attempt */
871 boost::optional<int> r = AskAboutPendingState();
872 if (r.get_value_or (1)) {
873 state_was_pending = true;
877 if (!state_was_pending) {
878 xmlpath = _session_dir->root_path();
879 xmlpath /= snapshot_name;
882 if (!sys::exists (xmlpath)) {
883 xmlpath = _session_dir->root_path();
884 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
885 if (!sys::exists (xmlpath)) {
886 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
891 state_tree = new XMLTree;
895 _writable = exists_and_writable (xmlpath.to_string());
897 if (!state_tree->read (xmlpath.to_string())) {
898 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
904 XMLNode& root (*state_tree->root());
906 if (root.name() != X_("Session")) {
907 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
913 const XMLProperty* prop;
915 if ((prop = root.property ("version")) == 0) {
916 /* no version implies very old version of Ardour */
917 Stateful::loading_state_version = 1000;
919 if (prop->value().find ('.') != string::npos) {
920 /* old school version format */
921 if (prop->value()[0] == '2') {
922 Stateful::loading_state_version = 2000;
924 Stateful::loading_state_version = 3000;
927 Stateful::loading_state_version = atoi (prop->value());
931 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
933 sys::path backup_path(_session_dir->root_path());
935 backup_path /= string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
937 // only create a backup for a given statefile version once
939 if (!sys::exists (backup_path)) {
941 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
942 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
945 if (!copy_file (xmlpath.to_string(), backup_path.to_string())) {;
955 Session::load_options (const XMLNode& node)
957 LocaleGuard lg (X_("POSIX"));
958 config.set_variables (node);
969 Session::get_template()
971 /* if we don't disable rec-enable, diskstreams
972 will believe they need to store their capture
973 sources in their state node.
976 disable_record (false);
982 Session::state (bool full_state)
984 XMLNode* node = new XMLNode("Session");
988 snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
989 node->add_property("version", buf);
991 /* store configuration settings */
995 node->add_property ("name", _name);
996 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
997 node->add_property ("sample-rate", buf);
999 if (session_dirs.size() > 1) {
1003 vector<space_and_path>::iterator i = session_dirs.begin();
1004 vector<space_and_path>::iterator next;
1006 ++i; /* skip the first one */
1010 while (i != session_dirs.end()) {
1014 if (next != session_dirs.end()) {
1024 child = node->add_child ("Path");
1025 child->add_content (p);
1029 /* save the ID counter */
1031 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1032 node->add_property ("id-counter", buf);
1034 /* save the event ID counter */
1036 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1037 node->add_property ("event-counter", buf);
1039 /* various options */
1041 node->add_child_nocopy (config.get_variables ());
1043 node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
1045 child = node->add_child ("Sources");
1048 Glib::Mutex::Lock sl (source_lock);
1050 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1052 /* Don't save information about non-file Sources, or
1053 * about non-destructive file sources that are empty
1054 * and unused by any regions.
1057 boost::shared_ptr<FileSource> fs;
1059 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1061 if (!fs->destructive()) {
1062 if (fs->empty() && !fs->used()) {
1067 child->add_child_nocopy (siter->second->get_state());
1072 child = node->add_child ("Regions");
1075 Glib::Mutex::Lock rl (region_lock);
1076 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1077 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1078 boost::shared_ptr<Region> r = i->second;
1079 /* only store regions not attached to playlists */
1080 if (r->playlist() == 0) {
1081 child->add_child_nocopy (r->state ());
1085 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1087 if (!cassocs.empty()) {
1088 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1090 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1092 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1093 i->first->id().print (buf, sizeof (buf));
1094 can->add_property (X_("copy"), buf);
1095 i->second->id().print (buf, sizeof (buf));
1096 can->add_property (X_("original"), buf);
1097 ca->add_child_nocopy (*can);
1103 node->add_child_nocopy (_locations->get_state());
1105 // for a template, just create a new Locations, populate it
1106 // with the default start and end, and get the state for that.
1107 Locations loc (*this);
1108 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1109 range->set (max_framepos, 0);
1111 node->add_child_nocopy (loc.get_state());
1114 child = node->add_child ("Bundles");
1116 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1117 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1118 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1120 child->add_child_nocopy (b->get_state());
1125 child = node->add_child ("Routes");
1127 boost::shared_ptr<RouteList> r = routes.reader ();
1129 RoutePublicOrderSorter cmp;
1130 RouteList public_order (*r);
1131 public_order.sort (cmp);
1133 /* the sort should have put control outs first */
1136 assert (_monitor_out == public_order.front());
1139 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1140 if (!(*i)->is_hidden()) {
1142 child->add_child_nocopy ((*i)->get_state());
1144 child->add_child_nocopy ((*i)->get_template());
1150 playlists->add_state (node, full_state);
1152 child = node->add_child ("RouteGroups");
1153 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1154 child->add_child_nocopy ((*i)->get_state());
1158 XMLNode* gain_child = node->add_child ("Click");
1159 gain_child->add_child_nocopy (_click_io->state (full_state));
1160 gain_child->add_child_nocopy (_click_gain->state (full_state));
1164 XMLNode* ns_child = node->add_child ("NamedSelections");
1165 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1167 ns_child->add_child_nocopy ((*i)->get_state());
1172 node->add_child_nocopy (_speakers->get_state());
1173 node->add_child_nocopy (_tempo_map->get_state());
1174 node->add_child_nocopy (get_control_protocol_state());
1177 node->add_child_copy (*_extra_xml);
1184 Session::get_control_protocol_state ()
1186 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1187 return cpm.get_state();
1191 Session::set_state (const XMLNode& node, int version)
1195 const XMLProperty* prop;
1198 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1200 if (node.name() != X_("Session")) {
1201 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1205 if ((prop = node.property ("name")) != 0) {
1206 _name = prop->value ();
1209 if ((prop = node.property (X_("sample-rate"))) != 0) {
1211 _nominal_frame_rate = atoi (prop->value());
1213 if (_nominal_frame_rate != _current_frame_rate) {
1214 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1215 if (r.get_value_or (0)) {
1221 setup_raid_path(_session_dir->root_path());
1223 if ((prop = node.property (X_("id-counter"))) != 0) {
1225 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1226 ID::init_counter (x);
1228 /* old sessions used a timebased counter, so fake
1229 the startup ID counter based on a standard
1234 ID::init_counter (now);
1237 if ((prop = node.property (X_("event-counter"))) != 0) {
1238 Evoral::init_event_id_counter (atoi (prop->value()));
1241 IO::disable_connecting ();
1243 Stateful::save_extra_xml (node);
1245 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1246 load_options (*child);
1247 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1248 load_options (*child);
1250 error << _("Session: XML state has no options section") << endmsg;
1253 if (version >= 3000) {
1254 if ((child = find_named_node (node, "Metadata")) == 0) {
1255 warning << _("Session: XML state has no metadata section") << endmsg;
1256 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1261 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1262 _speakers->set_state (*child, version);
1265 if ((child = find_named_node (node, "Sources")) == 0) {
1266 error << _("Session: XML state has no sources section") << endmsg;
1268 } else if (load_sources (*child)) {
1272 if ((child = find_named_node (node, "TempoMap")) == 0) {
1273 error << _("Session: XML state has no Tempo Map section") << endmsg;
1275 } else if (_tempo_map->set_state (*child, version)) {
1279 if ((child = find_named_node (node, "Locations")) == 0) {
1280 error << _("Session: XML state has no locations section") << endmsg;
1282 } else if (_locations->set_state (*child, version)) {
1288 if ((location = _locations->auto_loop_location()) != 0) {
1289 set_auto_loop_location (location);
1292 if ((location = _locations->auto_punch_location()) != 0) {
1293 set_auto_punch_location (location);
1296 if ((location = _locations->session_range_location()) != 0) {
1297 delete _session_range_location;
1298 _session_range_location = location;
1301 if (_session_range_location) {
1302 AudioFileSource::set_header_position_offset (_session_range_location->start());
1305 if ((child = find_named_node (node, "Regions")) == 0) {
1306 error << _("Session: XML state has no Regions section") << endmsg;
1308 } else if (load_regions (*child)) {
1312 if ((child = find_named_node (node, "Playlists")) == 0) {
1313 error << _("Session: XML state has no playlists section") << endmsg;
1315 } else if (playlists->load (*this, *child)) {
1319 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1321 } else if (playlists->load_unused (*this, *child)) {
1325 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1326 if (load_compounds (*child)) {
1331 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1332 if (load_named_selections (*child)) {
1337 if (version >= 3000) {
1338 if ((child = find_named_node (node, "Bundles")) == 0) {
1339 warning << _("Session: XML state has no bundles section") << endmsg;
1342 /* We can't load Bundles yet as they need to be able
1343 to convert from port names to Port objects, which can't happen until
1345 _bundle_xml_node = new XMLNode (*child);
1349 if (version < 3000) {
1350 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1351 error << _("Session: XML state has no diskstreams section") << endmsg;
1353 } else if (load_diskstreams_2X (*child, version)) {
1358 if ((child = find_named_node (node, "Routes")) == 0) {
1359 error << _("Session: XML state has no routes section") << endmsg;
1361 } else if (load_routes (*child, version)) {
1365 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1366 _diskstreams_2X.clear ();
1368 if (version >= 3000) {
1370 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1371 error << _("Session: XML state has no route groups section") << endmsg;
1373 } else if (load_route_groups (*child, version)) {
1377 } else if (version < 3000) {
1379 if ((child = find_named_node (node, "EditGroups")) == 0) {
1380 error << _("Session: XML state has no edit groups section") << endmsg;
1382 } else if (load_route_groups (*child, version)) {
1386 if ((child = find_named_node (node, "MixGroups")) == 0) {
1387 error << _("Session: XML state has no mix groups section") << endmsg;
1389 } else if (load_route_groups (*child, version)) {
1394 if ((child = find_named_node (node, "Click")) == 0) {
1395 warning << _("Session: XML state has no click section") << endmsg;
1396 } else if (_click_io) {
1397 const XMLNodeList& children (child->children());
1398 XMLNodeList::const_iterator i = children.begin();
1399 _click_io->set_state (**i, version);
1401 if (i != children.end()) {
1402 _click_gain->set_state (**i, version);
1406 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1407 ControlProtocolManager::instance().set_protocol_states (*child);
1410 update_have_rec_enabled_track ();
1412 /* here beginneth the second phase ... */
1414 StateReady (); /* EMIT SIGNAL */
1423 Session::load_routes (const XMLNode& node, int version)
1426 XMLNodeConstIterator niter;
1427 RouteList new_routes;
1429 nlist = node.children();
1433 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1435 boost::shared_ptr<Route> route;
1436 if (version < 3000) {
1437 route = XMLRouteFactory_2X (**niter, version);
1439 route = XMLRouteFactory (**niter, version);
1443 error << _("Session: cannot create Route from XML description.") << endmsg;
1447 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1449 new_routes.push_back (route);
1452 add_routes (new_routes, false, false, false);
1457 boost::shared_ptr<Route>
1458 Session::XMLRouteFactory (const XMLNode& node, int version)
1460 boost::shared_ptr<Route> ret;
1462 if (node.name() != "Route") {
1466 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1468 DataType type = DataType::AUDIO;
1469 const XMLProperty* prop = node.property("default-type");
1472 type = DataType (prop->value());
1475 assert (type != DataType::NIL);
1479 boost::shared_ptr<Track> track;
1481 if (type == DataType::AUDIO) {
1482 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1484 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1487 if (track->init()) {
1491 if (track->set_state (node, version)) {
1495 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1496 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1501 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1503 if (r->init () == 0 && r->set_state (node, version) == 0) {
1504 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1505 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1514 boost::shared_ptr<Route>
1515 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1517 boost::shared_ptr<Route> ret;
1519 if (node.name() != "Route") {
1523 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1525 ds_prop = node.property (X_("diskstream"));
1528 DataType type = DataType::AUDIO;
1529 const XMLProperty* prop = node.property("default-type");
1532 type = DataType (prop->value());
1535 assert (type != DataType::NIL);
1539 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1540 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1544 if (i == _diskstreams_2X.end()) {
1545 error << _("Could not find diskstream for route") << endmsg;
1546 return boost::shared_ptr<Route> ();
1549 boost::shared_ptr<Track> track;
1551 if (type == DataType::AUDIO) {
1552 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1554 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1557 if (track->init()) {
1561 if (track->set_state (node, version)) {
1565 track->set_diskstream (*i);
1567 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1568 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1573 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1575 if (r->init () == 0 && r->set_state (node, version) == 0) {
1576 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1577 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1587 Session::load_regions (const XMLNode& node)
1590 XMLNodeConstIterator niter;
1591 boost::shared_ptr<Region> region;
1593 nlist = node.children();
1597 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1598 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1599 error << _("Session: cannot create Region from XML description.");
1600 const XMLProperty *name = (**niter).property("name");
1603 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1614 Session::load_compounds (const XMLNode& node)
1616 XMLNodeList calist = node.children();
1617 XMLNodeConstIterator caiter;
1618 XMLProperty *caprop;
1620 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1621 XMLNode* ca = *caiter;
1625 if ((caprop = ca->property (X_("original"))) == 0) {
1628 orig_id = caprop->value();
1630 if ((caprop = ca->property (X_("copy"))) == 0) {
1633 copy_id = caprop->value();
1635 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1636 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1638 if (!orig || !copy) {
1639 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1645 RegionFactory::add_compound_association (orig, copy);
1652 Session::load_nested_sources (const XMLNode& node)
1655 XMLNodeConstIterator niter;
1657 nlist = node.children();
1659 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1660 if ((*niter)->name() == "Source") {
1662 /* it may already exist, so don't recreate it unnecessarily
1665 XMLProperty* prop = (*niter)->property (X_("id"));
1667 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1671 ID source_id (prop->value());
1673 if (!source_by_id (source_id)) {
1676 SourceFactory::create (*this, **niter, true);
1678 catch (failed_constructor& err) {
1679 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1686 boost::shared_ptr<Region>
1687 Session::XMLRegionFactory (const XMLNode& node, bool full)
1689 const XMLProperty* type = node.property("type");
1693 const XMLNodeList& nlist = node.children();
1695 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1696 XMLNode *child = (*niter);
1697 if (child->name() == "NestedSource") {
1698 load_nested_sources (*child);
1702 if (!type || type->value() == "audio") {
1703 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1704 } else if (type->value() == "midi") {
1705 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1708 } catch (failed_constructor& err) {
1709 return boost::shared_ptr<Region> ();
1712 return boost::shared_ptr<Region> ();
1715 boost::shared_ptr<AudioRegion>
1716 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1718 const XMLProperty* prop;
1719 boost::shared_ptr<Source> source;
1720 boost::shared_ptr<AudioSource> as;
1722 SourceList master_sources;
1723 uint32_t nchans = 1;
1726 if (node.name() != X_("Region")) {
1727 return boost::shared_ptr<AudioRegion>();
1730 if ((prop = node.property (X_("channels"))) != 0) {
1731 nchans = atoi (prop->value().c_str());
1734 if ((prop = node.property ("name")) == 0) {
1735 cerr << "no name for this region\n";
1739 if ((prop = node.property (X_("source-0"))) == 0) {
1740 if ((prop = node.property ("source")) == 0) {
1741 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1742 return boost::shared_ptr<AudioRegion>();
1746 PBD::ID s_id (prop->value());
1748 if ((source = source_by_id (s_id)) == 0) {
1749 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1750 return boost::shared_ptr<AudioRegion>();
1753 as = boost::dynamic_pointer_cast<AudioSource>(source);
1755 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1756 return boost::shared_ptr<AudioRegion>();
1759 sources.push_back (as);
1761 /* pickup other channels */
1763 for (uint32_t n=1; n < nchans; ++n) {
1764 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1765 if ((prop = node.property (buf)) != 0) {
1767 PBD::ID id2 (prop->value());
1769 if ((source = source_by_id (id2)) == 0) {
1770 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1771 return boost::shared_ptr<AudioRegion>();
1774 as = boost::dynamic_pointer_cast<AudioSource>(source);
1776 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1777 return boost::shared_ptr<AudioRegion>();
1779 sources.push_back (as);
1783 for (uint32_t n = 0; n < nchans; ++n) {
1784 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1785 if ((prop = node.property (buf)) != 0) {
1787 PBD::ID id2 (prop->value());
1789 if ((source = source_by_id (id2)) == 0) {
1790 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1791 return boost::shared_ptr<AudioRegion>();
1794 as = boost::dynamic_pointer_cast<AudioSource>(source);
1796 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1797 return boost::shared_ptr<AudioRegion>();
1799 master_sources.push_back (as);
1804 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1806 /* a final detail: this is the one and only place that we know how long missing files are */
1808 if (region->whole_file()) {
1809 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1810 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1812 sfp->set_length (region->length());
1817 if (!master_sources.empty()) {
1818 if (master_sources.size() != nchans) {
1819 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1821 region->set_master_sources (master_sources);
1829 catch (failed_constructor& err) {
1830 return boost::shared_ptr<AudioRegion>();
1834 boost::shared_ptr<MidiRegion>
1835 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1837 const XMLProperty* prop;
1838 boost::shared_ptr<Source> source;
1839 boost::shared_ptr<MidiSource> ms;
1842 if (node.name() != X_("Region")) {
1843 return boost::shared_ptr<MidiRegion>();
1846 if ((prop = node.property ("name")) == 0) {
1847 cerr << "no name for this region\n";
1851 if ((prop = node.property (X_("source-0"))) == 0) {
1852 if ((prop = node.property ("source")) == 0) {
1853 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1854 return boost::shared_ptr<MidiRegion>();
1858 PBD::ID s_id (prop->value());
1860 if ((source = source_by_id (s_id)) == 0) {
1861 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1862 return boost::shared_ptr<MidiRegion>();
1865 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1867 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1868 return boost::shared_ptr<MidiRegion>();
1871 sources.push_back (ms);
1874 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1875 /* a final detail: this is the one and only place that we know how long missing files are */
1877 if (region->whole_file()) {
1878 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1879 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1881 sfp->set_length (region->length());
1889 catch (failed_constructor& err) {
1890 return boost::shared_ptr<MidiRegion>();
1895 Session::get_sources_as_xml ()
1898 XMLNode* node = new XMLNode (X_("Sources"));
1899 Glib::Mutex::Lock lm (source_lock);
1901 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1902 node->add_child_nocopy (i->second->get_state());
1909 Session::path_from_region_name (DataType type, string name, string identifier)
1911 char buf[PATH_MAX+1];
1913 SessionDirectory sdir(get_best_session_directory_for_new_source());
1914 sys::path source_dir = ((type == DataType::AUDIO)
1915 ? sdir.sound_path() : sdir.midi_path());
1917 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1919 for (n = 0; n < 999999; ++n) {
1920 if (identifier.length()) {
1921 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1922 identifier.c_str(), n, ext.c_str());
1924 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1928 sys::path source_path = source_dir / buf;
1930 if (!sys::exists (source_path)) {
1931 return source_path.to_string();
1935 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1944 Session::load_sources (const XMLNode& node)
1947 XMLNodeConstIterator niter;
1948 boost::shared_ptr<Source> source;
1950 nlist = node.children();
1954 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1957 if ((source = XMLSourceFactory (**niter)) == 0) {
1958 error << _("Session: cannot create Source from XML description.") << endmsg;
1961 } catch (MissingSource& err) {
1965 if (!no_questions_about_missing_files) {
1966 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1971 switch (user_choice) {
1973 /* user added a new search location, so try again */
1978 /* user asked to quit the entire session load
1983 no_questions_about_missing_files = true;
1987 no_questions_about_missing_files = true;
1992 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1993 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2002 boost::shared_ptr<Source>
2003 Session::XMLSourceFactory (const XMLNode& node)
2005 if (node.name() != "Source") {
2006 return boost::shared_ptr<Source>();
2010 /* note: do peak building in another thread when loading session state */
2011 return SourceFactory::create (*this, node, true);
2014 catch (failed_constructor& err) {
2015 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2016 return boost::shared_ptr<Source>();
2021 Session::save_template (string template_name)
2025 if (_state_of_the_state & CannotSave) {
2029 sys::path user_template_dir(user_template_directory());
2033 sys::create_directories (user_template_dir);
2035 catch(sys::filesystem_error& ex)
2037 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2038 user_template_dir.to_string(), ex.what()) << endmsg;
2042 tree.set_root (&get_template());
2044 sys::path template_dir_path(user_template_dir);
2046 /* directory to put the template in */
2047 template_dir_path /= template_name;
2048 if (sys::exists (template_dir_path))
2050 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2051 template_dir_path.to_string()) << endmsg;
2055 sys::create_directories (template_dir_path);
2058 sys::path template_file_path = template_dir_path;
2059 template_file_path /= template_name + template_suffix;
2061 if (!tree.write (template_file_path.to_string())) {
2062 error << _("template not saved") << endmsg;
2066 /* copy plugin state directory */
2068 sys::path template_plugin_state_path = template_dir_path;
2069 template_plugin_state_path /= X_("plugins");
2070 sys::create_directories (template_plugin_state_path);
2071 copy_files (plugins_dir(), template_plugin_state_path.to_string());
2077 Session::refresh_disk_space ()
2079 #if HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H
2081 Glib::Mutex::Lock lm (space_lock);
2083 /* get freespace on every FS that is part of the session path */
2085 _total_free_4k_blocks = 0;
2086 _total_free_4k_blocks_uncertain = false;
2088 for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2090 struct statfs statfsbuf;
2091 statfs (i->path.c_str(), &statfsbuf);
2093 double const scale = statfsbuf.f_bsize / 4096.0;
2095 /* See if this filesystem is read-only */
2096 struct statvfs statvfsbuf;
2097 statvfs (i->path.c_str(), &statvfsbuf);
2099 /* f_bavail can be 0 if it is undefined for whatever
2100 filesystem we are looking at; Samba shares mounted
2101 via GVFS are an example of this.
2103 if (statfsbuf.f_bavail == 0) {
2104 /* block count unknown */
2106 i->blocks_unknown = true;
2107 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2108 /* read-only filesystem */
2110 i->blocks_unknown = false;
2112 /* read/write filesystem with known space */
2113 i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2114 i->blocks_unknown = false;
2117 _total_free_4k_blocks += i->blocks;
2118 if (i->blocks_unknown) {
2119 _total_free_4k_blocks_uncertain = true;
2126 Session::get_best_session_directory_for_new_source ()
2128 vector<space_and_path>::iterator i;
2129 string result = _session_dir->root_path();
2131 /* handle common case without system calls */
2133 if (session_dirs.size() == 1) {
2137 /* OK, here's the algorithm we're following here:
2139 We want to select which directory to use for
2140 the next file source to be created. Ideally,
2141 we'd like to use a round-robin process so as to
2142 get maximum performance benefits from splitting
2143 the files across multiple disks.
2145 However, in situations without much diskspace, an
2146 RR approach may end up filling up a filesystem
2147 with new files while others still have space.
2148 Its therefore important to pay some attention to
2149 the freespace in the filesystem holding each
2150 directory as well. However, if we did that by
2151 itself, we'd keep creating new files in the file
2152 system with the most space until it was as full
2153 as all others, thus negating any performance
2154 benefits of this RAID-1 like approach.
2156 So, we use a user-configurable space threshold. If
2157 there are at least 2 filesystems with more than this
2158 much space available, we use RR selection between them.
2159 If not, then we pick the filesystem with the most space.
2161 This gets a good balance between the two
2165 refresh_disk_space ();
2167 int free_enough = 0;
2169 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2170 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2175 if (free_enough >= 2) {
2176 /* use RR selection process, ensuring that the one
2180 i = last_rr_session_dir;
2183 if (++i == session_dirs.end()) {
2184 i = session_dirs.begin();
2187 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2188 if (create_session_directory ((*i).path)) {
2190 last_rr_session_dir = i;
2195 } while (i != last_rr_session_dir);
2199 /* pick FS with the most freespace (and that
2200 seems to actually work ...)
2203 vector<space_and_path> sorted;
2204 space_and_path_ascending_cmp cmp;
2206 sorted = session_dirs;
2207 sort (sorted.begin(), sorted.end(), cmp);
2209 for (i = sorted.begin(); i != sorted.end(); ++i) {
2210 if (create_session_directory ((*i).path)) {
2212 last_rr_session_dir = i;
2222 Session::load_named_selections (const XMLNode& node)
2225 XMLNodeConstIterator niter;
2228 nlist = node.children();
2232 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2234 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2235 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2243 Session::XMLNamedSelectionFactory (const XMLNode& node)
2246 return new NamedSelection (*this, node);
2249 catch (failed_constructor& err) {
2255 Session::automation_dir () const
2257 return Glib::build_filename (_path, "automation");
2261 Session::analysis_dir () const
2263 return Glib::build_filename (_path, "analysis");
2267 Session::plugins_dir () const
2269 return Glib::build_filename (_path, "plugins");
2273 Session::externals_dir () const
2275 return Glib::build_filename (_path, "externals");
2279 Session::load_bundles (XMLNode const & node)
2281 XMLNodeList nlist = node.children();
2282 XMLNodeConstIterator niter;
2286 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2287 if ((*niter)->name() == "InputBundle") {
2288 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2289 } else if ((*niter)->name() == "OutputBundle") {
2290 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2292 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2301 Session::load_route_groups (const XMLNode& node, int version)
2303 XMLNodeList nlist = node.children();
2304 XMLNodeConstIterator niter;
2308 if (version >= 3000) {
2310 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2311 if ((*niter)->name() == "RouteGroup") {
2312 RouteGroup* rg = new RouteGroup (*this, "");
2313 add_route_group (rg);
2314 rg->set_state (**niter, version);
2318 } else if (version < 3000) {
2320 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2321 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2322 RouteGroup* rg = new RouteGroup (*this, "");
2323 add_route_group (rg);
2324 rg->set_state (**niter, version);
2333 Session::auto_save()
2335 save_state (_current_snapshot_name);
2339 state_file_filter (const string &str, void */*arg*/)
2341 return (str.length() > strlen(statefile_suffix) &&
2342 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2346 bool operator()(const string* a, const string* b) {
2352 remove_end(string* state)
2354 string statename(*state);
2356 string::size_type start,end;
2357 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2358 statename = statename.substr (start+1);
2361 if ((end = statename.rfind(".ardour")) == string::npos) {
2362 end = statename.length();
2365 return new string(statename.substr (0, end));
2369 Session::possible_states (string path)
2371 PathScanner scanner;
2372 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2374 transform(states->begin(), states->end(), states->begin(), remove_end);
2377 sort (states->begin(), states->end(), cmp);
2383 Session::possible_states () const
2385 return possible_states(_path);
2389 Session::add_route_group (RouteGroup* g)
2391 _route_groups.push_back (g);
2392 route_group_added (g); /* EMIT SIGNAL */
2394 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2395 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2396 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2402 Session::remove_route_group (RouteGroup& rg)
2404 list<RouteGroup*>::iterator i;
2406 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2407 _route_groups.erase (i);
2410 route_group_removed (); /* EMIT SIGNAL */
2414 /** Set a new order for our route groups, without adding or removing any.
2415 * @param groups Route group list in the new order.
2418 Session::reorder_route_groups (list<RouteGroup*> groups)
2420 _route_groups = groups;
2422 route_groups_reordered (); /* EMIT SIGNAL */
2428 Session::route_group_by_name (string name)
2430 list<RouteGroup *>::iterator i;
2432 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2433 if ((*i)->name() == name) {
2441 Session::all_route_group() const
2443 return *_all_route_group;
2447 Session::add_commands (vector<Command*> const & cmds)
2449 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2455 Session::begin_reversible_command (const string& name)
2457 begin_reversible_command (g_quark_from_string (name.c_str ()));
2460 /** Begin a reversible command using a GQuark to identify it.
2461 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2462 * but there must be as many begin...()s as there are commit...()s.
2465 Session::begin_reversible_command (GQuark q)
2467 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2468 to hold all the commands that are committed. This keeps the order of
2469 commands correct in the history.
2472 if (_current_trans == 0) {
2473 /* start a new transaction */
2474 assert (_current_trans_quarks.empty ());
2475 _current_trans = new UndoTransaction();
2476 _current_trans->set_name (g_quark_to_string (q));
2479 _current_trans_quarks.push_front (q);
2483 Session::commit_reversible_command (Command *cmd)
2485 assert (_current_trans);
2486 assert (!_current_trans_quarks.empty ());
2491 _current_trans->add_command (cmd);
2494 _current_trans_quarks.pop_front ();
2496 if (!_current_trans_quarks.empty ()) {
2497 /* the transaction we're committing is not the top-level one */
2501 if (_current_trans->empty()) {
2502 /* no commands were added to the transaction, so just get rid of it */
2503 delete _current_trans;
2508 gettimeofday (&now, 0);
2509 _current_trans->set_timestamp (now);
2511 _history.add (_current_trans);
2516 accept_all_audio_files (const string& path, void */*arg*/)
2518 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2522 if (!AudioFileSource::safe_audio_file_extension (path)) {
2530 accept_all_midi_files (const string& path, void */*arg*/)
2532 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2536 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2537 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2538 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2542 accept_all_state_files (const string& path, void */*arg*/)
2544 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2548 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2552 Session::find_all_sources (string path, set<string>& result)
2557 if (!tree.read (path)) {
2561 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2566 XMLNodeConstIterator niter;
2568 nlist = node->children();
2572 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2576 if ((prop = (*niter)->property (X_("type"))) == 0) {
2580 DataType type (prop->value());
2582 if ((prop = (*niter)->property (X_("name"))) == 0) {
2586 if (Glib::path_is_absolute (prop->value())) {
2587 /* external file, ignore */
2595 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2596 result.insert (found_path);
2604 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2606 PathScanner scanner;
2607 vector<string*>* state_files;
2609 string this_snapshot_path;
2615 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2616 ripped = ripped.substr (0, ripped.length() - 1);
2619 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2621 if (state_files == 0) {
2626 this_snapshot_path = _path;
2627 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2628 this_snapshot_path += statefile_suffix;
2630 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2632 if (exclude_this_snapshot && **i == this_snapshot_path) {
2636 if (find_all_sources (**i, result) < 0) {
2644 struct RegionCounter {
2645 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2646 AudioSourceList::iterator iter;
2647 boost::shared_ptr<Region> region;
2650 RegionCounter() : count (0) {}
2654 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2656 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2657 return r.get_value_or (1);
2661 Session::cleanup_regions ()
2663 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2665 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2667 uint32_t used = playlists->region_use_count (i->second);
2669 if (used == 0 && !i->second->automatic ()) {
2670 RegionFactory::map_remove (i->second);
2674 /* dump the history list */
2681 Session::cleanup_sources (CleanupReport& rep)
2683 // FIXME: needs adaptation to midi
2685 vector<boost::shared_ptr<Source> > dead_sources;
2686 PathScanner scanner;
2689 vector<space_and_path>::iterator i;
2690 vector<space_and_path>::iterator nexti;
2691 vector<string*>* candidates;
2692 vector<string*>* candidates2;
2693 vector<string> unused;
2694 set<string> all_sources;
2699 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2701 /* consider deleting all unused playlists */
2703 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2708 /* sync the "all regions" property of each playlist with its current state
2711 playlists->sync_all_regions_with_regions ();
2713 /* find all un-used sources */
2718 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2720 SourceMap::iterator tmp;
2725 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2729 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2730 dead_sources.push_back (i->second);
2731 i->second->drop_references ();
2737 /* build a list of all the possible audio directories for the session */
2739 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2744 SessionDirectory sdir ((*i).path);
2745 audio_path += sdir.sound_path();
2747 if (nexti != session_dirs.end()) {
2755 /* build a list of all the possible midi directories for the session */
2757 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2762 SessionDirectory sdir ((*i).path);
2763 midi_path += sdir.midi_path();
2765 if (nexti != session_dirs.end()) {
2772 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2773 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2779 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2780 candidates->push_back (*i);
2785 candidates = candidates2; // might still be null
2788 /* find all sources, but don't use this snapshot because the
2789 state file on disk still references sources we may have already
2793 find_all_sources_across_snapshots (all_sources, true);
2795 /* add our current source list
2798 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2799 boost::shared_ptr<FileSource> fs;
2800 SourceMap::iterator tmp = i;
2803 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2804 if (playlists->source_use_count (fs) != 0) {
2805 all_sources.insert (fs->path());
2808 /* we might not remove this source from disk, because it may be used
2809 by other snapshots, but its not being used in this version
2810 so lets get rid of it now, along with any representative regions
2814 RegionFactory::remove_regions_using_source (i->second);
2822 char tmppath1[PATH_MAX+1];
2823 char tmppath2[PATH_MAX+1];
2826 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2831 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2833 if (realpath(spath.c_str(), tmppath1) == 0) {
2834 error << string_compose (_("Cannot expand path %1 (%2)"),
2835 spath, strerror (errno)) << endmsg;
2839 if (realpath((*i).c_str(), tmppath2) == 0) {
2840 error << string_compose (_("Cannot expand path %1 (%2)"),
2841 (*i), strerror (errno)) << endmsg;
2845 if (strcmp(tmppath1, tmppath2) == 0) {
2852 unused.push_back (spath);
2861 /* now try to move all unused files into the "dead" directory(ies) */
2863 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2864 struct stat statbuf;
2868 /* don't move the file across filesystems, just
2869 stick it in the `dead_dir_name' directory
2870 on whichever filesystem it was already on.
2873 if ((*x).find ("/sounds/") != string::npos) {
2875 /* old school, go up 1 level */
2877 newpath = Glib::path_get_dirname (*x); // "sounds"
2878 newpath = Glib::path_get_dirname (newpath); // "session-name"
2882 /* new school, go up 4 levels */
2884 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2885 newpath = Glib::path_get_dirname (newpath); // "session-name"
2886 newpath = Glib::path_get_dirname (newpath); // "interchange"
2887 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2890 newpath = Glib::build_filename (newpath, dead_dir_name);
2892 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2893 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2897 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2899 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2901 /* the new path already exists, try versioning */
2903 char buf[PATH_MAX+1];
2907 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2910 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2911 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2915 if (version == 999) {
2916 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2920 newpath = newpath_v;
2925 /* it doesn't exist, or we can't read it or something */
2929 stat ((*x).c_str(), &statbuf);
2931 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2932 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2933 (*x), newpath, strerror (errno))
2938 /* see if there an easy to find peakfile for this file, and remove it.
2941 string base = basename_nosuffix (*x);
2942 base += "%A"; /* this is what we add for the channel suffix of all native files,
2943 or for the first channel of embedded files. it will miss
2944 some peakfiles for other channels
2946 string peakpath = peak_path (base);
2948 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2949 if (::unlink (peakpath.c_str()) != 0) {
2950 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2951 peakpath, _path, strerror (errno))
2953 /* try to back out */
2954 ::rename (newpath.c_str(), _path.c_str());
2959 rep.paths.push_back (*x);
2960 rep.space += statbuf.st_size;
2963 /* dump the history list */
2967 /* save state so we don't end up a session file
2968 referring to non-existent sources.
2975 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2981 Session::cleanup_trash_sources (CleanupReport& rep)
2983 // FIXME: needs adaptation for MIDI
2985 vector<space_and_path>::iterator i;
2991 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2993 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2995 clear_directory (dead_dir, &rep.space, &rep.paths);
3002 Session::set_dirty ()
3004 bool was_dirty = dirty();
3006 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3010 DirtyChanged(); /* EMIT SIGNAL */
3016 Session::set_clean ()
3018 bool was_dirty = dirty();
3020 _state_of_the_state = Clean;
3024 DirtyChanged(); /* EMIT SIGNAL */
3029 Session::set_deletion_in_progress ()
3031 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3035 Session::clear_deletion_in_progress ()
3037 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3041 Session::add_controllable (boost::shared_ptr<Controllable> c)
3043 /* this adds a controllable to the list managed by the Session.
3044 this is a subset of those managed by the Controllable class
3045 itself, and represents the only ones whose state will be saved
3046 as part of the session.
3049 Glib::Mutex::Lock lm (controllables_lock);
3050 controllables.insert (c);
3053 struct null_deleter { void operator()(void const *) const {} };
3056 Session::remove_controllable (Controllable* c)
3058 if (_state_of_the_state & Deletion) {
3062 Glib::Mutex::Lock lm (controllables_lock);
3064 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3066 if (x != controllables.end()) {
3067 controllables.erase (x);
3071 boost::shared_ptr<Controllable>
3072 Session::controllable_by_id (const PBD::ID& id)
3074 Glib::Mutex::Lock lm (controllables_lock);
3076 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3077 if ((*i)->id() == id) {
3082 return boost::shared_ptr<Controllable>();
3085 boost::shared_ptr<Controllable>
3086 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3088 boost::shared_ptr<Controllable> c;
3089 boost::shared_ptr<Route> r;
3091 switch (desc.top_level_type()) {
3092 case ControllableDescriptor::NamedRoute:
3094 std::string str = desc.top_level_name();
3095 if (str == "master") {
3097 } else if (str == "control" || str == "listen") {
3100 r = route_by_name (desc.top_level_name());
3105 case ControllableDescriptor::RemoteControlID:
3106 r = route_by_remote_id (desc.rid());
3114 switch (desc.subtype()) {
3115 case ControllableDescriptor::Gain:
3116 c = r->gain_control ();
3119 case ControllableDescriptor::Solo:
3120 c = r->solo_control();
3123 case ControllableDescriptor::Mute:
3124 c = r->mute_control();
3127 case ControllableDescriptor::Recenable:
3129 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3132 c = t->rec_enable_control ();
3137 case ControllableDescriptor::PanDirection:
3139 c = r->pannable()->pan_azimuth_control;
3143 case ControllableDescriptor::PanWidth:
3145 c = r->pannable()->pan_width_control;
3149 case ControllableDescriptor::PanElevation:
3151 c = r->pannable()->pan_elevation_control;
3155 case ControllableDescriptor::Balance:
3156 /* XXX simple pan control */
3159 case ControllableDescriptor::PluginParameter:
3161 uint32_t plugin = desc.target (0);
3162 uint32_t parameter_index = desc.target (1);
3164 /* revert to zero based counting */
3170 if (parameter_index > 0) {
3174 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3177 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3178 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3183 case ControllableDescriptor::SendGain:
3185 uint32_t send = desc.target (0);
3187 /* revert to zero-based counting */
3193 boost::shared_ptr<Processor> p = r->nth_send (send);
3196 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3197 boost::shared_ptr<Amp> a = s->amp();
3200 c = s->amp()->gain_control();
3207 /* relax and return a null pointer */
3215 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3218 Stateful::add_instant_xml (node, _path);
3221 if (write_to_config) {
3222 Config->add_instant_xml (node);
3227 Session::instant_xml (const string& node_name)
3229 return Stateful::instant_xml (node_name, _path);
3233 Session::save_history (string snapshot_name)
3241 if (snapshot_name.empty()) {
3242 snapshot_name = _current_snapshot_name;
3245 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3246 const string backup_filename = history_filename + backup_suffix;
3247 const sys::path xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3248 const sys::path backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3250 if (sys::exists (xml_path)) {
3253 sys::rename (xml_path, backup_path);
3255 catch (const sys::filesystem_error& err)
3257 error << _("could not backup old history file, current history not saved") << endmsg;
3262 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3266 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3268 if (!tree.write (xml_path.to_string()))
3270 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3274 sys::remove (xml_path);
3275 sys::rename (backup_path, xml_path);
3277 catch (const sys::filesystem_error& err)
3279 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3280 backup_path.to_string(), err.what()) << endmsg;
3290 Session::restore_history (string snapshot_name)
3294 if (snapshot_name.empty()) {
3295 snapshot_name = _current_snapshot_name;
3298 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3299 const sys::path xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3301 info << "Loading history from " << xml_path.to_string() << endmsg;
3303 if (!sys::exists (xml_path)) {
3304 info << string_compose (_("%1: no history file \"%2\" for this session."),
3305 _name, xml_path.to_string()) << endmsg;
3309 if (!tree.read (xml_path.to_string())) {
3310 error << string_compose (_("Could not understand session history file \"%1\""),
3311 xml_path.to_string()) << endmsg;
3318 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3321 UndoTransaction* ut = new UndoTransaction ();
3324 ut->set_name(t->property("name")->value());
3325 stringstream ss(t->property("tv-sec")->value());
3327 ss.str(t->property("tv-usec")->value());
3329 ut->set_timestamp(tv);
3331 for (XMLNodeConstIterator child_it = t->children().begin();
3332 child_it != t->children().end(); child_it++)
3334 XMLNode *n = *child_it;
3337 if (n->name() == "MementoCommand" ||
3338 n->name() == "MementoUndoCommand" ||
3339 n->name() == "MementoRedoCommand") {
3341 if ((c = memento_command_factory(n))) {
3345 } else if (n->name() == "NoteDiffCommand") {
3346 PBD::ID id (n->property("midi-source")->value());
3347 boost::shared_ptr<MidiSource> midi_source =
3348 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3350 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3352 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3355 } else if (n->name() == "SysExDiffCommand") {
3357 PBD::ID id (n->property("midi-source")->value());
3358 boost::shared_ptr<MidiSource> midi_source =
3359 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3361 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3363 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3366 } else if (n->name() == "PatchChangeDiffCommand") {
3368 PBD::ID id (n->property("midi-source")->value());
3369 boost::shared_ptr<MidiSource> midi_source =
3370 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3372 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3374 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3377 } else if (n->name() == "StatefulDiffCommand") {
3378 if ((c = stateful_diff_command_factory (n))) {
3379 ut->add_command (c);
3382 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3393 Session::config_changed (std::string p, bool ours)
3399 if (p == "seamless-loop") {
3401 } else if (p == "rf-speed") {
3403 } else if (p == "auto-loop") {
3405 } else if (p == "auto-input") {
3407 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3408 /* auto-input only makes a difference if we're rolling */
3409 set_track_monitor_input_status (!config.get_auto_input());
3412 } else if (p == "punch-in") {
3416 if ((location = _locations->auto_punch_location()) != 0) {
3418 if (config.get_punch_in ()) {
3419 replace_event (SessionEvent::PunchIn, location->start());
3421 remove_event (location->start(), SessionEvent::PunchIn);
3425 } else if (p == "punch-out") {
3429 if ((location = _locations->auto_punch_location()) != 0) {
3431 if (config.get_punch_out()) {
3432 replace_event (SessionEvent::PunchOut, location->end());
3434 clear_events (SessionEvent::PunchOut);
3438 } else if (p == "edit-mode") {
3440 Glib::Mutex::Lock lm (playlists->lock);
3442 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3443 (*i)->set_edit_mode (Config->get_edit_mode ());
3446 } else if (p == "use-video-sync") {
3448 waiting_for_sync_offset = config.get_use_video_sync();
3450 } else if (p == "mmc-control") {
3452 //poke_midi_thread ();
3454 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3456 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3458 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3460 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3462 } else if (p == "midi-control") {
3464 //poke_midi_thread ();
3466 } else if (p == "raid-path") {
3468 setup_raid_path (config.get_raid_path());
3470 } else if (p == "timecode-format") {
3474 } else if (p == "video-pullup") {
3478 } else if (p == "seamless-loop") {
3480 if (play_loop && transport_rolling()) {
3481 // to reset diskstreams etc
3482 request_play_loop (true);
3485 } else if (p == "rf-speed") {
3487 cumulative_rf_motion = 0;
3490 } else if (p == "click-sound") {
3492 setup_click_sounds (1);
3494 } else if (p == "click-emphasis-sound") {
3496 setup_click_sounds (-1);
3498 } else if (p == "clicking") {
3500 if (Config->get_clicking()) {
3501 if (_click_io && click_data) { // don't require emphasis data
3508 } else if (p == "click-gain") {
3511 _click_gain->set_gain (Config->get_click_gain(), this);
3514 } else if (p == "send-mtc") {
3516 if (Config->get_send_mtc ()) {
3517 /* mark us ready to send */
3518 next_quarter_frame_to_send = 0;
3521 } else if (p == "send-mmc") {
3523 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3525 } else if (p == "midi-feedback") {
3527 session_midi_feedback = Config->get_midi_feedback();
3529 } else if (p == "jack-time-master") {
3531 engine().reset_timebase ();
3533 } else if (p == "native-file-header-format") {
3535 if (!first_file_header_format_reset) {
3536 reset_native_file_format ();
3539 first_file_header_format_reset = false;
3541 } else if (p == "native-file-data-format") {
3543 if (!first_file_data_format_reset) {
3544 reset_native_file_format ();
3547 first_file_data_format_reset = false;
3549 } else if (p == "external-sync") {
3550 if (!config.get_external_sync()) {
3551 drop_sync_source ();
3553 switch_to_sync_source (config.get_sync_source());
3555 } else if (p == "remote-model") {
3556 set_remote_control_ids ();
3557 } else if (p == "denormal-model") {
3559 } else if (p == "history-depth") {
3560 set_history_depth (Config->get_history_depth());
3561 } else if (p == "sync-all-route-ordering") {
3562 sync_order_keys ("session");
3563 } else if (p == "initial-program-change") {
3565 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3568 buf[0] = MIDI::program; // channel zero by default
3569 buf[1] = (Config->get_initial_program_change() & 0x7f);
3571 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3573 } else if (p == "solo-mute-override") {
3574 // catch_up_on_solo_mute_override ();
3575 } else if (p == "listen-position" || p == "pfl-position") {
3576 listen_position_changed ();
3577 } else if (p == "solo-control-is-listen-control") {
3578 solo_control_mode_changed ();
3579 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3580 last_timecode_valid = false;
3581 } else if (p == "playback-buffer-seconds") {
3582 AudioSource::allocate_working_buffers (frame_rate());
3583 } else if (p == "automation-thinning-factor") {
3584 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3591 Session::set_history_depth (uint32_t d)
3593 _history.set_depth (d);
3597 Session::load_diskstreams_2X (XMLNode const & node, int)
3600 XMLNodeConstIterator citer;
3602 clist = node.children();
3604 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3607 /* diskstreams added automatically by DiskstreamCreated handler */
3608 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3609 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3610 _diskstreams_2X.push_back (dsp);
3612 error << _("Session: unknown diskstream type in XML") << endmsg;
3616 catch (failed_constructor& err) {
3617 error << _("Session: could not load diskstream via XML state") << endmsg;
3625 /** Connect things to the MMC object */
3627 Session::setup_midi_machine_control ()
3629 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3631 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3632 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3633 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3634 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3635 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3636 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3637 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3638 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3639 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3640 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3641 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3642 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3643 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3645 /* also handle MIDI SPP because its so common */
3647 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3648 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3649 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3652 boost::shared_ptr<Controllable>
3653 Session::solo_cut_control() const
3655 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3656 controls in Ardour that currently get presented to the user in the GUI that require
3657 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3659 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3660 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3664 return _solo_cut_control;
3668 Session::rename (const std::string& new_name)
3670 string legal_name = legalize_for_path (new_name);
3676 string const old_sources_root = _session_dir->sources_root();
3678 #define RENAME ::rename
3683 * interchange subdirectory
3687 * Backup files are left unchanged and not renamed.
3690 /* pass one: not 100% safe check that the new directory names don't
3694 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3699 /* this is a stupid hack because Glib::path_get_dirname() is
3700 * lexical-only, and so passing it /a/b/c/ gives a different
3701 * result than passing it /a/b/c ...
3704 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3705 oldstr = oldstr.substr (0, oldstr.length() - 1);
3708 string base = Glib::path_get_dirname (oldstr);
3709 string p = Glib::path_get_basename (oldstr);
3711 newstr = Glib::build_filename (base, legal_name);
3713 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3720 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3725 /* this is a stupid hack because Glib::path_get_dirname() is
3726 * lexical-only, and so passing it /a/b/c/ gives a different
3727 * result than passing it /a/b/c ...
3730 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3731 oldstr = oldstr.substr (0, oldstr.length() - 1);
3734 string base = Glib::path_get_dirname (oldstr);
3735 string p = Glib::path_get_basename (oldstr);
3737 newstr = Glib::build_filename (base, legal_name);
3739 cerr << "Rename " << oldstr << " => " << newstr << endl;
3741 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3746 (*_session_dir) = newstr;
3751 /* directory below interchange */
3753 v.push_back (newstr);
3754 v.push_back (interchange_dir_name);
3757 oldstr = Glib::build_filename (v);
3760 v.push_back (newstr);
3761 v.push_back (interchange_dir_name);
3762 v.push_back (legal_name);
3764 newstr = Glib::build_filename (v);
3766 cerr << "Rename " << oldstr << " => " << newstr << endl;
3768 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3775 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3776 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3778 cerr << "Rename " << oldstr << " => " << newstr << endl;
3780 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3787 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3789 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3790 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3792 cerr << "Rename " << oldstr << " => " << newstr << endl;
3794 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3799 /* update file source paths */
3801 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3802 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3804 string p = fs->path ();
3805 boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3810 /* remove old name from recent sessions */
3812 remove_recent_sessions (_path);
3815 _current_snapshot_name = new_name;
3820 /* save state again to get everything just right */
3822 save_state (_current_snapshot_name);
3825 /* add to recent sessions */
3827 store_recent_sessions (new_name, _path);