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 std::string old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
659 const std::string new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
661 if (::g_rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
662 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
663 old_name, new_name, g_strerror(errno)) << endmsg;
667 /** Remove a state file.
668 * @param snapshot_name Snapshot name.
671 Session::remove_state (string snapshot_name)
673 if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
674 // refuse to remove the current snapshot or the "main" one
678 std::string xml_path(_session_dir->root_path());
680 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
682 if (!create_backup_file (xml_path)) {
683 // don't remove it if a backup can't be made
684 // create_backup_file will log the error.
689 if (g_remove (xml_path.c_str()) != 0) {
690 error << string_compose(_("Could not remove state file at path \"%1\" (%2)"),
691 xml_path, g_strerror (errno)) << endmsg;
695 #ifdef HAVE_JACK_SESSION
697 Session::jack_session_event (jack_session_event_t * event)
701 struct tm local_time;
704 localtime_r (&n, &local_time);
705 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
707 if (event->type == JackSessionSaveTemplate)
709 if (save_template( timebuf )) {
710 event->flags = JackSessionSaveError;
712 string cmd ("ardour3 -P -U ");
713 cmd += event->client_uuid;
717 event->command_line = strdup (cmd.c_str());
722 if (save_state (timebuf)) {
723 event->flags = JackSessionSaveError;
725 sys::path xml_path (_session_dir->root_path());
726 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
728 string cmd ("ardour3 -P -U ");
729 cmd += event->client_uuid;
731 cmd += xml_path.to_string();
734 event->command_line = strdup (cmd.c_str());
738 jack_session_reply (_engine.jack(), event);
740 if (event->type == JackSessionSaveAndQuit) {
741 Quit (); /* EMIT SIGNAL */
744 jack_session_event_free( event );
748 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
750 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
753 std::string xml_path(_session_dir->root_path());
755 if (!_writable || (_state_of_the_state & CannotSave)) {
759 if (!_engine.connected ()) {
760 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
766 /* tell sources we're saving first, in case they write out to a new file
767 * which should be saved with the state rather than the old one */
768 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
770 i->second->session_saved();
771 } catch (Evoral::SMF::FileError& e) {
772 error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
776 tree.set_root (&get_state());
778 if (snapshot_name.empty()) {
779 snapshot_name = _current_snapshot_name;
780 } else if (switch_to_snapshot) {
781 _current_snapshot_name = snapshot_name;
786 /* proper save: use statefile_suffix (.ardour in English) */
788 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
790 /* make a backup copy of the old file */
792 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) {
793 // create_backup_file will log the error
799 /* pending save: use pending_suffix (.pending in English) */
800 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
803 sys::path tmp_path(_session_dir->root_path());
805 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
807 // cerr << "actually writing state to " << xml_path.to_string() << endl;
809 if (!tree.write (tmp_path.to_string())) {
810 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
811 if (g_remove (tmp_path.to_string().c_str()) != 0) {
812 error << string_compose(_("Could not remove temporary state file at path \"%1\" (%2)"),
813 tmp_path.to_string(), g_strerror (errno)) << endmsg;
819 if (::rename (tmp_path.to_string().c_str(), xml_path.c_str()) != 0) {
820 error << string_compose (_("could not rename temporary session file %1 to %2"),
821 tmp_path.to_string(), xml_path) << endmsg;
822 if (g_remove (tmp_path.to_string().c_str()) != 0) {
823 error << string_compose(_("Could not remove temporary state file at path \"%1\" (%2)"),
824 tmp_path.to_string(), g_strerror (errno)) << endmsg;
832 save_history (snapshot_name);
834 bool was_dirty = dirty();
836 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
839 DirtyChanged (); /* EMIT SIGNAL */
842 StateSaved (snapshot_name); /* EMIT SIGNAL */
849 Session::restore_state (string snapshot_name)
851 if (load_state (snapshot_name) == 0) {
852 set_state (*state_tree->root(), Stateful::loading_state_version);
859 Session::load_state (string snapshot_name)
864 state_was_pending = false;
866 /* check for leftover pending state from a crashed capture attempt */
868 sys::path xmlpath(_session_dir->root_path());
869 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
871 if (Glib::file_test (xmlpath.to_string(), Glib::FILE_TEST_EXISTS)) {
873 /* there is pending state from a crashed capture attempt */
875 boost::optional<int> r = AskAboutPendingState();
876 if (r.get_value_or (1)) {
877 state_was_pending = true;
881 if (!state_was_pending) {
882 xmlpath = _session_dir->root_path();
883 xmlpath /= snapshot_name;
886 if (!Glib::file_test (xmlpath.to_string(), Glib::FILE_TEST_EXISTS)) {
887 xmlpath = _session_dir->root_path();
888 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
889 if (!Glib::file_test (xmlpath.to_string(), Glib::FILE_TEST_EXISTS)) {
890 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
895 state_tree = new XMLTree;
899 _writable = exists_and_writable (xmlpath.to_string());
901 if (!state_tree->read (xmlpath.to_string())) {
902 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
908 XMLNode& root (*state_tree->root());
910 if (root.name() != X_("Session")) {
911 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
917 const XMLProperty* prop;
919 if ((prop = root.property ("version")) == 0) {
920 /* no version implies very old version of Ardour */
921 Stateful::loading_state_version = 1000;
923 if (prop->value().find ('.') != string::npos) {
924 /* old school version format */
925 if (prop->value()[0] == '2') {
926 Stateful::loading_state_version = 2000;
928 Stateful::loading_state_version = 3000;
931 Stateful::loading_state_version = atoi (prop->value());
935 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
937 sys::path backup_path(_session_dir->root_path());
939 backup_path /= string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
941 // only create a backup for a given statefile version once
943 if (!Glib::file_test (backup_path.to_string(), Glib::FILE_TEST_EXISTS)) {
945 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
946 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
949 if (!copy_file (xmlpath.to_string(), backup_path.to_string())) {;
959 Session::load_options (const XMLNode& node)
961 LocaleGuard lg (X_("POSIX"));
962 config.set_variables (node);
973 Session::get_template()
975 /* if we don't disable rec-enable, diskstreams
976 will believe they need to store their capture
977 sources in their state node.
980 disable_record (false);
986 Session::state (bool full_state)
988 XMLNode* node = new XMLNode("Session");
992 snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
993 node->add_property("version", buf);
995 /* store configuration settings */
999 node->add_property ("name", _name);
1000 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1001 node->add_property ("sample-rate", buf);
1003 if (session_dirs.size() > 1) {
1007 vector<space_and_path>::iterator i = session_dirs.begin();
1008 vector<space_and_path>::iterator next;
1010 ++i; /* skip the first one */
1014 while (i != session_dirs.end()) {
1018 if (next != session_dirs.end()) {
1028 child = node->add_child ("Path");
1029 child->add_content (p);
1033 /* save the ID counter */
1035 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1036 node->add_property ("id-counter", buf);
1038 /* save the event ID counter */
1040 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1041 node->add_property ("event-counter", buf);
1043 /* various options */
1045 node->add_child_nocopy (config.get_variables ());
1047 node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
1049 child = node->add_child ("Sources");
1052 Glib::Mutex::Lock sl (source_lock);
1054 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1056 /* Don't save information about non-file Sources, or
1057 * about non-destructive file sources that are empty
1058 * and unused by any regions.
1061 boost::shared_ptr<FileSource> fs;
1063 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1065 if (!fs->destructive()) {
1066 if (fs->empty() && !fs->used()) {
1071 child->add_child_nocopy (siter->second->get_state());
1076 child = node->add_child ("Regions");
1079 Glib::Mutex::Lock rl (region_lock);
1080 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1081 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1082 boost::shared_ptr<Region> r = i->second;
1083 /* only store regions not attached to playlists */
1084 if (r->playlist() == 0) {
1085 child->add_child_nocopy (r->state ());
1089 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1091 if (!cassocs.empty()) {
1092 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1094 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1096 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1097 i->first->id().print (buf, sizeof (buf));
1098 can->add_property (X_("copy"), buf);
1099 i->second->id().print (buf, sizeof (buf));
1100 can->add_property (X_("original"), buf);
1101 ca->add_child_nocopy (*can);
1107 node->add_child_nocopy (_locations->get_state());
1109 // for a template, just create a new Locations, populate it
1110 // with the default start and end, and get the state for that.
1111 Locations loc (*this);
1112 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1113 range->set (max_framepos, 0);
1115 node->add_child_nocopy (loc.get_state());
1118 child = node->add_child ("Bundles");
1120 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1121 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1122 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1124 child->add_child_nocopy (b->get_state());
1129 child = node->add_child ("Routes");
1131 boost::shared_ptr<RouteList> r = routes.reader ();
1133 RoutePublicOrderSorter cmp;
1134 RouteList public_order (*r);
1135 public_order.sort (cmp);
1137 /* the sort should have put control outs first */
1140 assert (_monitor_out == public_order.front());
1143 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1144 if (!(*i)->is_hidden()) {
1146 child->add_child_nocopy ((*i)->get_state());
1148 child->add_child_nocopy ((*i)->get_template());
1154 playlists->add_state (node, full_state);
1156 child = node->add_child ("RouteGroups");
1157 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1158 child->add_child_nocopy ((*i)->get_state());
1162 XMLNode* gain_child = node->add_child ("Click");
1163 gain_child->add_child_nocopy (_click_io->state (full_state));
1164 gain_child->add_child_nocopy (_click_gain->state (full_state));
1168 XMLNode* ns_child = node->add_child ("NamedSelections");
1169 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1171 ns_child->add_child_nocopy ((*i)->get_state());
1176 node->add_child_nocopy (_speakers->get_state());
1177 node->add_child_nocopy (_tempo_map->get_state());
1178 node->add_child_nocopy (get_control_protocol_state());
1181 node->add_child_copy (*_extra_xml);
1188 Session::get_control_protocol_state ()
1190 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1191 return cpm.get_state();
1195 Session::set_state (const XMLNode& node, int version)
1199 const XMLProperty* prop;
1202 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1204 if (node.name() != X_("Session")) {
1205 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1209 if ((prop = node.property ("name")) != 0) {
1210 _name = prop->value ();
1213 if ((prop = node.property (X_("sample-rate"))) != 0) {
1215 _nominal_frame_rate = atoi (prop->value());
1217 if (_nominal_frame_rate != _current_frame_rate) {
1218 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1219 if (r.get_value_or (0)) {
1225 setup_raid_path(_session_dir->root_path());
1227 if ((prop = node.property (X_("id-counter"))) != 0) {
1229 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1230 ID::init_counter (x);
1232 /* old sessions used a timebased counter, so fake
1233 the startup ID counter based on a standard
1238 ID::init_counter (now);
1241 if ((prop = node.property (X_("event-counter"))) != 0) {
1242 Evoral::init_event_id_counter (atoi (prop->value()));
1245 IO::disable_connecting ();
1247 Stateful::save_extra_xml (node);
1249 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1250 load_options (*child);
1251 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1252 load_options (*child);
1254 error << _("Session: XML state has no options section") << endmsg;
1257 if (version >= 3000) {
1258 if ((child = find_named_node (node, "Metadata")) == 0) {
1259 warning << _("Session: XML state has no metadata section") << endmsg;
1260 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1265 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1266 _speakers->set_state (*child, version);
1269 if ((child = find_named_node (node, "Sources")) == 0) {
1270 error << _("Session: XML state has no sources section") << endmsg;
1272 } else if (load_sources (*child)) {
1276 if ((child = find_named_node (node, "TempoMap")) == 0) {
1277 error << _("Session: XML state has no Tempo Map section") << endmsg;
1279 } else if (_tempo_map->set_state (*child, version)) {
1283 if ((child = find_named_node (node, "Locations")) == 0) {
1284 error << _("Session: XML state has no locations section") << endmsg;
1286 } else if (_locations->set_state (*child, version)) {
1292 if ((location = _locations->auto_loop_location()) != 0) {
1293 set_auto_loop_location (location);
1296 if ((location = _locations->auto_punch_location()) != 0) {
1297 set_auto_punch_location (location);
1300 if ((location = _locations->session_range_location()) != 0) {
1301 delete _session_range_location;
1302 _session_range_location = location;
1305 if (_session_range_location) {
1306 AudioFileSource::set_header_position_offset (_session_range_location->start());
1309 if ((child = find_named_node (node, "Regions")) == 0) {
1310 error << _("Session: XML state has no Regions section") << endmsg;
1312 } else if (load_regions (*child)) {
1316 if ((child = find_named_node (node, "Playlists")) == 0) {
1317 error << _("Session: XML state has no playlists section") << endmsg;
1319 } else if (playlists->load (*this, *child)) {
1323 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1325 } else if (playlists->load_unused (*this, *child)) {
1329 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1330 if (load_compounds (*child)) {
1335 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1336 if (load_named_selections (*child)) {
1341 if (version >= 3000) {
1342 if ((child = find_named_node (node, "Bundles")) == 0) {
1343 warning << _("Session: XML state has no bundles section") << endmsg;
1346 /* We can't load Bundles yet as they need to be able
1347 to convert from port names to Port objects, which can't happen until
1349 _bundle_xml_node = new XMLNode (*child);
1353 if (version < 3000) {
1354 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1355 error << _("Session: XML state has no diskstreams section") << endmsg;
1357 } else if (load_diskstreams_2X (*child, version)) {
1362 if ((child = find_named_node (node, "Routes")) == 0) {
1363 error << _("Session: XML state has no routes section") << endmsg;
1365 } else if (load_routes (*child, version)) {
1369 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1370 _diskstreams_2X.clear ();
1372 if (version >= 3000) {
1374 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1375 error << _("Session: XML state has no route groups section") << endmsg;
1377 } else if (load_route_groups (*child, version)) {
1381 } else if (version < 3000) {
1383 if ((child = find_named_node (node, "EditGroups")) == 0) {
1384 error << _("Session: XML state has no edit groups section") << endmsg;
1386 } else if (load_route_groups (*child, version)) {
1390 if ((child = find_named_node (node, "MixGroups")) == 0) {
1391 error << _("Session: XML state has no mix groups section") << endmsg;
1393 } else if (load_route_groups (*child, version)) {
1398 if ((child = find_named_node (node, "Click")) == 0) {
1399 warning << _("Session: XML state has no click section") << endmsg;
1400 } else if (_click_io) {
1401 const XMLNodeList& children (child->children());
1402 XMLNodeList::const_iterator i = children.begin();
1403 _click_io->set_state (**i, version);
1405 if (i != children.end()) {
1406 _click_gain->set_state (**i, version);
1410 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1411 ControlProtocolManager::instance().set_protocol_states (*child);
1414 update_have_rec_enabled_track ();
1416 /* here beginneth the second phase ... */
1418 StateReady (); /* EMIT SIGNAL */
1427 Session::load_routes (const XMLNode& node, int version)
1430 XMLNodeConstIterator niter;
1431 RouteList new_routes;
1433 nlist = node.children();
1437 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1439 boost::shared_ptr<Route> route;
1440 if (version < 3000) {
1441 route = XMLRouteFactory_2X (**niter, version);
1443 route = XMLRouteFactory (**niter, version);
1447 error << _("Session: cannot create Route from XML description.") << endmsg;
1451 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1453 new_routes.push_back (route);
1456 add_routes (new_routes, false, false, false);
1461 boost::shared_ptr<Route>
1462 Session::XMLRouteFactory (const XMLNode& node, int version)
1464 boost::shared_ptr<Route> ret;
1466 if (node.name() != "Route") {
1470 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1472 DataType type = DataType::AUDIO;
1473 const XMLProperty* prop = node.property("default-type");
1476 type = DataType (prop->value());
1479 assert (type != DataType::NIL);
1483 boost::shared_ptr<Track> track;
1485 if (type == DataType::AUDIO) {
1486 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1488 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1491 if (track->init()) {
1495 if (track->set_state (node, version)) {
1499 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1500 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1505 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1507 if (r->init () == 0 && r->set_state (node, version) == 0) {
1508 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1509 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1518 boost::shared_ptr<Route>
1519 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1521 boost::shared_ptr<Route> ret;
1523 if (node.name() != "Route") {
1527 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1529 ds_prop = node.property (X_("diskstream"));
1532 DataType type = DataType::AUDIO;
1533 const XMLProperty* prop = node.property("default-type");
1536 type = DataType (prop->value());
1539 assert (type != DataType::NIL);
1543 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1544 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1548 if (i == _diskstreams_2X.end()) {
1549 error << _("Could not find diskstream for route") << endmsg;
1550 return boost::shared_ptr<Route> ();
1553 boost::shared_ptr<Track> track;
1555 if (type == DataType::AUDIO) {
1556 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1558 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1561 if (track->init()) {
1565 if (track->set_state (node, version)) {
1569 track->set_diskstream (*i);
1571 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1572 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1577 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1579 if (r->init () == 0 && r->set_state (node, version) == 0) {
1580 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1581 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1591 Session::load_regions (const XMLNode& node)
1594 XMLNodeConstIterator niter;
1595 boost::shared_ptr<Region> region;
1597 nlist = node.children();
1601 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1602 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1603 error << _("Session: cannot create Region from XML description.");
1604 const XMLProperty *name = (**niter).property("name");
1607 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1618 Session::load_compounds (const XMLNode& node)
1620 XMLNodeList calist = node.children();
1621 XMLNodeConstIterator caiter;
1622 XMLProperty *caprop;
1624 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1625 XMLNode* ca = *caiter;
1629 if ((caprop = ca->property (X_("original"))) == 0) {
1632 orig_id = caprop->value();
1634 if ((caprop = ca->property (X_("copy"))) == 0) {
1637 copy_id = caprop->value();
1639 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1640 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1642 if (!orig || !copy) {
1643 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1649 RegionFactory::add_compound_association (orig, copy);
1656 Session::load_nested_sources (const XMLNode& node)
1659 XMLNodeConstIterator niter;
1661 nlist = node.children();
1663 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1664 if ((*niter)->name() == "Source") {
1666 /* it may already exist, so don't recreate it unnecessarily
1669 XMLProperty* prop = (*niter)->property (X_("id"));
1671 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1675 ID source_id (prop->value());
1677 if (!source_by_id (source_id)) {
1680 SourceFactory::create (*this, **niter, true);
1682 catch (failed_constructor& err) {
1683 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1690 boost::shared_ptr<Region>
1691 Session::XMLRegionFactory (const XMLNode& node, bool full)
1693 const XMLProperty* type = node.property("type");
1697 const XMLNodeList& nlist = node.children();
1699 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1700 XMLNode *child = (*niter);
1701 if (child->name() == "NestedSource") {
1702 load_nested_sources (*child);
1706 if (!type || type->value() == "audio") {
1707 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1708 } else if (type->value() == "midi") {
1709 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1712 } catch (failed_constructor& err) {
1713 return boost::shared_ptr<Region> ();
1716 return boost::shared_ptr<Region> ();
1719 boost::shared_ptr<AudioRegion>
1720 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1722 const XMLProperty* prop;
1723 boost::shared_ptr<Source> source;
1724 boost::shared_ptr<AudioSource> as;
1726 SourceList master_sources;
1727 uint32_t nchans = 1;
1730 if (node.name() != X_("Region")) {
1731 return boost::shared_ptr<AudioRegion>();
1734 if ((prop = node.property (X_("channels"))) != 0) {
1735 nchans = atoi (prop->value().c_str());
1738 if ((prop = node.property ("name")) == 0) {
1739 cerr << "no name for this region\n";
1743 if ((prop = node.property (X_("source-0"))) == 0) {
1744 if ((prop = node.property ("source")) == 0) {
1745 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1746 return boost::shared_ptr<AudioRegion>();
1750 PBD::ID s_id (prop->value());
1752 if ((source = source_by_id (s_id)) == 0) {
1753 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1754 return boost::shared_ptr<AudioRegion>();
1757 as = boost::dynamic_pointer_cast<AudioSource>(source);
1759 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1760 return boost::shared_ptr<AudioRegion>();
1763 sources.push_back (as);
1765 /* pickup other channels */
1767 for (uint32_t n=1; n < nchans; ++n) {
1768 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1769 if ((prop = node.property (buf)) != 0) {
1771 PBD::ID id2 (prop->value());
1773 if ((source = source_by_id (id2)) == 0) {
1774 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1775 return boost::shared_ptr<AudioRegion>();
1778 as = boost::dynamic_pointer_cast<AudioSource>(source);
1780 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1781 return boost::shared_ptr<AudioRegion>();
1783 sources.push_back (as);
1787 for (uint32_t n = 0; n < nchans; ++n) {
1788 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1789 if ((prop = node.property (buf)) != 0) {
1791 PBD::ID id2 (prop->value());
1793 if ((source = source_by_id (id2)) == 0) {
1794 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1795 return boost::shared_ptr<AudioRegion>();
1798 as = boost::dynamic_pointer_cast<AudioSource>(source);
1800 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1801 return boost::shared_ptr<AudioRegion>();
1803 master_sources.push_back (as);
1808 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1810 /* a final detail: this is the one and only place that we know how long missing files are */
1812 if (region->whole_file()) {
1813 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1814 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1816 sfp->set_length (region->length());
1821 if (!master_sources.empty()) {
1822 if (master_sources.size() != nchans) {
1823 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1825 region->set_master_sources (master_sources);
1833 catch (failed_constructor& err) {
1834 return boost::shared_ptr<AudioRegion>();
1838 boost::shared_ptr<MidiRegion>
1839 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1841 const XMLProperty* prop;
1842 boost::shared_ptr<Source> source;
1843 boost::shared_ptr<MidiSource> ms;
1846 if (node.name() != X_("Region")) {
1847 return boost::shared_ptr<MidiRegion>();
1850 if ((prop = node.property ("name")) == 0) {
1851 cerr << "no name for this region\n";
1855 if ((prop = node.property (X_("source-0"))) == 0) {
1856 if ((prop = node.property ("source")) == 0) {
1857 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1858 return boost::shared_ptr<MidiRegion>();
1862 PBD::ID s_id (prop->value());
1864 if ((source = source_by_id (s_id)) == 0) {
1865 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1866 return boost::shared_ptr<MidiRegion>();
1869 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1871 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1872 return boost::shared_ptr<MidiRegion>();
1875 sources.push_back (ms);
1878 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1879 /* a final detail: this is the one and only place that we know how long missing files are */
1881 if (region->whole_file()) {
1882 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1883 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1885 sfp->set_length (region->length());
1893 catch (failed_constructor& err) {
1894 return boost::shared_ptr<MidiRegion>();
1899 Session::get_sources_as_xml ()
1902 XMLNode* node = new XMLNode (X_("Sources"));
1903 Glib::Mutex::Lock lm (source_lock);
1905 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1906 node->add_child_nocopy (i->second->get_state());
1913 Session::path_from_region_name (DataType type, string name, string identifier)
1915 char buf[PATH_MAX+1];
1917 SessionDirectory sdir(get_best_session_directory_for_new_source());
1918 sys::path source_dir = ((type == DataType::AUDIO)
1919 ? sdir.sound_path() : sdir.midi_path());
1921 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1923 for (n = 0; n < 999999; ++n) {
1924 if (identifier.length()) {
1925 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1926 identifier.c_str(), n, ext.c_str());
1928 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1932 sys::path source_path = source_dir / buf;
1934 if (!Glib::file_test (source_path.to_string(), Glib::FILE_TEST_EXISTS)) {
1935 return source_path.to_string();
1939 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1948 Session::load_sources (const XMLNode& node)
1951 XMLNodeConstIterator niter;
1952 boost::shared_ptr<Source> source;
1954 nlist = node.children();
1958 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1961 if ((source = XMLSourceFactory (**niter)) == 0) {
1962 error << _("Session: cannot create Source from XML description.") << endmsg;
1965 } catch (MissingSource& err) {
1969 if (!no_questions_about_missing_files) {
1970 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1975 switch (user_choice) {
1977 /* user added a new search location, so try again */
1982 /* user asked to quit the entire session load
1987 no_questions_about_missing_files = true;
1991 no_questions_about_missing_files = true;
1996 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1997 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2006 boost::shared_ptr<Source>
2007 Session::XMLSourceFactory (const XMLNode& node)
2009 if (node.name() != "Source") {
2010 return boost::shared_ptr<Source>();
2014 /* note: do peak building in another thread when loading session state */
2015 return SourceFactory::create (*this, node, true);
2018 catch (failed_constructor& err) {
2019 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2020 return boost::shared_ptr<Source>();
2025 Session::save_template (string template_name)
2029 if (_state_of_the_state & CannotSave) {
2033 sys::path user_template_dir(user_template_directory());
2037 sys::create_directories (user_template_dir);
2039 catch(sys::filesystem_error& ex)
2041 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2042 user_template_dir.to_string(), ex.what()) << endmsg;
2046 tree.set_root (&get_template());
2048 sys::path template_dir_path(user_template_dir);
2050 /* directory to put the template in */
2051 template_dir_path /= template_name;
2052 if (Glib::file_test (template_dir_path.to_string(), Glib::FILE_TEST_EXISTS)) {
2053 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2054 template_dir_path.to_string()) << endmsg;
2058 sys::create_directories (template_dir_path);
2061 sys::path template_file_path = template_dir_path;
2062 template_file_path /= template_name + template_suffix;
2064 if (!tree.write (template_file_path.to_string())) {
2065 error << _("template not saved") << endmsg;
2069 /* copy plugin state directory */
2071 sys::path template_plugin_state_path = template_dir_path;
2072 template_plugin_state_path /= X_("plugins");
2073 sys::create_directories (template_plugin_state_path);
2074 copy_files (plugins_dir(), template_plugin_state_path.to_string());
2080 Session::refresh_disk_space ()
2082 #if HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H
2084 Glib::Mutex::Lock lm (space_lock);
2086 /* get freespace on every FS that is part of the session path */
2088 _total_free_4k_blocks = 0;
2089 _total_free_4k_blocks_uncertain = false;
2091 for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2093 struct statfs statfsbuf;
2094 statfs (i->path.c_str(), &statfsbuf);
2096 double const scale = statfsbuf.f_bsize / 4096.0;
2098 /* See if this filesystem is read-only */
2099 struct statvfs statvfsbuf;
2100 statvfs (i->path.c_str(), &statvfsbuf);
2102 /* f_bavail can be 0 if it is undefined for whatever
2103 filesystem we are looking at; Samba shares mounted
2104 via GVFS are an example of this.
2106 if (statfsbuf.f_bavail == 0) {
2107 /* block count unknown */
2109 i->blocks_unknown = true;
2110 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2111 /* read-only filesystem */
2113 i->blocks_unknown = false;
2115 /* read/write filesystem with known space */
2116 i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2117 i->blocks_unknown = false;
2120 _total_free_4k_blocks += i->blocks;
2121 if (i->blocks_unknown) {
2122 _total_free_4k_blocks_uncertain = true;
2129 Session::get_best_session_directory_for_new_source ()
2131 vector<space_and_path>::iterator i;
2132 string result = _session_dir->root_path();
2134 /* handle common case without system calls */
2136 if (session_dirs.size() == 1) {
2140 /* OK, here's the algorithm we're following here:
2142 We want to select which directory to use for
2143 the next file source to be created. Ideally,
2144 we'd like to use a round-robin process so as to
2145 get maximum performance benefits from splitting
2146 the files across multiple disks.
2148 However, in situations without much diskspace, an
2149 RR approach may end up filling up a filesystem
2150 with new files while others still have space.
2151 Its therefore important to pay some attention to
2152 the freespace in the filesystem holding each
2153 directory as well. However, if we did that by
2154 itself, we'd keep creating new files in the file
2155 system with the most space until it was as full
2156 as all others, thus negating any performance
2157 benefits of this RAID-1 like approach.
2159 So, we use a user-configurable space threshold. If
2160 there are at least 2 filesystems with more than this
2161 much space available, we use RR selection between them.
2162 If not, then we pick the filesystem with the most space.
2164 This gets a good balance between the two
2168 refresh_disk_space ();
2170 int free_enough = 0;
2172 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2173 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2178 if (free_enough >= 2) {
2179 /* use RR selection process, ensuring that the one
2183 i = last_rr_session_dir;
2186 if (++i == session_dirs.end()) {
2187 i = session_dirs.begin();
2190 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2191 if (create_session_directory ((*i).path)) {
2193 last_rr_session_dir = i;
2198 } while (i != last_rr_session_dir);
2202 /* pick FS with the most freespace (and that
2203 seems to actually work ...)
2206 vector<space_and_path> sorted;
2207 space_and_path_ascending_cmp cmp;
2209 sorted = session_dirs;
2210 sort (sorted.begin(), sorted.end(), cmp);
2212 for (i = sorted.begin(); i != sorted.end(); ++i) {
2213 if (create_session_directory ((*i).path)) {
2215 last_rr_session_dir = i;
2225 Session::load_named_selections (const XMLNode& node)
2228 XMLNodeConstIterator niter;
2231 nlist = node.children();
2235 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2237 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2238 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2246 Session::XMLNamedSelectionFactory (const XMLNode& node)
2249 return new NamedSelection (*this, node);
2252 catch (failed_constructor& err) {
2258 Session::automation_dir () const
2260 return Glib::build_filename (_path, "automation");
2264 Session::analysis_dir () const
2266 return Glib::build_filename (_path, "analysis");
2270 Session::plugins_dir () const
2272 return Glib::build_filename (_path, "plugins");
2276 Session::externals_dir () const
2278 return Glib::build_filename (_path, "externals");
2282 Session::load_bundles (XMLNode const & node)
2284 XMLNodeList nlist = node.children();
2285 XMLNodeConstIterator niter;
2289 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2290 if ((*niter)->name() == "InputBundle") {
2291 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2292 } else if ((*niter)->name() == "OutputBundle") {
2293 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2295 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2304 Session::load_route_groups (const XMLNode& node, int version)
2306 XMLNodeList nlist = node.children();
2307 XMLNodeConstIterator niter;
2311 if (version >= 3000) {
2313 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2314 if ((*niter)->name() == "RouteGroup") {
2315 RouteGroup* rg = new RouteGroup (*this, "");
2316 add_route_group (rg);
2317 rg->set_state (**niter, version);
2321 } else if (version < 3000) {
2323 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2324 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2325 RouteGroup* rg = new RouteGroup (*this, "");
2326 add_route_group (rg);
2327 rg->set_state (**niter, version);
2336 Session::auto_save()
2338 save_state (_current_snapshot_name);
2342 state_file_filter (const string &str, void */*arg*/)
2344 return (str.length() > strlen(statefile_suffix) &&
2345 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2349 bool operator()(const string* a, const string* b) {
2355 remove_end(string* state)
2357 string statename(*state);
2359 string::size_type start,end;
2360 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2361 statename = statename.substr (start+1);
2364 if ((end = statename.rfind(".ardour")) == string::npos) {
2365 end = statename.length();
2368 return new string(statename.substr (0, end));
2372 Session::possible_states (string path)
2374 PathScanner scanner;
2375 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2377 transform(states->begin(), states->end(), states->begin(), remove_end);
2380 sort (states->begin(), states->end(), cmp);
2386 Session::possible_states () const
2388 return possible_states(_path);
2392 Session::add_route_group (RouteGroup* g)
2394 _route_groups.push_back (g);
2395 route_group_added (g); /* EMIT SIGNAL */
2397 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2398 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2399 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2405 Session::remove_route_group (RouteGroup& rg)
2407 list<RouteGroup*>::iterator i;
2409 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2410 _route_groups.erase (i);
2413 route_group_removed (); /* EMIT SIGNAL */
2417 /** Set a new order for our route groups, without adding or removing any.
2418 * @param groups Route group list in the new order.
2421 Session::reorder_route_groups (list<RouteGroup*> groups)
2423 _route_groups = groups;
2425 route_groups_reordered (); /* EMIT SIGNAL */
2431 Session::route_group_by_name (string name)
2433 list<RouteGroup *>::iterator i;
2435 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2436 if ((*i)->name() == name) {
2444 Session::all_route_group() const
2446 return *_all_route_group;
2450 Session::add_commands (vector<Command*> const & cmds)
2452 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2458 Session::begin_reversible_command (const string& name)
2460 begin_reversible_command (g_quark_from_string (name.c_str ()));
2463 /** Begin a reversible command using a GQuark to identify it.
2464 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2465 * but there must be as many begin...()s as there are commit...()s.
2468 Session::begin_reversible_command (GQuark q)
2470 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2471 to hold all the commands that are committed. This keeps the order of
2472 commands correct in the history.
2475 if (_current_trans == 0) {
2476 /* start a new transaction */
2477 assert (_current_trans_quarks.empty ());
2478 _current_trans = new UndoTransaction();
2479 _current_trans->set_name (g_quark_to_string (q));
2482 _current_trans_quarks.push_front (q);
2486 Session::commit_reversible_command (Command *cmd)
2488 assert (_current_trans);
2489 assert (!_current_trans_quarks.empty ());
2494 _current_trans->add_command (cmd);
2497 _current_trans_quarks.pop_front ();
2499 if (!_current_trans_quarks.empty ()) {
2500 /* the transaction we're committing is not the top-level one */
2504 if (_current_trans->empty()) {
2505 /* no commands were added to the transaction, so just get rid of it */
2506 delete _current_trans;
2511 gettimeofday (&now, 0);
2512 _current_trans->set_timestamp (now);
2514 _history.add (_current_trans);
2519 accept_all_audio_files (const string& path, void */*arg*/)
2521 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2525 if (!AudioFileSource::safe_audio_file_extension (path)) {
2533 accept_all_midi_files (const string& path, void */*arg*/)
2535 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2539 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2540 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2541 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2545 accept_all_state_files (const string& path, void */*arg*/)
2547 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2551 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2555 Session::find_all_sources (string path, set<string>& result)
2560 if (!tree.read (path)) {
2564 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2569 XMLNodeConstIterator niter;
2571 nlist = node->children();
2575 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2579 if ((prop = (*niter)->property (X_("type"))) == 0) {
2583 DataType type (prop->value());
2585 if ((prop = (*niter)->property (X_("name"))) == 0) {
2589 if (Glib::path_is_absolute (prop->value())) {
2590 /* external file, ignore */
2598 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2599 result.insert (found_path);
2607 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2609 PathScanner scanner;
2610 vector<string*>* state_files;
2612 string this_snapshot_path;
2618 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2619 ripped = ripped.substr (0, ripped.length() - 1);
2622 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2624 if (state_files == 0) {
2629 this_snapshot_path = _path;
2630 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2631 this_snapshot_path += statefile_suffix;
2633 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2635 if (exclude_this_snapshot && **i == this_snapshot_path) {
2639 if (find_all_sources (**i, result) < 0) {
2647 struct RegionCounter {
2648 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2649 AudioSourceList::iterator iter;
2650 boost::shared_ptr<Region> region;
2653 RegionCounter() : count (0) {}
2657 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2659 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2660 return r.get_value_or (1);
2664 Session::cleanup_regions ()
2666 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2668 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2670 uint32_t used = playlists->region_use_count (i->second);
2672 if (used == 0 && !i->second->automatic ()) {
2673 RegionFactory::map_remove (i->second);
2677 /* dump the history list */
2684 Session::cleanup_sources (CleanupReport& rep)
2686 // FIXME: needs adaptation to midi
2688 vector<boost::shared_ptr<Source> > dead_sources;
2689 PathScanner scanner;
2692 vector<space_and_path>::iterator i;
2693 vector<space_and_path>::iterator nexti;
2694 vector<string*>* candidates;
2695 vector<string*>* candidates2;
2696 vector<string> unused;
2697 set<string> all_sources;
2702 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2704 /* consider deleting all unused playlists */
2706 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2711 /* sync the "all regions" property of each playlist with its current state
2714 playlists->sync_all_regions_with_regions ();
2716 /* find all un-used sources */
2721 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2723 SourceMap::iterator tmp;
2728 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2732 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2733 dead_sources.push_back (i->second);
2734 i->second->drop_references ();
2740 /* build a list of all the possible audio directories for the session */
2742 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2747 SessionDirectory sdir ((*i).path);
2748 audio_path += sdir.sound_path();
2750 if (nexti != session_dirs.end()) {
2758 /* build a list of all the possible midi directories for the session */
2760 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2765 SessionDirectory sdir ((*i).path);
2766 midi_path += sdir.midi_path();
2768 if (nexti != session_dirs.end()) {
2775 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2776 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2782 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2783 candidates->push_back (*i);
2788 candidates = candidates2; // might still be null
2791 /* find all sources, but don't use this snapshot because the
2792 state file on disk still references sources we may have already
2796 find_all_sources_across_snapshots (all_sources, true);
2798 /* add our current source list
2801 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2802 boost::shared_ptr<FileSource> fs;
2803 SourceMap::iterator tmp = i;
2806 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2807 if (playlists->source_use_count (fs) != 0) {
2808 all_sources.insert (fs->path());
2811 /* we might not remove this source from disk, because it may be used
2812 by other snapshots, but its not being used in this version
2813 so lets get rid of it now, along with any representative regions
2817 RegionFactory::remove_regions_using_source (i->second);
2825 char tmppath1[PATH_MAX+1];
2826 char tmppath2[PATH_MAX+1];
2829 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2834 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2836 if (realpath(spath.c_str(), tmppath1) == 0) {
2837 error << string_compose (_("Cannot expand path %1 (%2)"),
2838 spath, strerror (errno)) << endmsg;
2842 if (realpath((*i).c_str(), tmppath2) == 0) {
2843 error << string_compose (_("Cannot expand path %1 (%2)"),
2844 (*i), strerror (errno)) << endmsg;
2848 if (strcmp(tmppath1, tmppath2) == 0) {
2855 unused.push_back (spath);
2864 /* now try to move all unused files into the "dead" directory(ies) */
2866 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2867 struct stat statbuf;
2871 /* don't move the file across filesystems, just
2872 stick it in the `dead_dir_name' directory
2873 on whichever filesystem it was already on.
2876 if ((*x).find ("/sounds/") != string::npos) {
2878 /* old school, go up 1 level */
2880 newpath = Glib::path_get_dirname (*x); // "sounds"
2881 newpath = Glib::path_get_dirname (newpath); // "session-name"
2885 /* new school, go up 4 levels */
2887 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2888 newpath = Glib::path_get_dirname (newpath); // "session-name"
2889 newpath = Glib::path_get_dirname (newpath); // "interchange"
2890 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2893 newpath = Glib::build_filename (newpath, dead_dir_name);
2895 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2896 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2900 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2902 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2904 /* the new path already exists, try versioning */
2906 char buf[PATH_MAX+1];
2910 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2913 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2914 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2918 if (version == 999) {
2919 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2923 newpath = newpath_v;
2928 /* it doesn't exist, or we can't read it or something */
2932 stat ((*x).c_str(), &statbuf);
2934 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2935 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2936 (*x), newpath, strerror (errno))
2941 /* see if there an easy to find peakfile for this file, and remove it.
2944 string base = basename_nosuffix (*x);
2945 base += "%A"; /* this is what we add for the channel suffix of all native files,
2946 or for the first channel of embedded files. it will miss
2947 some peakfiles for other channels
2949 string peakpath = peak_path (base);
2951 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2952 if (::unlink (peakpath.c_str()) != 0) {
2953 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2954 peakpath, _path, strerror (errno))
2956 /* try to back out */
2957 ::rename (newpath.c_str(), _path.c_str());
2962 rep.paths.push_back (*x);
2963 rep.space += statbuf.st_size;
2966 /* dump the history list */
2970 /* save state so we don't end up a session file
2971 referring to non-existent sources.
2978 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2984 Session::cleanup_trash_sources (CleanupReport& rep)
2986 // FIXME: needs adaptation for MIDI
2988 vector<space_and_path>::iterator i;
2994 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2996 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2998 clear_directory (dead_dir, &rep.space, &rep.paths);
3005 Session::set_dirty ()
3007 bool was_dirty = dirty();
3009 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3013 DirtyChanged(); /* EMIT SIGNAL */
3019 Session::set_clean ()
3021 bool was_dirty = dirty();
3023 _state_of_the_state = Clean;
3027 DirtyChanged(); /* EMIT SIGNAL */
3032 Session::set_deletion_in_progress ()
3034 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3038 Session::clear_deletion_in_progress ()
3040 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3044 Session::add_controllable (boost::shared_ptr<Controllable> c)
3046 /* this adds a controllable to the list managed by the Session.
3047 this is a subset of those managed by the Controllable class
3048 itself, and represents the only ones whose state will be saved
3049 as part of the session.
3052 Glib::Mutex::Lock lm (controllables_lock);
3053 controllables.insert (c);
3056 struct null_deleter { void operator()(void const *) const {} };
3059 Session::remove_controllable (Controllable* c)
3061 if (_state_of_the_state & Deletion) {
3065 Glib::Mutex::Lock lm (controllables_lock);
3067 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3069 if (x != controllables.end()) {
3070 controllables.erase (x);
3074 boost::shared_ptr<Controllable>
3075 Session::controllable_by_id (const PBD::ID& id)
3077 Glib::Mutex::Lock lm (controllables_lock);
3079 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3080 if ((*i)->id() == id) {
3085 return boost::shared_ptr<Controllable>();
3088 boost::shared_ptr<Controllable>
3089 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3091 boost::shared_ptr<Controllable> c;
3092 boost::shared_ptr<Route> r;
3094 switch (desc.top_level_type()) {
3095 case ControllableDescriptor::NamedRoute:
3097 std::string str = desc.top_level_name();
3098 if (str == "master") {
3100 } else if (str == "control" || str == "listen") {
3103 r = route_by_name (desc.top_level_name());
3108 case ControllableDescriptor::RemoteControlID:
3109 r = route_by_remote_id (desc.rid());
3117 switch (desc.subtype()) {
3118 case ControllableDescriptor::Gain:
3119 c = r->gain_control ();
3122 case ControllableDescriptor::Solo:
3123 c = r->solo_control();
3126 case ControllableDescriptor::Mute:
3127 c = r->mute_control();
3130 case ControllableDescriptor::Recenable:
3132 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3135 c = t->rec_enable_control ();
3140 case ControllableDescriptor::PanDirection:
3142 c = r->pannable()->pan_azimuth_control;
3146 case ControllableDescriptor::PanWidth:
3148 c = r->pannable()->pan_width_control;
3152 case ControllableDescriptor::PanElevation:
3154 c = r->pannable()->pan_elevation_control;
3158 case ControllableDescriptor::Balance:
3159 /* XXX simple pan control */
3162 case ControllableDescriptor::PluginParameter:
3164 uint32_t plugin = desc.target (0);
3165 uint32_t parameter_index = desc.target (1);
3167 /* revert to zero based counting */
3173 if (parameter_index > 0) {
3177 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3180 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3181 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3186 case ControllableDescriptor::SendGain:
3188 uint32_t send = desc.target (0);
3190 /* revert to zero-based counting */
3196 boost::shared_ptr<Processor> p = r->nth_send (send);
3199 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3200 boost::shared_ptr<Amp> a = s->amp();
3203 c = s->amp()->gain_control();
3210 /* relax and return a null pointer */
3218 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3221 Stateful::add_instant_xml (node, _path);
3224 if (write_to_config) {
3225 Config->add_instant_xml (node);
3230 Session::instant_xml (const string& node_name)
3232 return Stateful::instant_xml (node_name, _path);
3236 Session::save_history (string snapshot_name)
3244 if (snapshot_name.empty()) {
3245 snapshot_name = _current_snapshot_name;
3248 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3249 const string backup_filename = history_filename + backup_suffix;
3250 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3251 const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3253 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3254 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3255 error << _("could not backup old history file, current history not saved") << endmsg;
3260 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3264 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3266 if (!tree.write (xml_path))
3268 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3270 if (g_remove (xml_path.c_str()) != 0) {
3271 error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3272 xml_path, g_strerror (errno)) << endmsg;
3274 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3275 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3276 backup_path, g_strerror (errno)) << endmsg;
3286 Session::restore_history (string snapshot_name)
3290 if (snapshot_name.empty()) {
3291 snapshot_name = _current_snapshot_name;
3294 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3295 const sys::path xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3297 info << "Loading history from " << xml_path.to_string() << endmsg;
3299 if (!Glib::file_test (xml_path.to_string(), Glib::FILE_TEST_EXISTS)) {
3300 info << string_compose (_("%1: no history file \"%2\" for this session."),
3301 _name, xml_path.to_string()) << endmsg;
3305 if (!tree.read (xml_path.to_string())) {
3306 error << string_compose (_("Could not understand session history file \"%1\""),
3307 xml_path.to_string()) << endmsg;
3314 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3317 UndoTransaction* ut = new UndoTransaction ();
3320 ut->set_name(t->property("name")->value());
3321 stringstream ss(t->property("tv-sec")->value());
3323 ss.str(t->property("tv-usec")->value());
3325 ut->set_timestamp(tv);
3327 for (XMLNodeConstIterator child_it = t->children().begin();
3328 child_it != t->children().end(); child_it++)
3330 XMLNode *n = *child_it;
3333 if (n->name() == "MementoCommand" ||
3334 n->name() == "MementoUndoCommand" ||
3335 n->name() == "MementoRedoCommand") {
3337 if ((c = memento_command_factory(n))) {
3341 } else if (n->name() == "NoteDiffCommand") {
3342 PBD::ID id (n->property("midi-source")->value());
3343 boost::shared_ptr<MidiSource> midi_source =
3344 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3346 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3348 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3351 } else if (n->name() == "SysExDiffCommand") {
3353 PBD::ID id (n->property("midi-source")->value());
3354 boost::shared_ptr<MidiSource> midi_source =
3355 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3357 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3359 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3362 } else if (n->name() == "PatchChangeDiffCommand") {
3364 PBD::ID id (n->property("midi-source")->value());
3365 boost::shared_ptr<MidiSource> midi_source =
3366 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3368 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3370 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3373 } else if (n->name() == "StatefulDiffCommand") {
3374 if ((c = stateful_diff_command_factory (n))) {
3375 ut->add_command (c);
3378 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3389 Session::config_changed (std::string p, bool ours)
3395 if (p == "seamless-loop") {
3397 } else if (p == "rf-speed") {
3399 } else if (p == "auto-loop") {
3401 } else if (p == "auto-input") {
3403 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3404 /* auto-input only makes a difference if we're rolling */
3405 set_track_monitor_input_status (!config.get_auto_input());
3408 } else if (p == "punch-in") {
3412 if ((location = _locations->auto_punch_location()) != 0) {
3414 if (config.get_punch_in ()) {
3415 replace_event (SessionEvent::PunchIn, location->start());
3417 remove_event (location->start(), SessionEvent::PunchIn);
3421 } else if (p == "punch-out") {
3425 if ((location = _locations->auto_punch_location()) != 0) {
3427 if (config.get_punch_out()) {
3428 replace_event (SessionEvent::PunchOut, location->end());
3430 clear_events (SessionEvent::PunchOut);
3434 } else if (p == "edit-mode") {
3436 Glib::Mutex::Lock lm (playlists->lock);
3438 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3439 (*i)->set_edit_mode (Config->get_edit_mode ());
3442 } else if (p == "use-video-sync") {
3444 waiting_for_sync_offset = config.get_use_video_sync();
3446 } else if (p == "mmc-control") {
3448 //poke_midi_thread ();
3450 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3452 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3454 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3456 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3458 } else if (p == "midi-control") {
3460 //poke_midi_thread ();
3462 } else if (p == "raid-path") {
3464 setup_raid_path (config.get_raid_path());
3466 } else if (p == "timecode-format") {
3470 } else if (p == "video-pullup") {
3474 } else if (p == "seamless-loop") {
3476 if (play_loop && transport_rolling()) {
3477 // to reset diskstreams etc
3478 request_play_loop (true);
3481 } else if (p == "rf-speed") {
3483 cumulative_rf_motion = 0;
3486 } else if (p == "click-sound") {
3488 setup_click_sounds (1);
3490 } else if (p == "click-emphasis-sound") {
3492 setup_click_sounds (-1);
3494 } else if (p == "clicking") {
3496 if (Config->get_clicking()) {
3497 if (_click_io && click_data) { // don't require emphasis data
3504 } else if (p == "click-gain") {
3507 _click_gain->set_gain (Config->get_click_gain(), this);
3510 } else if (p == "send-mtc") {
3512 if (Config->get_send_mtc ()) {
3513 /* mark us ready to send */
3514 next_quarter_frame_to_send = 0;
3517 } else if (p == "send-mmc") {
3519 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3521 } else if (p == "midi-feedback") {
3523 session_midi_feedback = Config->get_midi_feedback();
3525 } else if (p == "jack-time-master") {
3527 engine().reset_timebase ();
3529 } else if (p == "native-file-header-format") {
3531 if (!first_file_header_format_reset) {
3532 reset_native_file_format ();
3535 first_file_header_format_reset = false;
3537 } else if (p == "native-file-data-format") {
3539 if (!first_file_data_format_reset) {
3540 reset_native_file_format ();
3543 first_file_data_format_reset = false;
3545 } else if (p == "external-sync") {
3546 if (!config.get_external_sync()) {
3547 drop_sync_source ();
3549 switch_to_sync_source (config.get_sync_source());
3551 } else if (p == "remote-model") {
3552 set_remote_control_ids ();
3553 } else if (p == "denormal-model") {
3555 } else if (p == "history-depth") {
3556 set_history_depth (Config->get_history_depth());
3557 } else if (p == "sync-all-route-ordering") {
3558 sync_order_keys ("session");
3559 } else if (p == "initial-program-change") {
3561 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3564 buf[0] = MIDI::program; // channel zero by default
3565 buf[1] = (Config->get_initial_program_change() & 0x7f);
3567 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3569 } else if (p == "solo-mute-override") {
3570 // catch_up_on_solo_mute_override ();
3571 } else if (p == "listen-position" || p == "pfl-position") {
3572 listen_position_changed ();
3573 } else if (p == "solo-control-is-listen-control") {
3574 solo_control_mode_changed ();
3575 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3576 last_timecode_valid = false;
3577 } else if (p == "playback-buffer-seconds") {
3578 AudioSource::allocate_working_buffers (frame_rate());
3579 } else if (p == "automation-thinning-factor") {
3580 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3587 Session::set_history_depth (uint32_t d)
3589 _history.set_depth (d);
3593 Session::load_diskstreams_2X (XMLNode const & node, int)
3596 XMLNodeConstIterator citer;
3598 clist = node.children();
3600 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3603 /* diskstreams added automatically by DiskstreamCreated handler */
3604 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3605 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3606 _diskstreams_2X.push_back (dsp);
3608 error << _("Session: unknown diskstream type in XML") << endmsg;
3612 catch (failed_constructor& err) {
3613 error << _("Session: could not load diskstream via XML state") << endmsg;
3621 /** Connect things to the MMC object */
3623 Session::setup_midi_machine_control ()
3625 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3627 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3628 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3629 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3630 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3631 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3632 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3633 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3634 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3635 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3636 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3637 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3638 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3639 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3641 /* also handle MIDI SPP because its so common */
3643 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3644 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3645 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3648 boost::shared_ptr<Controllable>
3649 Session::solo_cut_control() const
3651 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3652 controls in Ardour that currently get presented to the user in the GUI that require
3653 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3655 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3656 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3660 return _solo_cut_control;
3664 Session::rename (const std::string& new_name)
3666 string legal_name = legalize_for_path (new_name);
3672 string const old_sources_root = _session_dir->sources_root();
3674 #define RENAME ::rename
3679 * interchange subdirectory
3683 * Backup files are left unchanged and not renamed.
3686 /* pass one: not 100% safe check that the new directory names don't
3690 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3695 /* this is a stupid hack because Glib::path_get_dirname() is
3696 * lexical-only, and so passing it /a/b/c/ gives a different
3697 * result than passing it /a/b/c ...
3700 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3701 oldstr = oldstr.substr (0, oldstr.length() - 1);
3704 string base = Glib::path_get_dirname (oldstr);
3705 string p = Glib::path_get_basename (oldstr);
3707 newstr = Glib::build_filename (base, legal_name);
3709 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3716 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3721 /* this is a stupid hack because Glib::path_get_dirname() is
3722 * lexical-only, and so passing it /a/b/c/ gives a different
3723 * result than passing it /a/b/c ...
3726 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3727 oldstr = oldstr.substr (0, oldstr.length() - 1);
3730 string base = Glib::path_get_dirname (oldstr);
3731 string p = Glib::path_get_basename (oldstr);
3733 newstr = Glib::build_filename (base, legal_name);
3735 cerr << "Rename " << oldstr << " => " << newstr << endl;
3737 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3742 (*_session_dir) = newstr;
3747 /* directory below interchange */
3749 v.push_back (newstr);
3750 v.push_back (interchange_dir_name);
3753 oldstr = Glib::build_filename (v);
3756 v.push_back (newstr);
3757 v.push_back (interchange_dir_name);
3758 v.push_back (legal_name);
3760 newstr = Glib::build_filename (v);
3762 cerr << "Rename " << oldstr << " => " << newstr << endl;
3764 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3771 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3772 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3774 cerr << "Rename " << oldstr << " => " << newstr << endl;
3776 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3783 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3785 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3786 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3788 cerr << "Rename " << oldstr << " => " << newstr << endl;
3790 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3795 /* update file source paths */
3797 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3798 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3800 string p = fs->path ();
3801 boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3806 /* remove old name from recent sessions */
3808 remove_recent_sessions (_path);
3811 _current_snapshot_name = new_name;
3816 /* save state again to get everything just right */
3818 save_state (_current_snapshot_name);
3821 /* add to recent sessions */
3823 store_recent_sessions (new_name, _path);