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>
56 #include <glibmm/thread.h>
58 #include <boost/algorithm/string.hpp>
60 #include "midi++/mmc.h"
61 #include "midi++/port.h"
62 #include "midi++/manager.h"
64 #include "evoral/SMF.hpp"
66 #include "pbd/boost_debug.h"
67 #include "pbd/basename.h"
68 #include "pbd/controllable_descriptor.h"
69 #include "pbd/enumwriter.h"
70 #include "pbd/error.h"
71 #include "pbd/filesystem.h"
72 #include "pbd/file_utils.h"
73 #include "pbd/pathscanner.h"
74 #include "pbd/pthread_utils.h"
75 #include "pbd/search_path.h"
76 #include "pbd/stacktrace.h"
77 #include "pbd/convert.h"
78 #include "pbd/clear_dir.h"
80 #include "ardour/amp.h"
81 #include "ardour/audio_diskstream.h"
82 #include "ardour/audio_track.h"
83 #include "ardour/audioengine.h"
84 #include "ardour/audiofilesource.h"
85 #include "ardour/audioregion.h"
86 #include "ardour/automation_control.h"
87 #include "ardour/butler.h"
88 #include "ardour/control_protocol_manager.h"
89 #include "ardour/directory_names.h"
90 #include "ardour/filename_extensions.h"
91 #include "ardour/location.h"
92 #include "ardour/midi_model.h"
93 #include "ardour/midi_patch_manager.h"
94 #include "ardour/midi_region.h"
95 #include "ardour/midi_source.h"
96 #include "ardour/midi_track.h"
97 #include "ardour/named_selection.h"
98 #include "ardour/pannable.h"
99 #include "ardour/playlist_factory.h"
100 #include "ardour/port.h"
101 #include "ardour/processor.h"
102 #include "ardour/proxy_controllable.h"
103 #include "ardour/recent_sessions.h"
104 #include "ardour/region_factory.h"
105 #include "ardour/route_group.h"
106 #include "ardour/send.h"
107 #include "ardour/session.h"
108 #include "ardour/session_directory.h"
109 #include "ardour/session_metadata.h"
110 #include "ardour/session_playlists.h"
111 #include "ardour/session_state_utils.h"
112 #include "ardour/session_utils.h"
113 #include "ardour/silentfilesource.h"
114 #include "ardour/sndfilesource.h"
115 #include "ardour/source_factory.h"
116 #include "ardour/speakers.h"
117 #include "ardour/template_utils.h"
118 #include "ardour/tempo.h"
119 #include "ardour/ticker.h"
120 #include "ardour/user_bundle.h"
122 #include "control_protocol/control_protocol.h"
128 using namespace ARDOUR;
131 /** @param snapshot_name Snapshot name, without the .ardour prefix */
133 Session::first_stage_init (string fullpath, string snapshot_name)
135 if (fullpath.length() == 0) {
137 throw failed_constructor();
140 char buf[PATH_MAX+1];
141 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
142 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
144 throw failed_constructor();
149 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
150 _path += G_DIR_SEPARATOR;
153 /* these two are just provisional settings. set_state()
154 will likely override them.
157 _name = _current_snapshot_name = snapshot_name;
159 set_history_depth (Config->get_history_depth());
161 _current_frame_rate = _engine.frame_rate ();
162 _nominal_frame_rate = _current_frame_rate;
163 _base_frame_rate = _current_frame_rate;
165 _tempo_map = new TempoMap (_current_frame_rate);
166 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
169 _non_soloed_outs_muted = false;
171 _solo_isolated_cnt = 0;
172 g_atomic_int_set (&processing_prohibited, 0);
173 _transport_speed = 0;
174 _default_transport_speed = 1.0;
175 _last_transport_speed = 0;
176 _target_transport_speed = 0;
177 auto_play_legal = false;
178 transport_sub_state = 0;
179 _transport_frame = 0;
180 _requested_return_frame = -1;
181 _session_range_location = 0;
182 g_atomic_int_set (&_record_status, Disabled);
183 loop_changing = false;
186 _last_roll_location = 0;
187 _last_roll_or_reversal_location = 0;
188 _last_record_location = 0;
189 pending_locate_frame = 0;
190 pending_locate_roll = false;
191 pending_locate_flush = false;
192 state_was_pending = false;
194 outbound_mtc_timecode_frame = 0;
195 next_quarter_frame_to_send = -1;
196 current_block_size = 0;
197 solo_update_disabled = false;
198 _have_captured = false;
199 _worst_output_latency = 0;
200 _worst_input_latency = 0;
201 _worst_track_latency = 0;
202 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
203 _was_seamless = Config->get_seamless_loop ();
205 _send_qf_mtc = false;
206 _pframes_since_last_mtc = 0;
207 g_atomic_int_set (&_playback_load, 100);
208 g_atomic_int_set (&_capture_load, 100);
211 pending_abort = false;
212 destructive_index = 0;
213 first_file_data_format_reset = true;
214 first_file_header_format_reset = true;
215 post_export_sync = false;
218 no_questions_about_missing_files = false;
219 _speakers.reset (new Speakers);
221 ignore_route_processor_changes = false;
222 _pre_export_mmc_enabled = false;
224 AudioDiskstream::allocate_working_buffers();
226 /* default short fade = 15ms */
228 SndFileSource::setup_standard_crossfades (*this, frame_rate());
230 last_mmc_step.tv_sec = 0;
231 last_mmc_step.tv_usec = 0;
234 /* click sounds are unset by default, which causes us to internal
235 waveforms for clicks.
239 click_emphasis_length = 0;
242 process_function = &Session::process_with_events;
244 if (config.get_use_video_sync()) {
245 waiting_for_sync_offset = true;
247 waiting_for_sync_offset = false;
250 last_timecode_when = 0;
251 last_timecode_valid = false;
255 last_rr_session_dir = session_dirs.begin();
256 refresh_disk_space ();
258 /* default: assume simple stereo speaker configuration */
260 _speakers->setup_default_speakers (2);
264 average_slave_delta = 1800; // !!! why 1800 ????
265 have_first_delta_accumulator = false;
266 delta_accumulator_cnt = 0;
267 _slave_state = Stopped;
269 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
270 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
271 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
272 add_controllable (_solo_cut_control);
274 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
276 /* These are all static "per-class" signals */
278 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
279 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
280 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
281 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
282 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
284 /* stop IO objects from doing stuff until we're ready for them */
286 Delivery::disable_panners ();
287 IO::disable_connecting ();
291 Session::second_stage_init ()
293 AudioFileSource::set_peak_dir (_session_dir->peak_path());
296 if (load_state (_current_snapshot_name)) {
301 if (_butler->start_thread()) {
305 if (start_midi_thread ()) {
309 setup_midi_machine_control ();
311 // set_state() will call setup_raid_path(), but if it's a new session we need
312 // to call setup_raid_path() here.
315 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
319 setup_raid_path(_path);
322 /* we can't save till after ::when_engine_running() is called,
323 because otherwise we save state with no connections made.
324 therefore, we reset _state_of_the_state because ::set_state()
325 will have cleared it.
327 we also have to include Loading so that any events that get
328 generated between here and the end of ::when_engine_running()
329 will be processed directly rather than queued.
332 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
334 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
335 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
336 setup_click_sounds (0);
337 setup_midi_control ();
339 /* Pay attention ... */
341 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
342 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
344 midi_clock = new MidiClockTicker ();
345 midi_clock->set_session (this);
348 when_engine_running ();
351 /* handle this one in a different way than all others, so that its clear what happened */
353 catch (AudioEngine::PortRegistrationFailure& err) {
354 error << err.what() << endmsg;
362 BootMessage (_("Reset Remote Controls"));
364 send_full_time_code (0);
365 _engine.transport_locate (0);
367 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
368 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
370 MIDI::Name::MidiPatchManager::instance().set_session (this);
372 /* initial program change will be delivered later; see ::config_changed() */
374 _state_of_the_state = Clean;
376 Port::set_connecting_blocked (false);
378 DirtyChanged (); /* EMIT SIGNAL */
380 if (state_was_pending) {
381 save_state (_current_snapshot_name);
382 remove_pending_capture_state ();
383 state_was_pending = false;
386 BootMessage (_("Session loading complete"));
392 Session::raid_path () const
394 SearchPath raid_search_path;
396 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
397 raid_search_path += (*i).path;
400 return raid_search_path.to_string ();
404 Session::setup_raid_path (string path)
413 session_dirs.clear ();
415 SearchPath search_path(path);
416 SearchPath sound_search_path;
417 SearchPath midi_search_path;
419 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
421 sp.blocks = 0; // not needed
422 session_dirs.push_back (sp);
424 SessionDirectory sdir(sp.path);
426 sound_search_path += sdir.sound_path ();
427 midi_search_path += sdir.midi_path ();
430 // reset the round-robin soundfile path thingie
431 last_rr_session_dir = session_dirs.begin();
435 Session::path_is_within_session (const std::string& path)
437 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
438 if (PBD::sys::path_is_within (i->path, path)) {
446 Session::ensure_subdirs ()
450 dir = session_directory().peak_path();
452 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
453 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
457 dir = session_directory().sound_path();
459 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
460 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
464 dir = session_directory().midi_path();
466 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
467 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
471 dir = session_directory().dead_path();
473 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
474 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
478 dir = session_directory().export_path();
480 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
481 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
485 dir = analysis_dir ();
487 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
488 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
492 dir = plugins_dir ();
494 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
495 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
499 dir = externals_dir ();
501 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
502 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
509 /** @param session_template directory containing session template, or empty.
510 * Caller must not hold process lock.
513 Session::create (const string& session_template, BusProfile* bus_profile)
515 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
516 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
520 if (ensure_subdirs ()) {
524 _writable = exists_and_writable (sys::path (_path));
526 if (!session_template.empty()) {
527 std::string in_path = session_template_dir_to_file (session_template);
529 ifstream in(in_path.c_str());
532 string out_path = _path;
534 out_path += statefile_suffix;
536 ofstream out(out_path.c_str());
542 /* Copy plugin state files from template to new session */
543 std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
544 copy_files (template_plugins, plugins_dir ());
549 error << string_compose (_("Could not open %1 for writing session template"), out_path)
555 error << string_compose (_("Could not open session template %1 for reading"), in_path)
562 /* set initial start + end point */
564 _state_of_the_state = Clean;
566 /* set up Master Out and Control Out if necessary */
571 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
573 if (bus_profile->master_out_channels) {
574 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
578 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
579 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
582 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
583 r->input()->ensure_io (count, false, this);
584 r->output()->ensure_io (count, false, this);
590 /* prohibit auto-connect to master, because there isn't one */
591 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
595 add_routes (rl, false, false, false);
598 /* this allows the user to override settings with an environment variable.
601 if (no_auto_connect()) {
602 bus_profile->input_ac = AutoConnectOption (0);
603 bus_profile->output_ac = AutoConnectOption (0);
606 Config->set_input_auto_connect (bus_profile->input_ac);
607 Config->set_output_auto_connect (bus_profile->output_ac);
610 if (Config->get_use_monitor_bus() && bus_profile) {
611 add_monitor_section ();
620 Session::maybe_write_autosave()
622 if (dirty() && record_status() != Recording) {
623 save_state("", true);
628 Session::remove_pending_capture_state ()
630 sys::path pending_state_file_path(_session_dir->root_path());
632 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
636 sys::remove (pending_state_file_path);
638 catch(sys::filesystem_error& ex)
640 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
641 pending_state_file_path.to_string(), ex.what()) << endmsg;
645 /** Rename a state file.
646 * @param old_name Old snapshot name.
647 * @param new_name New snapshot name.
650 Session::rename_state (string old_name, string new_name)
652 if (old_name == _current_snapshot_name || old_name == _name) {
653 /* refuse to rename the current snapshot or the "main" one */
657 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
658 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
660 const sys::path old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
661 const sys::path new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
665 sys::rename (old_xml_path, new_xml_path);
667 catch (const sys::filesystem_error& err)
669 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
670 old_name, new_name, err.what()) << endmsg;
674 /** Remove a state file.
675 * @param snapshot_name Snapshot name.
678 Session::remove_state (string snapshot_name)
680 if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
681 // refuse to remove the current snapshot or the "main" one
685 std::string xml_path(_session_dir->root_path());
687 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
689 if (!create_backup_file (xml_path)) {
690 // don't remove it if a backup can't be made
691 // create_backup_file will log the error.
696 sys::remove (xml_path);
699 #ifdef HAVE_JACK_SESSION
701 Session::jack_session_event (jack_session_event_t * event)
705 struct tm local_time;
708 localtime_r (&n, &local_time);
709 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
711 if (event->type == JackSessionSaveTemplate)
713 if (save_template( timebuf )) {
714 event->flags = JackSessionSaveError;
716 string cmd ("ardour3 -P -U ");
717 cmd += event->client_uuid;
721 event->command_line = strdup (cmd.c_str());
726 if (save_state (timebuf)) {
727 event->flags = JackSessionSaveError;
729 sys::path xml_path (_session_dir->root_path());
730 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
732 string cmd ("ardour3 -P -U ");
733 cmd += event->client_uuid;
735 cmd += xml_path.to_string();
738 event->command_line = strdup (cmd.c_str());
742 jack_session_reply (_engine.jack(), event);
744 if (event->type == JackSessionSaveAndQuit) {
745 Quit (); /* EMIT SIGNAL */
748 jack_session_event_free( event );
752 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
754 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
757 std::string xml_path(_session_dir->root_path());
759 if (!_writable || (_state_of_the_state & CannotSave)) {
763 if (!_engine.connected ()) {
764 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
770 /* tell sources we're saving first, in case they write out to a new file
771 * which should be saved with the state rather than the old one */
772 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
774 i->second->session_saved();
775 } catch (Evoral::SMF::FileError& e) {
776 error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
780 tree.set_root (&get_state());
782 if (snapshot_name.empty()) {
783 snapshot_name = _current_snapshot_name;
784 } else if (switch_to_snapshot) {
785 _current_snapshot_name = snapshot_name;
790 /* proper save: use statefile_suffix (.ardour in English) */
792 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
794 /* make a backup copy of the old file */
796 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
797 // create_backup_file will log the error
803 /* pending save: use pending_suffix (.pending in English) */
804 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
807 sys::path tmp_path(_session_dir->root_path());
809 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
811 // cerr << "actually writing state to " << xml_path.to_string() << endl;
813 if (!tree.write (tmp_path.to_string())) {
814 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
815 sys::remove (tmp_path);
820 if (::rename (tmp_path.to_string().c_str(), xml_path.c_str()) != 0) {
821 error << string_compose (_("could not rename temporary session file %1 to %2"),
822 tmp_path.to_string(), xml_path) << endmsg;
823 sys::remove (tmp_path);
830 save_history (snapshot_name);
832 bool was_dirty = dirty();
834 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
837 DirtyChanged (); /* EMIT SIGNAL */
840 StateSaved (snapshot_name); /* EMIT SIGNAL */
847 Session::restore_state (string snapshot_name)
849 if (load_state (snapshot_name) == 0) {
850 set_state (*state_tree->root(), Stateful::loading_state_version);
857 Session::load_state (string snapshot_name)
862 state_was_pending = false;
864 /* check for leftover pending state from a crashed capture attempt */
866 sys::path xmlpath(_session_dir->root_path());
867 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
869 if (sys::exists (xmlpath)) {
871 /* there is pending state from a crashed capture attempt */
873 boost::optional<int> r = AskAboutPendingState();
874 if (r.get_value_or (1)) {
875 state_was_pending = true;
879 if (!state_was_pending) {
880 xmlpath = _session_dir->root_path();
881 xmlpath /= snapshot_name;
884 if (!sys::exists (xmlpath)) {
885 xmlpath = _session_dir->root_path();
886 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
887 if (!sys::exists (xmlpath)) {
888 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
893 state_tree = new XMLTree;
897 _writable = exists_and_writable (xmlpath);
899 if (!state_tree->read (xmlpath.to_string())) {
900 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
906 XMLNode& root (*state_tree->root());
908 if (root.name() != X_("Session")) {
909 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
915 const XMLProperty* prop;
917 if ((prop = root.property ("version")) == 0) {
918 /* no version implies very old version of Ardour */
919 Stateful::loading_state_version = 1000;
921 if (prop->value().find ('.') != string::npos) {
922 /* old school version format */
923 if (prop->value()[0] == '2') {
924 Stateful::loading_state_version = 2000;
926 Stateful::loading_state_version = 3000;
929 Stateful::loading_state_version = atoi (prop->value());
933 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
935 sys::path backup_path(_session_dir->root_path());
937 backup_path /= string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
939 // only create a backup for a given statefile version once
941 if (!sys::exists (backup_path)) {
943 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
944 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
947 if (!copy_file (xmlpath.to_string(), backup_path.to_string())) {;
957 Session::load_options (const XMLNode& node)
959 LocaleGuard lg (X_("POSIX"));
960 config.set_variables (node);
971 Session::get_template()
973 /* if we don't disable rec-enable, diskstreams
974 will believe they need to store their capture
975 sources in their state node.
978 disable_record (false);
984 Session::state (bool full_state)
986 XMLNode* node = new XMLNode("Session");
990 snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
991 node->add_property("version", buf);
993 /* store configuration settings */
997 node->add_property ("name", _name);
998 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
999 node->add_property ("sample-rate", buf);
1001 if (session_dirs.size() > 1) {
1005 vector<space_and_path>::iterator i = session_dirs.begin();
1006 vector<space_and_path>::iterator next;
1008 ++i; /* skip the first one */
1012 while (i != session_dirs.end()) {
1016 if (next != session_dirs.end()) {
1026 child = node->add_child ("Path");
1027 child->add_content (p);
1031 /* save the ID counter */
1033 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1034 node->add_property ("id-counter", buf);
1036 /* save the event ID counter */
1038 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1039 node->add_property ("event-counter", buf);
1041 /* various options */
1043 node->add_child_nocopy (config.get_variables ());
1045 node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
1047 child = node->add_child ("Sources");
1050 Glib::Mutex::Lock sl (source_lock);
1052 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1054 /* Don't save information about non-file Sources, or
1055 * about non-destructive file sources that are empty
1056 * and unused by any regions.
1059 boost::shared_ptr<FileSource> fs;
1061 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1063 if (!fs->destructive()) {
1064 if (fs->empty() && !fs->used()) {
1069 child->add_child_nocopy (siter->second->get_state());
1074 child = node->add_child ("Regions");
1077 Glib::Mutex::Lock rl (region_lock);
1078 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1079 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1080 boost::shared_ptr<Region> r = i->second;
1081 /* only store regions not attached to playlists */
1082 if (r->playlist() == 0) {
1083 child->add_child_nocopy (r->state ());
1087 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1089 if (!cassocs.empty()) {
1090 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1092 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1094 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1095 i->first->id().print (buf, sizeof (buf));
1096 can->add_property (X_("copy"), buf);
1097 i->second->id().print (buf, sizeof (buf));
1098 can->add_property (X_("original"), buf);
1099 ca->add_child_nocopy (*can);
1105 node->add_child_nocopy (_locations->get_state());
1107 // for a template, just create a new Locations, populate it
1108 // with the default start and end, and get the state for that.
1109 Locations loc (*this);
1110 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1111 range->set (max_framepos, 0);
1113 node->add_child_nocopy (loc.get_state());
1116 child = node->add_child ("Bundles");
1118 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1119 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1120 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1122 child->add_child_nocopy (b->get_state());
1127 child = node->add_child ("Routes");
1129 boost::shared_ptr<RouteList> r = routes.reader ();
1131 RoutePublicOrderSorter cmp;
1132 RouteList public_order (*r);
1133 public_order.sort (cmp);
1135 /* the sort should have put control outs first */
1138 assert (_monitor_out == public_order.front());
1141 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1142 if (!(*i)->is_hidden()) {
1144 child->add_child_nocopy ((*i)->get_state());
1146 child->add_child_nocopy ((*i)->get_template());
1152 playlists->add_state (node, full_state);
1154 child = node->add_child ("RouteGroups");
1155 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1156 child->add_child_nocopy ((*i)->get_state());
1160 XMLNode* gain_child = node->add_child ("Click");
1161 gain_child->add_child_nocopy (_click_io->state (full_state));
1162 gain_child->add_child_nocopy (_click_gain->state (full_state));
1166 XMLNode* ns_child = node->add_child ("NamedSelections");
1167 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1169 ns_child->add_child_nocopy ((*i)->get_state());
1174 node->add_child_nocopy (_speakers->get_state());
1175 node->add_child_nocopy (_tempo_map->get_state());
1176 node->add_child_nocopy (get_control_protocol_state());
1179 node->add_child_copy (*_extra_xml);
1186 Session::get_control_protocol_state ()
1188 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1189 return cpm.get_state();
1193 Session::set_state (const XMLNode& node, int version)
1197 const XMLProperty* prop;
1200 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1202 if (node.name() != X_("Session")) {
1203 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1207 if ((prop = node.property ("name")) != 0) {
1208 _name = prop->value ();
1211 if ((prop = node.property (X_("sample-rate"))) != 0) {
1213 _nominal_frame_rate = atoi (prop->value());
1215 if (_nominal_frame_rate != _current_frame_rate) {
1216 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1217 if (r.get_value_or (0)) {
1223 setup_raid_path(_session_dir->root_path());
1225 if ((prop = node.property (X_("id-counter"))) != 0) {
1227 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1228 ID::init_counter (x);
1230 /* old sessions used a timebased counter, so fake
1231 the startup ID counter based on a standard
1236 ID::init_counter (now);
1239 if ((prop = node.property (X_("event-counter"))) != 0) {
1240 Evoral::init_event_id_counter (atoi (prop->value()));
1243 IO::disable_connecting ();
1245 Stateful::save_extra_xml (node);
1247 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1248 load_options (*child);
1249 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1250 load_options (*child);
1252 error << _("Session: XML state has no options section") << endmsg;
1255 if (version >= 3000) {
1256 if ((child = find_named_node (node, "Metadata")) == 0) {
1257 warning << _("Session: XML state has no metadata section") << endmsg;
1258 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1263 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1264 _speakers->set_state (*child, version);
1267 if ((child = find_named_node (node, "Sources")) == 0) {
1268 error << _("Session: XML state has no sources section") << endmsg;
1270 } else if (load_sources (*child)) {
1274 if ((child = find_named_node (node, "TempoMap")) == 0) {
1275 error << _("Session: XML state has no Tempo Map section") << endmsg;
1277 } else if (_tempo_map->set_state (*child, version)) {
1281 if ((child = find_named_node (node, "Locations")) == 0) {
1282 error << _("Session: XML state has no locations section") << endmsg;
1284 } else if (_locations->set_state (*child, version)) {
1290 if ((location = _locations->auto_loop_location()) != 0) {
1291 set_auto_loop_location (location);
1294 if ((location = _locations->auto_punch_location()) != 0) {
1295 set_auto_punch_location (location);
1298 if ((location = _locations->session_range_location()) != 0) {
1299 delete _session_range_location;
1300 _session_range_location = location;
1303 if (_session_range_location) {
1304 AudioFileSource::set_header_position_offset (_session_range_location->start());
1307 if ((child = find_named_node (node, "Regions")) == 0) {
1308 error << _("Session: XML state has no Regions section") << endmsg;
1310 } else if (load_regions (*child)) {
1314 if ((child = find_named_node (node, "Playlists")) == 0) {
1315 error << _("Session: XML state has no playlists section") << endmsg;
1317 } else if (playlists->load (*this, *child)) {
1321 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1323 } else if (playlists->load_unused (*this, *child)) {
1327 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1328 if (load_compounds (*child)) {
1333 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1334 if (load_named_selections (*child)) {
1339 if (version >= 3000) {
1340 if ((child = find_named_node (node, "Bundles")) == 0) {
1341 warning << _("Session: XML state has no bundles section") << endmsg;
1344 /* We can't load Bundles yet as they need to be able
1345 to convert from port names to Port objects, which can't happen until
1347 _bundle_xml_node = new XMLNode (*child);
1351 if (version < 3000) {
1352 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1353 error << _("Session: XML state has no diskstreams section") << endmsg;
1355 } else if (load_diskstreams_2X (*child, version)) {
1360 if ((child = find_named_node (node, "Routes")) == 0) {
1361 error << _("Session: XML state has no routes section") << endmsg;
1363 } else if (load_routes (*child, version)) {
1367 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1368 _diskstreams_2X.clear ();
1370 if (version >= 3000) {
1372 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1373 error << _("Session: XML state has no route groups section") << endmsg;
1375 } else if (load_route_groups (*child, version)) {
1379 } else if (version < 3000) {
1381 if ((child = find_named_node (node, "EditGroups")) == 0) {
1382 error << _("Session: XML state has no edit groups section") << endmsg;
1384 } else if (load_route_groups (*child, version)) {
1388 if ((child = find_named_node (node, "MixGroups")) == 0) {
1389 error << _("Session: XML state has no mix groups section") << endmsg;
1391 } else if (load_route_groups (*child, version)) {
1396 if ((child = find_named_node (node, "Click")) == 0) {
1397 warning << _("Session: XML state has no click section") << endmsg;
1398 } else if (_click_io) {
1399 const XMLNodeList& children (child->children());
1400 XMLNodeList::const_iterator i = children.begin();
1401 _click_io->set_state (**i, version);
1403 if (i != children.end()) {
1404 _click_gain->set_state (**i, version);
1408 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1409 ControlProtocolManager::instance().set_protocol_states (*child);
1412 update_have_rec_enabled_track ();
1414 /* here beginneth the second phase ... */
1416 StateReady (); /* EMIT SIGNAL */
1425 Session::load_routes (const XMLNode& node, int version)
1428 XMLNodeConstIterator niter;
1429 RouteList new_routes;
1431 nlist = node.children();
1435 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1437 boost::shared_ptr<Route> route;
1438 if (version < 3000) {
1439 route = XMLRouteFactory_2X (**niter, version);
1441 route = XMLRouteFactory (**niter, version);
1445 error << _("Session: cannot create Route from XML description.") << endmsg;
1449 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1451 new_routes.push_back (route);
1454 add_routes (new_routes, false, false, false);
1459 boost::shared_ptr<Route>
1460 Session::XMLRouteFactory (const XMLNode& node, int version)
1462 boost::shared_ptr<Route> ret;
1464 if (node.name() != "Route") {
1468 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1470 DataType type = DataType::AUDIO;
1471 const XMLProperty* prop = node.property("default-type");
1474 type = DataType (prop->value());
1477 assert (type != DataType::NIL);
1481 boost::shared_ptr<Track> track;
1483 if (type == DataType::AUDIO) {
1484 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1486 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1489 if (track->init()) {
1493 if (track->set_state (node, version)) {
1497 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1498 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1503 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1505 if (r->init () == 0 && r->set_state (node, version) == 0) {
1506 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1507 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1516 boost::shared_ptr<Route>
1517 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1519 boost::shared_ptr<Route> ret;
1521 if (node.name() != "Route") {
1525 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1527 ds_prop = node.property (X_("diskstream"));
1530 DataType type = DataType::AUDIO;
1531 const XMLProperty* prop = node.property("default-type");
1534 type = DataType (prop->value());
1537 assert (type != DataType::NIL);
1541 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1542 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1546 if (i == _diskstreams_2X.end()) {
1547 error << _("Could not find diskstream for route") << endmsg;
1548 return boost::shared_ptr<Route> ();
1551 boost::shared_ptr<Track> track;
1553 if (type == DataType::AUDIO) {
1554 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1556 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1559 if (track->init()) {
1563 if (track->set_state (node, version)) {
1567 track->set_diskstream (*i);
1569 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1570 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1575 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1577 if (r->init () == 0 && r->set_state (node, version) == 0) {
1578 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1579 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1589 Session::load_regions (const XMLNode& node)
1592 XMLNodeConstIterator niter;
1593 boost::shared_ptr<Region> region;
1595 nlist = node.children();
1599 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1600 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1601 error << _("Session: cannot create Region from XML description.");
1602 const XMLProperty *name = (**niter).property("name");
1605 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1616 Session::load_compounds (const XMLNode& node)
1618 XMLNodeList calist = node.children();
1619 XMLNodeConstIterator caiter;
1620 XMLProperty *caprop;
1622 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1623 XMLNode* ca = *caiter;
1627 if ((caprop = ca->property (X_("original"))) == 0) {
1630 orig_id = caprop->value();
1632 if ((caprop = ca->property (X_("copy"))) == 0) {
1635 copy_id = caprop->value();
1637 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1638 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1640 if (!orig || !copy) {
1641 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1647 RegionFactory::add_compound_association (orig, copy);
1654 Session::load_nested_sources (const XMLNode& node)
1657 XMLNodeConstIterator niter;
1659 nlist = node.children();
1661 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1662 if ((*niter)->name() == "Source") {
1664 /* it may already exist, so don't recreate it unnecessarily
1667 XMLProperty* prop = (*niter)->property (X_("id"));
1669 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1673 ID source_id (prop->value());
1675 if (!source_by_id (source_id)) {
1678 SourceFactory::create (*this, **niter, true);
1680 catch (failed_constructor& err) {
1681 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1688 boost::shared_ptr<Region>
1689 Session::XMLRegionFactory (const XMLNode& node, bool full)
1691 const XMLProperty* type = node.property("type");
1695 const XMLNodeList& nlist = node.children();
1697 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1698 XMLNode *child = (*niter);
1699 if (child->name() == "NestedSource") {
1700 load_nested_sources (*child);
1704 if (!type || type->value() == "audio") {
1705 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1706 } else if (type->value() == "midi") {
1707 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1710 } catch (failed_constructor& err) {
1711 return boost::shared_ptr<Region> ();
1714 return boost::shared_ptr<Region> ();
1717 boost::shared_ptr<AudioRegion>
1718 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1720 const XMLProperty* prop;
1721 boost::shared_ptr<Source> source;
1722 boost::shared_ptr<AudioSource> as;
1724 SourceList master_sources;
1725 uint32_t nchans = 1;
1728 if (node.name() != X_("Region")) {
1729 return boost::shared_ptr<AudioRegion>();
1732 if ((prop = node.property (X_("channels"))) != 0) {
1733 nchans = atoi (prop->value().c_str());
1736 if ((prop = node.property ("name")) == 0) {
1737 cerr << "no name for this region\n";
1741 if ((prop = node.property (X_("source-0"))) == 0) {
1742 if ((prop = node.property ("source")) == 0) {
1743 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1744 return boost::shared_ptr<AudioRegion>();
1748 PBD::ID s_id (prop->value());
1750 if ((source = source_by_id (s_id)) == 0) {
1751 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1752 return boost::shared_ptr<AudioRegion>();
1755 as = boost::dynamic_pointer_cast<AudioSource>(source);
1757 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1758 return boost::shared_ptr<AudioRegion>();
1761 sources.push_back (as);
1763 /* pickup other channels */
1765 for (uint32_t n=1; n < nchans; ++n) {
1766 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1767 if ((prop = node.property (buf)) != 0) {
1769 PBD::ID id2 (prop->value());
1771 if ((source = source_by_id (id2)) == 0) {
1772 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1773 return boost::shared_ptr<AudioRegion>();
1776 as = boost::dynamic_pointer_cast<AudioSource>(source);
1778 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1779 return boost::shared_ptr<AudioRegion>();
1781 sources.push_back (as);
1785 for (uint32_t n = 0; n < nchans; ++n) {
1786 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1787 if ((prop = node.property (buf)) != 0) {
1789 PBD::ID id2 (prop->value());
1791 if ((source = source_by_id (id2)) == 0) {
1792 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1793 return boost::shared_ptr<AudioRegion>();
1796 as = boost::dynamic_pointer_cast<AudioSource>(source);
1798 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1799 return boost::shared_ptr<AudioRegion>();
1801 master_sources.push_back (as);
1806 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1808 /* a final detail: this is the one and only place that we know how long missing files are */
1810 if (region->whole_file()) {
1811 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1812 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1814 sfp->set_length (region->length());
1819 if (!master_sources.empty()) {
1820 if (master_sources.size() != nchans) {
1821 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1823 region->set_master_sources (master_sources);
1831 catch (failed_constructor& err) {
1832 return boost::shared_ptr<AudioRegion>();
1836 boost::shared_ptr<MidiRegion>
1837 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1839 const XMLProperty* prop;
1840 boost::shared_ptr<Source> source;
1841 boost::shared_ptr<MidiSource> ms;
1844 if (node.name() != X_("Region")) {
1845 return boost::shared_ptr<MidiRegion>();
1848 if ((prop = node.property ("name")) == 0) {
1849 cerr << "no name for this region\n";
1853 if ((prop = node.property (X_("source-0"))) == 0) {
1854 if ((prop = node.property ("source")) == 0) {
1855 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1856 return boost::shared_ptr<MidiRegion>();
1860 PBD::ID s_id (prop->value());
1862 if ((source = source_by_id (s_id)) == 0) {
1863 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1864 return boost::shared_ptr<MidiRegion>();
1867 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1869 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1870 return boost::shared_ptr<MidiRegion>();
1873 sources.push_back (ms);
1876 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1877 /* a final detail: this is the one and only place that we know how long missing files are */
1879 if (region->whole_file()) {
1880 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1881 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1883 sfp->set_length (region->length());
1891 catch (failed_constructor& err) {
1892 return boost::shared_ptr<MidiRegion>();
1897 Session::get_sources_as_xml ()
1900 XMLNode* node = new XMLNode (X_("Sources"));
1901 Glib::Mutex::Lock lm (source_lock);
1903 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1904 node->add_child_nocopy (i->second->get_state());
1911 Session::path_from_region_name (DataType type, string name, string identifier)
1913 char buf[PATH_MAX+1];
1915 SessionDirectory sdir(get_best_session_directory_for_new_source());
1916 sys::path source_dir = ((type == DataType::AUDIO)
1917 ? sdir.sound_path() : sdir.midi_path());
1919 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1921 for (n = 0; n < 999999; ++n) {
1922 if (identifier.length()) {
1923 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1924 identifier.c_str(), n, ext.c_str());
1926 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1930 sys::path source_path = source_dir / buf;
1932 if (!sys::exists (source_path)) {
1933 return source_path.to_string();
1937 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1946 Session::load_sources (const XMLNode& node)
1949 XMLNodeConstIterator niter;
1950 boost::shared_ptr<Source> source;
1952 nlist = node.children();
1956 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1959 if ((source = XMLSourceFactory (**niter)) == 0) {
1960 error << _("Session: cannot create Source from XML description.") << endmsg;
1963 } catch (MissingSource& err) {
1967 if (!no_questions_about_missing_files) {
1968 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1973 switch (user_choice) {
1975 /* user added a new search location, so try again */
1980 /* user asked to quit the entire session load
1985 no_questions_about_missing_files = true;
1989 no_questions_about_missing_files = true;
1994 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1995 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2004 boost::shared_ptr<Source>
2005 Session::XMLSourceFactory (const XMLNode& node)
2007 if (node.name() != "Source") {
2008 return boost::shared_ptr<Source>();
2012 /* note: do peak building in another thread when loading session state */
2013 return SourceFactory::create (*this, node, true);
2016 catch (failed_constructor& err) {
2017 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2018 return boost::shared_ptr<Source>();
2023 Session::save_template (string template_name)
2027 if (_state_of_the_state & CannotSave) {
2031 sys::path user_template_dir(user_template_directory());
2035 sys::create_directories (user_template_dir);
2037 catch(sys::filesystem_error& ex)
2039 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2040 user_template_dir.to_string(), ex.what()) << endmsg;
2044 tree.set_root (&get_template());
2046 sys::path template_dir_path(user_template_dir);
2048 /* directory to put the template in */
2049 template_dir_path /= template_name;
2050 if (sys::exists (template_dir_path))
2052 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2053 template_dir_path.to_string()) << endmsg;
2057 sys::create_directories (template_dir_path);
2060 sys::path template_file_path = template_dir_path;
2061 template_file_path /= template_name + template_suffix;
2063 if (!tree.write (template_file_path.to_string())) {
2064 error << _("template not saved") << endmsg;
2068 /* copy plugin state directory */
2070 sys::path template_plugin_state_path = template_dir_path;
2071 template_plugin_state_path /= X_("plugins");
2072 sys::create_directories (template_plugin_state_path);
2073 copy_files (plugins_dir(), template_plugin_state_path.to_string());
2079 Session::refresh_disk_space ()
2081 #if HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H
2083 Glib::Mutex::Lock lm (space_lock);
2085 /* get freespace on every FS that is part of the session path */
2087 _total_free_4k_blocks = 0;
2088 _total_free_4k_blocks_uncertain = false;
2090 for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2092 struct statfs statfsbuf;
2093 statfs (i->path.c_str(), &statfsbuf);
2095 double const scale = statfsbuf.f_bsize / 4096.0;
2097 /* See if this filesystem is read-only */
2098 struct statvfs statvfsbuf;
2099 statvfs (i->path.c_str(), &statvfsbuf);
2101 /* f_bavail can be 0 if it is undefined for whatever
2102 filesystem we are looking at; Samba shares mounted
2103 via GVFS are an example of this.
2105 if (statfsbuf.f_bavail == 0) {
2106 /* block count unknown */
2108 i->blocks_unknown = true;
2109 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2110 /* read-only filesystem */
2112 i->blocks_unknown = false;
2114 /* read/write filesystem with known space */
2115 i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2116 i->blocks_unknown = false;
2119 _total_free_4k_blocks += i->blocks;
2120 if (i->blocks_unknown) {
2121 _total_free_4k_blocks_uncertain = true;
2128 Session::get_best_session_directory_for_new_source ()
2130 vector<space_and_path>::iterator i;
2131 string result = _session_dir->root_path();
2133 /* handle common case without system calls */
2135 if (session_dirs.size() == 1) {
2139 /* OK, here's the algorithm we're following here:
2141 We want to select which directory to use for
2142 the next file source to be created. Ideally,
2143 we'd like to use a round-robin process so as to
2144 get maximum performance benefits from splitting
2145 the files across multiple disks.
2147 However, in situations without much diskspace, an
2148 RR approach may end up filling up a filesystem
2149 with new files while others still have space.
2150 Its therefore important to pay some attention to
2151 the freespace in the filesystem holding each
2152 directory as well. However, if we did that by
2153 itself, we'd keep creating new files in the file
2154 system with the most space until it was as full
2155 as all others, thus negating any performance
2156 benefits of this RAID-1 like approach.
2158 So, we use a user-configurable space threshold. If
2159 there are at least 2 filesystems with more than this
2160 much space available, we use RR selection between them.
2161 If not, then we pick the filesystem with the most space.
2163 This gets a good balance between the two
2167 refresh_disk_space ();
2169 int free_enough = 0;
2171 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2172 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2177 if (free_enough >= 2) {
2178 /* use RR selection process, ensuring that the one
2182 i = last_rr_session_dir;
2185 if (++i == session_dirs.end()) {
2186 i = session_dirs.begin();
2189 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2190 if (create_session_directory ((*i).path)) {
2192 last_rr_session_dir = i;
2197 } while (i != last_rr_session_dir);
2201 /* pick FS with the most freespace (and that
2202 seems to actually work ...)
2205 vector<space_and_path> sorted;
2206 space_and_path_ascending_cmp cmp;
2208 sorted = session_dirs;
2209 sort (sorted.begin(), sorted.end(), cmp);
2211 for (i = sorted.begin(); i != sorted.end(); ++i) {
2212 if (create_session_directory ((*i).path)) {
2214 last_rr_session_dir = i;
2224 Session::load_named_selections (const XMLNode& node)
2227 XMLNodeConstIterator niter;
2230 nlist = node.children();
2234 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2236 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2237 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2245 Session::XMLNamedSelectionFactory (const XMLNode& node)
2248 return new NamedSelection (*this, node);
2251 catch (failed_constructor& err) {
2257 Session::automation_dir () const
2259 return Glib::build_filename (_path, "automation");
2263 Session::analysis_dir () const
2265 return Glib::build_filename (_path, "analysis");
2269 Session::plugins_dir () const
2271 return Glib::build_filename (_path, "plugins");
2275 Session::externals_dir () const
2277 return Glib::build_filename (_path, "externals");
2281 Session::load_bundles (XMLNode const & node)
2283 XMLNodeList nlist = node.children();
2284 XMLNodeConstIterator niter;
2288 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2289 if ((*niter)->name() == "InputBundle") {
2290 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2291 } else if ((*niter)->name() == "OutputBundle") {
2292 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2294 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2303 Session::load_route_groups (const XMLNode& node, int version)
2305 XMLNodeList nlist = node.children();
2306 XMLNodeConstIterator niter;
2310 if (version >= 3000) {
2312 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2313 if ((*niter)->name() == "RouteGroup") {
2314 RouteGroup* rg = new RouteGroup (*this, "");
2315 add_route_group (rg);
2316 rg->set_state (**niter, version);
2320 } else if (version < 3000) {
2322 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2323 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2324 RouteGroup* rg = new RouteGroup (*this, "");
2325 add_route_group (rg);
2326 rg->set_state (**niter, version);
2335 Session::auto_save()
2337 save_state (_current_snapshot_name);
2341 state_file_filter (const string &str, void */*arg*/)
2343 return (str.length() > strlen(statefile_suffix) &&
2344 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2348 bool operator()(const string* a, const string* b) {
2354 remove_end(string* state)
2356 string statename(*state);
2358 string::size_type start,end;
2359 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2360 statename = statename.substr (start+1);
2363 if ((end = statename.rfind(".ardour")) == string::npos) {
2364 end = statename.length();
2367 return new string(statename.substr (0, end));
2371 Session::possible_states (string path)
2373 PathScanner scanner;
2374 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2376 transform(states->begin(), states->end(), states->begin(), remove_end);
2379 sort (states->begin(), states->end(), cmp);
2385 Session::possible_states () const
2387 return possible_states(_path);
2391 Session::add_route_group (RouteGroup* g)
2393 _route_groups.push_back (g);
2394 route_group_added (g); /* EMIT SIGNAL */
2396 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2397 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2398 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2404 Session::remove_route_group (RouteGroup& rg)
2406 list<RouteGroup*>::iterator i;
2408 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2409 _route_groups.erase (i);
2412 route_group_removed (); /* EMIT SIGNAL */
2416 /** Set a new order for our route groups, without adding or removing any.
2417 * @param groups Route group list in the new order.
2420 Session::reorder_route_groups (list<RouteGroup*> groups)
2422 _route_groups = groups;
2424 route_groups_reordered (); /* EMIT SIGNAL */
2430 Session::route_group_by_name (string name)
2432 list<RouteGroup *>::iterator i;
2434 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2435 if ((*i)->name() == name) {
2443 Session::all_route_group() const
2445 return *_all_route_group;
2449 Session::add_commands (vector<Command*> const & cmds)
2451 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2457 Session::begin_reversible_command (const string& name)
2459 begin_reversible_command (g_quark_from_string (name.c_str ()));
2462 /** Begin a reversible command using a GQuark to identify it.
2463 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2464 * but there must be as many begin...()s as there are commit...()s.
2467 Session::begin_reversible_command (GQuark q)
2469 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2470 to hold all the commands that are committed. This keeps the order of
2471 commands correct in the history.
2474 if (_current_trans == 0) {
2475 /* start a new transaction */
2476 assert (_current_trans_quarks.empty ());
2477 _current_trans = new UndoTransaction();
2478 _current_trans->set_name (g_quark_to_string (q));
2481 _current_trans_quarks.push_front (q);
2485 Session::commit_reversible_command (Command *cmd)
2487 assert (_current_trans);
2488 assert (!_current_trans_quarks.empty ());
2493 _current_trans->add_command (cmd);
2496 _current_trans_quarks.pop_front ();
2498 if (!_current_trans_quarks.empty ()) {
2499 /* the transaction we're committing is not the top-level one */
2503 if (_current_trans->empty()) {
2504 /* no commands were added to the transaction, so just get rid of it */
2505 delete _current_trans;
2510 gettimeofday (&now, 0);
2511 _current_trans->set_timestamp (now);
2513 _history.add (_current_trans);
2518 accept_all_audio_files (const string& path, void */*arg*/)
2520 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2524 if (!AudioFileSource::safe_audio_file_extension (path)) {
2532 accept_all_midi_files (const string& path, void */*arg*/)
2534 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2538 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2539 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2540 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2544 accept_all_state_files (const string& path, void */*arg*/)
2546 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2550 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2554 Session::find_all_sources (string path, set<string>& result)
2559 if (!tree.read (path)) {
2563 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2568 XMLNodeConstIterator niter;
2570 nlist = node->children();
2574 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2578 if ((prop = (*niter)->property (X_("type"))) == 0) {
2582 DataType type (prop->value());
2584 if ((prop = (*niter)->property (X_("name"))) == 0) {
2588 if (Glib::path_is_absolute (prop->value())) {
2589 /* external file, ignore */
2597 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2598 result.insert (found_path);
2606 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2608 PathScanner scanner;
2609 vector<string*>* state_files;
2611 string this_snapshot_path;
2617 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2618 ripped = ripped.substr (0, ripped.length() - 1);
2621 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2623 if (state_files == 0) {
2628 this_snapshot_path = _path;
2629 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2630 this_snapshot_path += statefile_suffix;
2632 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2634 if (exclude_this_snapshot && **i == this_snapshot_path) {
2638 if (find_all_sources (**i, result) < 0) {
2646 struct RegionCounter {
2647 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2648 AudioSourceList::iterator iter;
2649 boost::shared_ptr<Region> region;
2652 RegionCounter() : count (0) {}
2656 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2658 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2659 return r.get_value_or (1);
2663 Session::cleanup_regions ()
2665 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2667 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2669 uint32_t used = playlists->region_use_count (i->second);
2671 if (used == 0 && !i->second->automatic ()) {
2672 RegionFactory::map_remove (i->second);
2676 /* dump the history list */
2683 Session::cleanup_sources (CleanupReport& rep)
2685 // FIXME: needs adaptation to midi
2687 vector<boost::shared_ptr<Source> > dead_sources;
2688 PathScanner scanner;
2691 vector<space_and_path>::iterator i;
2692 vector<space_and_path>::iterator nexti;
2693 vector<string*>* candidates;
2694 vector<string*>* candidates2;
2695 vector<string> unused;
2696 set<string> all_sources;
2701 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2703 /* consider deleting all unused playlists */
2705 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2710 /* sync the "all regions" property of each playlist with its current state
2713 playlists->sync_all_regions_with_regions ();
2715 /* find all un-used sources */
2720 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2722 SourceMap::iterator tmp;
2727 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2731 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2732 dead_sources.push_back (i->second);
2733 i->second->drop_references ();
2739 /* build a list of all the possible audio directories for the session */
2741 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2746 SessionDirectory sdir ((*i).path);
2747 audio_path += sdir.sound_path();
2749 if (nexti != session_dirs.end()) {
2757 /* build a list of all the possible midi directories for the session */
2759 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2764 SessionDirectory sdir ((*i).path);
2765 midi_path += sdir.midi_path();
2767 if (nexti != session_dirs.end()) {
2774 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2775 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2781 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2782 candidates->push_back (*i);
2787 candidates = candidates2; // might still be null
2790 /* find all sources, but don't use this snapshot because the
2791 state file on disk still references sources we may have already
2795 find_all_sources_across_snapshots (all_sources, true);
2797 /* add our current source list
2800 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2801 boost::shared_ptr<FileSource> fs;
2802 SourceMap::iterator tmp = i;
2805 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2806 if (playlists->source_use_count (fs) != 0) {
2807 all_sources.insert (fs->path());
2810 /* we might not remove this source from disk, because it may be used
2811 by other snapshots, but its not being used in this version
2812 so lets get rid of it now, along with any representative regions
2816 RegionFactory::remove_regions_using_source (i->second);
2824 char tmppath1[PATH_MAX+1];
2825 char tmppath2[PATH_MAX+1];
2828 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2833 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2835 if (realpath(spath.c_str(), tmppath1) == 0) {
2836 error << string_compose (_("Cannot expand path %1 (%2)"),
2837 spath, strerror (errno)) << endmsg;
2841 if (realpath((*i).c_str(), tmppath2) == 0) {
2842 error << string_compose (_("Cannot expand path %1 (%2)"),
2843 (*i), strerror (errno)) << endmsg;
2847 if (strcmp(tmppath1, tmppath2) == 0) {
2854 unused.push_back (spath);
2863 /* now try to move all unused files into the "dead" directory(ies) */
2865 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2866 struct stat statbuf;
2870 /* don't move the file across filesystems, just
2871 stick it in the `dead_dir_name' directory
2872 on whichever filesystem it was already on.
2875 if ((*x).find ("/sounds/") != string::npos) {
2877 /* old school, go up 1 level */
2879 newpath = Glib::path_get_dirname (*x); // "sounds"
2880 newpath = Glib::path_get_dirname (newpath); // "session-name"
2884 /* new school, go up 4 levels */
2886 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2887 newpath = Glib::path_get_dirname (newpath); // "session-name"
2888 newpath = Glib::path_get_dirname (newpath); // "interchange"
2889 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2892 newpath = Glib::build_filename (newpath, dead_dir_name);
2894 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2895 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2899 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2901 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2903 /* the new path already exists, try versioning */
2905 char buf[PATH_MAX+1];
2909 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2912 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2913 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2917 if (version == 999) {
2918 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2922 newpath = newpath_v;
2927 /* it doesn't exist, or we can't read it or something */
2931 stat ((*x).c_str(), &statbuf);
2933 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2934 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2935 (*x), newpath, strerror (errno))
2940 /* see if there an easy to find peakfile for this file, and remove it.
2943 string base = basename_nosuffix (*x);
2944 base += "%A"; /* this is what we add for the channel suffix of all native files,
2945 or for the first channel of embedded files. it will miss
2946 some peakfiles for other channels
2948 string peakpath = peak_path (base);
2950 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2951 if (::unlink (peakpath.c_str()) != 0) {
2952 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2953 peakpath, _path, strerror (errno))
2955 /* try to back out */
2956 ::rename (newpath.c_str(), _path.c_str());
2961 rep.paths.push_back (*x);
2962 rep.space += statbuf.st_size;
2965 /* dump the history list */
2969 /* save state so we don't end up a session file
2970 referring to non-existent sources.
2977 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2983 Session::cleanup_trash_sources (CleanupReport& rep)
2985 // FIXME: needs adaptation for MIDI
2987 vector<space_and_path>::iterator i;
2993 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2995 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2997 clear_directory (dead_dir, &rep.space, &rep.paths);
3004 Session::set_dirty ()
3006 bool was_dirty = dirty();
3008 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3012 DirtyChanged(); /* EMIT SIGNAL */
3018 Session::set_clean ()
3020 bool was_dirty = dirty();
3022 _state_of_the_state = Clean;
3026 DirtyChanged(); /* EMIT SIGNAL */
3031 Session::set_deletion_in_progress ()
3033 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3037 Session::clear_deletion_in_progress ()
3039 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3043 Session::add_controllable (boost::shared_ptr<Controllable> c)
3045 /* this adds a controllable to the list managed by the Session.
3046 this is a subset of those managed by the Controllable class
3047 itself, and represents the only ones whose state will be saved
3048 as part of the session.
3051 Glib::Mutex::Lock lm (controllables_lock);
3052 controllables.insert (c);
3055 struct null_deleter { void operator()(void const *) const {} };
3058 Session::remove_controllable (Controllable* c)
3060 if (_state_of_the_state & Deletion) {
3064 Glib::Mutex::Lock lm (controllables_lock);
3066 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3068 if (x != controllables.end()) {
3069 controllables.erase (x);
3073 boost::shared_ptr<Controllable>
3074 Session::controllable_by_id (const PBD::ID& id)
3076 Glib::Mutex::Lock lm (controllables_lock);
3078 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3079 if ((*i)->id() == id) {
3084 return boost::shared_ptr<Controllable>();
3087 boost::shared_ptr<Controllable>
3088 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3090 boost::shared_ptr<Controllable> c;
3091 boost::shared_ptr<Route> r;
3093 switch (desc.top_level_type()) {
3094 case ControllableDescriptor::NamedRoute:
3096 std::string str = desc.top_level_name();
3097 if (str == "master") {
3099 } else if (str == "control" || str == "listen") {
3102 r = route_by_name (desc.top_level_name());
3107 case ControllableDescriptor::RemoteControlID:
3108 r = route_by_remote_id (desc.rid());
3116 switch (desc.subtype()) {
3117 case ControllableDescriptor::Gain:
3118 c = r->gain_control ();
3121 case ControllableDescriptor::Solo:
3122 c = r->solo_control();
3125 case ControllableDescriptor::Mute:
3126 c = r->mute_control();
3129 case ControllableDescriptor::Recenable:
3131 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3134 c = t->rec_enable_control ();
3139 case ControllableDescriptor::PanDirection:
3141 c = r->pannable()->pan_azimuth_control;
3145 case ControllableDescriptor::PanWidth:
3147 c = r->pannable()->pan_width_control;
3151 case ControllableDescriptor::PanElevation:
3153 c = r->pannable()->pan_elevation_control;
3157 case ControllableDescriptor::Balance:
3158 /* XXX simple pan control */
3161 case ControllableDescriptor::PluginParameter:
3163 uint32_t plugin = desc.target (0);
3164 uint32_t parameter_index = desc.target (1);
3166 /* revert to zero based counting */
3172 if (parameter_index > 0) {
3176 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3179 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3180 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3185 case ControllableDescriptor::SendGain:
3187 uint32_t send = desc.target (0);
3189 /* revert to zero-based counting */
3195 boost::shared_ptr<Processor> p = r->nth_send (send);
3198 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3199 boost::shared_ptr<Amp> a = s->amp();
3202 c = s->amp()->gain_control();
3209 /* relax and return a null pointer */
3217 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3220 Stateful::add_instant_xml (node, _path);
3223 if (write_to_config) {
3224 Config->add_instant_xml (node);
3229 Session::instant_xml (const string& node_name)
3231 return Stateful::instant_xml (node_name, _path);
3235 Session::save_history (string snapshot_name)
3243 if (snapshot_name.empty()) {
3244 snapshot_name = _current_snapshot_name;
3247 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3248 const string backup_filename = history_filename + backup_suffix;
3249 const sys::path xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3250 const sys::path backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3252 if (sys::exists (xml_path)) {
3255 sys::rename (xml_path, backup_path);
3257 catch (const sys::filesystem_error& err)
3259 error << _("could not backup old history file, current history not saved") << endmsg;
3264 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3268 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3270 if (!tree.write (xml_path.to_string()))
3272 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3276 sys::remove (xml_path);
3277 sys::rename (backup_path, xml_path);
3279 catch (const sys::filesystem_error& err)
3281 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3282 backup_path.to_string(), err.what()) << endmsg;
3292 Session::restore_history (string snapshot_name)
3296 if (snapshot_name.empty()) {
3297 snapshot_name = _current_snapshot_name;
3300 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3301 const sys::path xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3303 info << "Loading history from " << xml_path.to_string() << endmsg;
3305 if (!sys::exists (xml_path)) {
3306 info << string_compose (_("%1: no history file \"%2\" for this session."),
3307 _name, xml_path.to_string()) << endmsg;
3311 if (!tree.read (xml_path.to_string())) {
3312 error << string_compose (_("Could not understand session history file \"%1\""),
3313 xml_path.to_string()) << endmsg;
3320 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3323 UndoTransaction* ut = new UndoTransaction ();
3326 ut->set_name(t->property("name")->value());
3327 stringstream ss(t->property("tv-sec")->value());
3329 ss.str(t->property("tv-usec")->value());
3331 ut->set_timestamp(tv);
3333 for (XMLNodeConstIterator child_it = t->children().begin();
3334 child_it != t->children().end(); child_it++)
3336 XMLNode *n = *child_it;
3339 if (n->name() == "MementoCommand" ||
3340 n->name() == "MementoUndoCommand" ||
3341 n->name() == "MementoRedoCommand") {
3343 if ((c = memento_command_factory(n))) {
3347 } else if (n->name() == "NoteDiffCommand") {
3348 PBD::ID id (n->property("midi-source")->value());
3349 boost::shared_ptr<MidiSource> midi_source =
3350 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3352 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3354 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3357 } else if (n->name() == "SysExDiffCommand") {
3359 PBD::ID id (n->property("midi-source")->value());
3360 boost::shared_ptr<MidiSource> midi_source =
3361 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3363 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3365 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3368 } else if (n->name() == "PatchChangeDiffCommand") {
3370 PBD::ID id (n->property("midi-source")->value());
3371 boost::shared_ptr<MidiSource> midi_source =
3372 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3374 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3376 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3379 } else if (n->name() == "StatefulDiffCommand") {
3380 if ((c = stateful_diff_command_factory (n))) {
3381 ut->add_command (c);
3384 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3395 Session::config_changed (std::string p, bool ours)
3401 if (p == "seamless-loop") {
3403 } else if (p == "rf-speed") {
3405 } else if (p == "auto-loop") {
3407 } else if (p == "auto-input") {
3409 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3410 /* auto-input only makes a difference if we're rolling */
3411 set_track_monitor_input_status (!config.get_auto_input());
3414 } else if (p == "punch-in") {
3418 if ((location = _locations->auto_punch_location()) != 0) {
3420 if (config.get_punch_in ()) {
3421 replace_event (SessionEvent::PunchIn, location->start());
3423 remove_event (location->start(), SessionEvent::PunchIn);
3427 } else if (p == "punch-out") {
3431 if ((location = _locations->auto_punch_location()) != 0) {
3433 if (config.get_punch_out()) {
3434 replace_event (SessionEvent::PunchOut, location->end());
3436 clear_events (SessionEvent::PunchOut);
3440 } else if (p == "edit-mode") {
3442 Glib::Mutex::Lock lm (playlists->lock);
3444 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3445 (*i)->set_edit_mode (Config->get_edit_mode ());
3448 } else if (p == "use-video-sync") {
3450 waiting_for_sync_offset = config.get_use_video_sync();
3452 } else if (p == "mmc-control") {
3454 //poke_midi_thread ();
3456 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3458 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3460 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3462 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3464 } else if (p == "midi-control") {
3466 //poke_midi_thread ();
3468 } else if (p == "raid-path") {
3470 setup_raid_path (config.get_raid_path());
3472 } else if (p == "timecode-format") {
3476 } else if (p == "video-pullup") {
3480 } else if (p == "seamless-loop") {
3482 if (play_loop && transport_rolling()) {
3483 // to reset diskstreams etc
3484 request_play_loop (true);
3487 } else if (p == "rf-speed") {
3489 cumulative_rf_motion = 0;
3492 } else if (p == "click-sound") {
3494 setup_click_sounds (1);
3496 } else if (p == "click-emphasis-sound") {
3498 setup_click_sounds (-1);
3500 } else if (p == "clicking") {
3502 if (Config->get_clicking()) {
3503 if (_click_io && click_data) { // don't require emphasis data
3510 } else if (p == "click-gain") {
3513 _click_gain->set_gain (Config->get_click_gain(), this);
3516 } else if (p == "send-mtc") {
3518 if (Config->get_send_mtc ()) {
3519 /* mark us ready to send */
3520 next_quarter_frame_to_send = 0;
3523 } else if (p == "send-mmc") {
3525 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3527 } else if (p == "midi-feedback") {
3529 session_midi_feedback = Config->get_midi_feedback();
3531 } else if (p == "jack-time-master") {
3533 engine().reset_timebase ();
3535 } else if (p == "native-file-header-format") {
3537 if (!first_file_header_format_reset) {
3538 reset_native_file_format ();
3541 first_file_header_format_reset = false;
3543 } else if (p == "native-file-data-format") {
3545 if (!first_file_data_format_reset) {
3546 reset_native_file_format ();
3549 first_file_data_format_reset = false;
3551 } else if (p == "external-sync") {
3552 if (!config.get_external_sync()) {
3553 drop_sync_source ();
3555 switch_to_sync_source (config.get_sync_source());
3557 } else if (p == "remote-model") {
3558 set_remote_control_ids ();
3559 } else if (p == "denormal-model") {
3561 } else if (p == "history-depth") {
3562 set_history_depth (Config->get_history_depth());
3563 } else if (p == "sync-all-route-ordering") {
3564 sync_order_keys ("session");
3565 } else if (p == "initial-program-change") {
3567 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3570 buf[0] = MIDI::program; // channel zero by default
3571 buf[1] = (Config->get_initial_program_change() & 0x7f);
3573 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3575 } else if (p == "solo-mute-override") {
3576 // catch_up_on_solo_mute_override ();
3577 } else if (p == "listen-position" || p == "pfl-position") {
3578 listen_position_changed ();
3579 } else if (p == "solo-control-is-listen-control") {
3580 solo_control_mode_changed ();
3581 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3582 last_timecode_valid = false;
3583 } else if (p == "playback-buffer-seconds") {
3584 AudioSource::allocate_working_buffers (frame_rate());
3585 } else if (p == "automation-thinning-factor") {
3586 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3593 Session::set_history_depth (uint32_t d)
3595 _history.set_depth (d);
3599 Session::load_diskstreams_2X (XMLNode const & node, int)
3602 XMLNodeConstIterator citer;
3604 clist = node.children();
3606 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3609 /* diskstreams added automatically by DiskstreamCreated handler */
3610 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3611 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3612 _diskstreams_2X.push_back (dsp);
3614 error << _("Session: unknown diskstream type in XML") << endmsg;
3618 catch (failed_constructor& err) {
3619 error << _("Session: could not load diskstream via XML state") << endmsg;
3627 /** Connect things to the MMC object */
3629 Session::setup_midi_machine_control ()
3631 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3633 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3634 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3635 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3636 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3637 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3638 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3639 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3640 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3641 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3642 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3643 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3644 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3645 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3647 /* also handle MIDI SPP because its so common */
3649 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3650 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3651 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3654 boost::shared_ptr<Controllable>
3655 Session::solo_cut_control() const
3657 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3658 controls in Ardour that currently get presented to the user in the GUI that require
3659 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3661 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3662 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3666 return _solo_cut_control;
3670 Session::rename (const std::string& new_name)
3672 string legal_name = legalize_for_path (new_name);
3678 string const old_sources_root = _session_dir->sources_root();
3680 #define RENAME ::rename
3685 * interchange subdirectory
3689 * Backup files are left unchanged and not renamed.
3692 /* pass one: not 100% safe check that the new directory names don't
3696 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3701 /* this is a stupid hack because Glib::path_get_dirname() is
3702 * lexical-only, and so passing it /a/b/c/ gives a different
3703 * result than passing it /a/b/c ...
3706 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3707 oldstr = oldstr.substr (0, oldstr.length() - 1);
3710 string base = Glib::path_get_dirname (oldstr);
3711 string p = Glib::path_get_basename (oldstr);
3713 newstr = Glib::build_filename (base, legal_name);
3715 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3722 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3727 /* this is a stupid hack because Glib::path_get_dirname() is
3728 * lexical-only, and so passing it /a/b/c/ gives a different
3729 * result than passing it /a/b/c ...
3732 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3733 oldstr = oldstr.substr (0, oldstr.length() - 1);
3736 string base = Glib::path_get_dirname (oldstr);
3737 string p = Glib::path_get_basename (oldstr);
3739 newstr = Glib::build_filename (base, legal_name);
3741 cerr << "Rename " << oldstr << " => " << newstr << endl;
3743 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3748 (*_session_dir) = newstr;
3753 /* directory below interchange */
3755 v.push_back (newstr);
3756 v.push_back (interchange_dir_name);
3759 oldstr = Glib::build_filename (v);
3762 v.push_back (newstr);
3763 v.push_back (interchange_dir_name);
3764 v.push_back (legal_name);
3766 newstr = Glib::build_filename (v);
3768 cerr << "Rename " << oldstr << " => " << newstr << endl;
3770 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3777 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3778 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3780 cerr << "Rename " << oldstr << " => " << newstr << endl;
3782 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3789 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3791 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3792 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3794 cerr << "Rename " << oldstr << " => " << newstr << endl;
3796 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3801 /* update file source paths */
3803 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3804 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3806 string p = fs->path ();
3807 boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3812 /* remove old name from recent sessions */
3814 remove_recent_sessions (_path);
3817 _current_snapshot_name = new_name;
3822 /* save state again to get everything just right */
3824 save_state (_current_snapshot_name);
3827 /* add to recent sessions */
3829 store_recent_sessions (new_name, _path);