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 */
43 #ifdef HAVE_SYS_STATVFS_H
44 #include <sys/statvfs.h>
48 #include <glib/gstdio.h>
51 #include <glibmm/threads.h>
53 #include <boost/algorithm/string.hpp>
55 #include "midi++/mmc.h"
56 #include "midi++/port.h"
57 #include "midi++/manager.h"
59 #include "evoral/SMF.hpp"
61 #include "pbd/boost_debug.h"
62 #include "pbd/basename.h"
63 #include "pbd/controllable_descriptor.h"
64 #include "pbd/enumwriter.h"
65 #include "pbd/error.h"
66 #include "pbd/file_utils.h"
67 #include "pbd/pathexpand.h"
68 #include "pbd/pathscanner.h"
69 #include "pbd/pthread_utils.h"
70 #include "pbd/stacktrace.h"
71 #include "pbd/convert.h"
72 #include "pbd/clear_dir.h"
74 #include "ardour/amp.h"
75 #include "ardour/audio_diskstream.h"
76 #include "ardour/audio_track.h"
77 #include "ardour/audioengine.h"
78 #include "ardour/audiofilesource.h"
79 #include "ardour/audioregion.h"
80 #include "ardour/automation_control.h"
81 #include "ardour/butler.h"
82 #include "ardour/control_protocol_manager.h"
83 #include "ardour/directory_names.h"
84 #include "ardour/filename_extensions.h"
85 #include "ardour/location.h"
86 #include "ardour/midi_model.h"
87 #include "ardour/midi_patch_manager.h"
88 #include "ardour/midi_region.h"
89 #include "ardour/midi_source.h"
90 #include "ardour/midi_track.h"
91 #include "ardour/pannable.h"
92 #include "ardour/playlist_factory.h"
93 #include "ardour/port.h"
94 #include "ardour/processor.h"
95 #include "ardour/proxy_controllable.h"
96 #include "ardour/recent_sessions.h"
97 #include "ardour/region_factory.h"
98 #include "ardour/route_group.h"
99 #include "ardour/send.h"
100 #include "ardour/session.h"
101 #include "ardour/session_directory.h"
102 #include "ardour/session_metadata.h"
103 #include "ardour/session_playlists.h"
104 #include "ardour/session_state_utils.h"
105 #include "ardour/silentfilesource.h"
106 #include "ardour/sndfilesource.h"
107 #include "ardour/source_factory.h"
108 #include "ardour/speakers.h"
109 #include "ardour/template_utils.h"
110 #include "ardour/tempo.h"
111 #include "ardour/ticker.h"
112 #include "ardour/user_bundle.h"
114 #include "control_protocol/control_protocol.h"
120 using namespace ARDOUR;
123 /** @param snapshot_name Snapshot name, without the .ardour prefix */
125 Session::first_stage_init (string fullpath, string snapshot_name)
127 if (fullpath.length() == 0) {
129 throw failed_constructor();
132 _path = canonical_path (fullpath);
134 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
135 _path += G_DIR_SEPARATOR;
138 /* these two are just provisional settings. set_state()
139 will likely override them.
142 _name = _current_snapshot_name = snapshot_name;
144 set_history_depth (Config->get_history_depth());
146 _current_frame_rate = _engine.frame_rate ();
147 _nominal_frame_rate = _current_frame_rate;
148 _base_frame_rate = _current_frame_rate;
150 _tempo_map = new TempoMap (_current_frame_rate);
151 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
154 _non_soloed_outs_muted = false;
156 _solo_isolated_cnt = 0;
157 g_atomic_int_set (&processing_prohibited, 0);
158 _transport_speed = 0;
159 _default_transport_speed = 1.0;
160 _last_transport_speed = 0;
161 _target_transport_speed = 0;
162 auto_play_legal = false;
163 transport_sub_state = 0;
164 _transport_frame = 0;
165 _requested_return_frame = -1;
166 _session_range_location = 0;
167 g_atomic_int_set (&_record_status, Disabled);
168 loop_changing = false;
171 _last_roll_location = 0;
172 _last_roll_or_reversal_location = 0;
173 _last_record_location = 0;
174 pending_locate_frame = 0;
175 pending_locate_roll = false;
176 pending_locate_flush = false;
177 state_was_pending = false;
179 outbound_mtc_timecode_frame = 0;
180 next_quarter_frame_to_send = -1;
181 current_block_size = 0;
182 solo_update_disabled = false;
183 _have_captured = false;
184 _worst_output_latency = 0;
185 _worst_input_latency = 0;
186 _worst_track_latency = 0;
187 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
188 _was_seamless = Config->get_seamless_loop ();
190 _send_qf_mtc = false;
191 _pframes_since_last_mtc = 0;
192 g_atomic_int_set (&_playback_load, 100);
193 g_atomic_int_set (&_capture_load, 100);
196 pending_abort = false;
197 _adding_routes_in_progress = false;
198 destructive_index = 0;
199 first_file_data_format_reset = true;
200 first_file_header_format_reset = true;
201 post_export_sync = false;
204 no_questions_about_missing_files = false;
205 _speakers.reset (new Speakers);
207 ignore_route_processor_changes = false;
208 _pre_export_mmc_enabled = false;
210 AudioDiskstream::allocate_working_buffers();
212 /* default short fade = 15ms */
214 SndFileSource::setup_standard_crossfades (*this, frame_rate());
216 last_mmc_step.tv_sec = 0;
217 last_mmc_step.tv_usec = 0;
220 /* click sounds are unset by default, which causes us to internal
221 waveforms for clicks.
225 click_emphasis_length = 0;
228 process_function = &Session::process_with_events;
230 if (config.get_use_video_sync()) {
231 waiting_for_sync_offset = true;
233 waiting_for_sync_offset = false;
236 last_timecode_when = 0;
237 last_timecode_valid = false;
241 last_rr_session_dir = session_dirs.begin();
242 refresh_disk_space ();
244 /* default: assume simple stereo speaker configuration */
246 _speakers->setup_default_speakers (2);
250 average_slave_delta = 1800; // !!! why 1800 ????
251 have_first_delta_accumulator = false;
252 delta_accumulator_cnt = 0;
253 _slave_state = Stopped;
255 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
256 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
257 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
258 add_controllable (_solo_cut_control);
260 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
262 /* These are all static "per-class" signals */
264 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
265 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
266 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
267 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
268 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
270 /* stop IO objects from doing stuff until we're ready for them */
272 Delivery::disable_panners ();
273 IO::disable_connecting ();
277 Session::second_stage_init ()
279 AudioFileSource::set_peak_dir (_session_dir->peak_path());
282 if (load_state (_current_snapshot_name)) {
287 if (_butler->start_thread()) {
291 if (start_midi_thread ()) {
295 setup_midi_machine_control ();
297 // set_state() will call setup_raid_path(), but if it's a new session we need
298 // to call setup_raid_path() here.
301 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
305 setup_raid_path(_path);
308 /* we can't save till after ::when_engine_running() is called,
309 because otherwise we save state with no connections made.
310 therefore, we reset _state_of_the_state because ::set_state()
311 will have cleared it.
313 we also have to include Loading so that any events that get
314 generated between here and the end of ::when_engine_running()
315 will be processed directly rather than queued.
318 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
320 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
321 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
322 setup_click_sounds (0);
323 setup_midi_control ();
325 /* Pay attention ... */
327 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
328 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
330 midi_clock = new MidiClockTicker ();
331 midi_clock->set_session (this);
334 when_engine_running ();
337 /* handle this one in a different way than all others, so that its clear what happened */
339 catch (AudioEngine::PortRegistrationFailure& err) {
340 error << err.what() << endmsg;
348 BootMessage (_("Reset Remote Controls"));
350 send_full_time_code (0);
351 _engine.transport_locate (0);
353 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
354 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
356 MIDI::Name::MidiPatchManager::instance().set_session (this);
359 /* initial program change will be delivered later; see ::config_changed() */
361 _state_of_the_state = Clean;
363 Port::set_connecting_blocked (false);
365 DirtyChanged (); /* EMIT SIGNAL */
367 if (state_was_pending) {
368 save_state (_current_snapshot_name);
369 remove_pending_capture_state ();
370 state_was_pending = false;
373 BootMessage (_("Session loading complete"));
379 Session::raid_path () const
381 SearchPath raid_search_path;
383 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
384 raid_search_path += (*i).path;
387 return raid_search_path.to_string ();
391 Session::setup_raid_path (string path)
400 session_dirs.clear ();
402 SearchPath search_path(path);
403 SearchPath sound_search_path;
404 SearchPath midi_search_path;
406 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
408 sp.blocks = 0; // not needed
409 session_dirs.push_back (sp);
411 SessionDirectory sdir(sp.path);
413 sound_search_path += sdir.sound_path ();
414 midi_search_path += sdir.midi_path ();
417 // reset the round-robin soundfile path thingie
418 last_rr_session_dir = session_dirs.begin();
422 Session::path_is_within_session (const std::string& path)
424 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
425 if (PBD::path_is_within (i->path, path)) {
433 Session::ensure_subdirs ()
437 dir = session_directory().peak_path();
439 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
440 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
444 dir = session_directory().sound_path();
446 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
447 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
451 dir = session_directory().midi_path();
453 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
454 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
458 dir = session_directory().dead_path();
460 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
461 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
465 dir = session_directory().export_path();
467 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
468 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
472 dir = analysis_dir ();
474 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
475 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
479 dir = plugins_dir ();
481 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
482 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
486 dir = externals_dir ();
488 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
489 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
496 /** @param session_template directory containing session template, or empty.
497 * Caller must not hold process lock.
500 Session::create (const string& session_template, BusProfile* bus_profile)
502 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
503 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
507 if (ensure_subdirs ()) {
511 _writable = exists_and_writable (_path);
513 if (!session_template.empty()) {
514 std::string in_path = session_template_dir_to_file (session_template);
516 ifstream in(in_path.c_str());
519 string out_path = _path;
521 out_path += statefile_suffix;
523 ofstream out(out_path.c_str());
529 /* Copy plugin state files from template to new session */
530 std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
531 copy_files (template_plugins, plugins_dir ());
536 error << string_compose (_("Could not open %1 for writing session template"), out_path)
542 error << string_compose (_("Could not open session template %1 for reading"), in_path)
549 /* set initial start + end point */
551 _state_of_the_state = Clean;
553 /* set up Master Out and Control Out if necessary */
558 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
560 if (bus_profile->master_out_channels) {
561 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
565 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
566 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
569 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
570 r->input()->ensure_io (count, false, this);
571 r->output()->ensure_io (count, false, this);
577 /* prohibit auto-connect to master, because there isn't one */
578 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
582 add_routes (rl, false, false, false);
585 /* this allows the user to override settings with an environment variable.
588 if (no_auto_connect()) {
589 bus_profile->input_ac = AutoConnectOption (0);
590 bus_profile->output_ac = AutoConnectOption (0);
593 Config->set_input_auto_connect (bus_profile->input_ac);
594 Config->set_output_auto_connect (bus_profile->output_ac);
597 if (Config->get_use_monitor_bus() && bus_profile) {
598 add_monitor_section ();
607 Session::maybe_write_autosave()
609 if (dirty() && record_status() != Recording) {
610 save_state("", true);
615 Session::remove_pending_capture_state ()
617 std::string pending_state_file_path(_session_dir->root_path());
619 pending_state_file_path = Glib::build_filename (pending_state_file_path, legalize_for_path (_current_snapshot_name) + pending_suffix);
621 if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS)) return;
623 if (g_remove (pending_state_file_path.c_str()) != 0) {
624 error << string_compose(_("Could not remove pending capture state at path \"%1\" (%2)"),
625 pending_state_file_path, g_strerror (errno)) << endmsg;
629 /** Rename a state file.
630 * @param old_name Old snapshot name.
631 * @param new_name New snapshot name.
634 Session::rename_state (string old_name, string new_name)
636 if (old_name == _current_snapshot_name || old_name == _name) {
637 /* refuse to rename the current snapshot or the "main" one */
641 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
642 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
644 const std::string old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
645 const std::string new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
647 if (::g_rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
648 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
649 old_name, new_name, g_strerror(errno)) << endmsg;
653 /** Remove a state file.
654 * @param snapshot_name Snapshot name.
657 Session::remove_state (string snapshot_name)
659 if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
660 // refuse to remove the current snapshot or the "main" one
664 std::string xml_path(_session_dir->root_path());
666 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
668 if (!create_backup_file (xml_path)) {
669 // don't remove it if a backup can't be made
670 // create_backup_file will log the error.
675 if (g_remove (xml_path.c_str()) != 0) {
676 error << string_compose(_("Could not remove session file at path \"%1\" (%2)"),
677 xml_path, g_strerror (errno)) << endmsg;
681 #ifdef HAVE_JACK_SESSION
683 Session::jack_session_event (jack_session_event_t * event)
685 char timebuf[128], *tmp;
687 struct tm local_time;
690 localtime_r (&n, &local_time);
691 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
693 while ((tmp = strchr(timebuf, ':'))) { *tmp = '.'; }
695 if (event->type == JackSessionSaveTemplate)
697 if (save_template( timebuf )) {
698 event->flags = JackSessionSaveError;
700 string cmd ("ardour3 -P -U ");
701 cmd += event->client_uuid;
705 event->command_line = strdup (cmd.c_str());
710 if (save_state (timebuf)) {
711 event->flags = JackSessionSaveError;
713 std::string xml_path (_session_dir->root_path());
714 std::string legalized_filename = legalize_for_path (timebuf) + statefile_suffix;
715 xml_path = Glib::build_filename (xml_path, legalized_filename);
717 string cmd ("ardour3 -P -U ");
718 cmd += event->client_uuid;
723 event->command_line = strdup (cmd.c_str());
727 jack_session_reply (_engine.jack(), event);
729 if (event->type == JackSessionSaveAndQuit) {
730 Quit (); /* EMIT SIGNAL */
733 jack_session_event_free( event );
737 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
739 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
742 std::string xml_path(_session_dir->root_path());
744 if (!_writable || (_state_of_the_state & CannotSave)) {
748 if (!_engine.connected ()) {
749 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
755 /* tell sources we're saving first, in case they write out to a new file
756 * which should be saved with the state rather than the old one */
757 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
759 i->second->session_saved();
760 } catch (Evoral::SMF::FileError& e) {
761 error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
765 SaveSession (); /* EMIT SIGNAL */
767 tree.set_root (&get_state());
769 if (snapshot_name.empty()) {
770 snapshot_name = _current_snapshot_name;
771 } else if (switch_to_snapshot) {
772 _current_snapshot_name = snapshot_name;
777 /* proper save: use statefile_suffix (.ardour in English) */
779 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
781 /* make a backup copy of the old file */
783 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) {
784 // create_backup_file will log the error
790 /* pending save: use pending_suffix (.pending in English) */
791 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
794 std::string tmp_path(_session_dir->root_path());
795 tmp_path = Glib::build_filename (tmp_path, legalize_for_path (snapshot_name) + temp_suffix);
797 // cerr << "actually writing state to " << xml_path << endl;
799 if (!tree.write (tmp_path)) {
800 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
801 if (g_remove (tmp_path.c_str()) != 0) {
802 error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
803 tmp_path, g_strerror (errno)) << endmsg;
809 if (::rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
810 error << string_compose (_("could not rename temporary session file %1 to %2"),
811 tmp_path, xml_path) << endmsg;
812 if (g_remove (tmp_path.c_str()) != 0) {
813 error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
814 tmp_path, g_strerror (errno)) << endmsg;
822 save_history (snapshot_name);
824 bool was_dirty = dirty();
826 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
829 DirtyChanged (); /* EMIT SIGNAL */
832 StateSaved (snapshot_name); /* EMIT SIGNAL */
839 Session::restore_state (string snapshot_name)
841 if (load_state (snapshot_name) == 0) {
842 set_state (*state_tree->root(), Stateful::loading_state_version);
849 Session::load_state (string snapshot_name)
854 state_was_pending = false;
856 /* check for leftover pending state from a crashed capture attempt */
858 std::string xmlpath(_session_dir->root_path());
859 xmlpath = Glib::build_filename (xmlpath, legalize_for_path (snapshot_name) + pending_suffix);
861 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
863 /* there is pending state from a crashed capture attempt */
865 boost::optional<int> r = AskAboutPendingState();
866 if (r.get_value_or (1)) {
867 state_was_pending = true;
871 if (!state_was_pending) {
872 xmlpath = Glib::build_filename (_session_dir->root_path(), snapshot_name);
875 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
876 xmlpath = Glib::build_filename (_session_dir->root_path(), legalize_for_path (snapshot_name) + statefile_suffix);
877 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
878 error << string_compose(_("%1: session file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
883 state_tree = new XMLTree;
887 _writable = exists_and_writable (xmlpath);
889 if (!state_tree->read (xmlpath)) {
890 error << string_compose(_("Could not understand session file %1"), xmlpath) << endmsg;
896 XMLNode& root (*state_tree->root());
898 if (root.name() != X_("Session")) {
899 error << string_compose (_("Session file %1 is not a session"), xmlpath) << endmsg;
905 const XMLProperty* prop;
907 if ((prop = root.property ("version")) == 0) {
908 /* no version implies very old version of Ardour */
909 Stateful::loading_state_version = 1000;
911 if (prop->value().find ('.') != string::npos) {
912 /* old school version format */
913 if (prop->value()[0] == '2') {
914 Stateful::loading_state_version = 2000;
916 Stateful::loading_state_version = 3000;
919 Stateful::loading_state_version = atoi (prop->value());
923 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
925 std::string backup_path(_session_dir->root_path());
926 std::string backup_filename = string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
927 backup_path = Glib::build_filename (backup_path, backup_filename);
929 // only create a backup for a given statefile version once
931 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
933 VersionMismatch (xmlpath, backup_path);
935 if (!copy_file (xmlpath, backup_path)) {;
945 Session::load_options (const XMLNode& node)
947 LocaleGuard lg (X_("POSIX"));
948 config.set_variables (node);
959 Session::get_template()
961 /* if we don't disable rec-enable, diskstreams
962 will believe they need to store their capture
963 sources in their state node.
966 disable_record (false);
972 Session::state (bool full_state)
974 XMLNode* node = new XMLNode("Session");
978 snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
979 node->add_property("version", buf);
981 /* store configuration settings */
985 node->add_property ("name", _name);
986 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
987 node->add_property ("sample-rate", buf);
989 if (session_dirs.size() > 1) {
993 vector<space_and_path>::iterator i = session_dirs.begin();
994 vector<space_and_path>::iterator next;
996 ++i; /* skip the first one */
1000 while (i != session_dirs.end()) {
1004 if (next != session_dirs.end()) {
1014 child = node->add_child ("Path");
1015 child->add_content (p);
1019 /* save the ID counter */
1021 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1022 node->add_property ("id-counter", buf);
1024 /* save the event ID counter */
1026 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1027 node->add_property ("event-counter", buf);
1029 /* various options */
1031 node->add_child_nocopy (config.get_variables ());
1033 node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
1035 child = node->add_child ("Sources");
1038 Glib::Threads::Mutex::Lock sl (source_lock);
1040 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1042 /* Don't save information about non-file Sources, or
1043 * about non-destructive file sources that are empty
1044 * and unused by any regions.
1047 boost::shared_ptr<FileSource> fs;
1049 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1051 if (!fs->destructive()) {
1052 if (fs->empty() && !fs->used()) {
1057 child->add_child_nocopy (siter->second->get_state());
1062 child = node->add_child ("Regions");
1065 Glib::Threads::Mutex::Lock rl (region_lock);
1066 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1067 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1068 boost::shared_ptr<Region> r = i->second;
1069 /* only store regions not attached to playlists */
1070 if (r->playlist() == 0) {
1071 if (boost::dynamic_pointer_cast<AudioRegion>(r)) {
1072 child->add_child_nocopy ((boost::dynamic_pointer_cast<AudioRegion>(r))->get_basic_state ());
1074 child->add_child_nocopy (r->get_state ());
1079 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1081 if (!cassocs.empty()) {
1082 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1084 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1086 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1087 i->first->id().print (buf, sizeof (buf));
1088 can->add_property (X_("copy"), buf);
1089 i->second->id().print (buf, sizeof (buf));
1090 can->add_property (X_("original"), buf);
1091 ca->add_child_nocopy (*can);
1097 node->add_child_nocopy (_locations->get_state());
1099 // for a template, just create a new Locations, populate it
1100 // with the default start and end, and get the state for that.
1101 Locations loc (*this);
1102 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1103 range->set (max_framepos, 0);
1105 node->add_child_nocopy (loc.get_state());
1108 child = node->add_child ("Bundles");
1110 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1111 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1112 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1114 child->add_child_nocopy (b->get_state());
1119 child = node->add_child ("Routes");
1121 boost::shared_ptr<RouteList> r = routes.reader ();
1123 RoutePublicOrderSorter cmp;
1124 RouteList public_order (*r);
1125 public_order.sort (cmp);
1127 /* the sort should have put control outs first */
1130 assert (_monitor_out == public_order.front());
1133 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1134 if (!(*i)->is_auditioner()) {
1136 child->add_child_nocopy ((*i)->get_state());
1138 child->add_child_nocopy ((*i)->get_template());
1144 playlists->add_state (node, full_state);
1146 child = node->add_child ("RouteGroups");
1147 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1148 child->add_child_nocopy ((*i)->get_state());
1152 XMLNode* gain_child = node->add_child ("Click");
1153 gain_child->add_child_nocopy (_click_io->state (full_state));
1154 gain_child->add_child_nocopy (_click_gain->state (full_state));
1158 XMLNode* ltc_input_child = node->add_child ("LTC-In");
1159 ltc_input_child->add_child_nocopy (_ltc_input->state (full_state));
1163 XMLNode* ltc_output_child = node->add_child ("LTC-Out");
1164 ltc_output_child->add_child_nocopy (_ltc_output->state (full_state));
1167 node->add_child_nocopy (_speakers->get_state());
1168 node->add_child_nocopy (_tempo_map->get_state());
1169 node->add_child_nocopy (get_control_protocol_state());
1172 node->add_child_copy (*_extra_xml);
1179 Session::get_control_protocol_state ()
1181 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1182 return cpm.get_state();
1186 Session::set_state (const XMLNode& node, int version)
1190 const XMLProperty* prop;
1193 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1195 if (node.name() != X_("Session")) {
1196 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1200 if ((prop = node.property ("name")) != 0) {
1201 _name = prop->value ();
1204 if ((prop = node.property (X_("sample-rate"))) != 0) {
1206 _nominal_frame_rate = atoi (prop->value());
1208 if (_nominal_frame_rate != _current_frame_rate) {
1209 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1210 if (r.get_value_or (0)) {
1216 setup_raid_path(_session_dir->root_path());
1218 if ((prop = node.property (X_("id-counter"))) != 0) {
1220 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1221 ID::init_counter (x);
1223 /* old sessions used a timebased counter, so fake
1224 the startup ID counter based on a standard
1229 ID::init_counter (now);
1232 if ((prop = node.property (X_("event-counter"))) != 0) {
1233 Evoral::init_event_id_counter (atoi (prop->value()));
1236 IO::disable_connecting ();
1238 Stateful::save_extra_xml (node);
1240 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1241 load_options (*child);
1242 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1243 load_options (*child);
1245 error << _("Session: XML state has no options section") << endmsg;
1248 if (version >= 3000) {
1249 if ((child = find_named_node (node, "Metadata")) == 0) {
1250 warning << _("Session: XML state has no metadata section") << endmsg;
1251 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1256 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1257 _speakers->set_state (*child, version);
1260 if ((child = find_named_node (node, "Sources")) == 0) {
1261 error << _("Session: XML state has no sources section") << endmsg;
1263 } else if (load_sources (*child)) {
1267 if ((child = find_named_node (node, "TempoMap")) == 0) {
1268 error << _("Session: XML state has no Tempo Map section") << endmsg;
1270 } else if (_tempo_map->set_state (*child, version)) {
1274 if ((child = find_named_node (node, "Locations")) == 0) {
1275 error << _("Session: XML state has no locations section") << endmsg;
1277 } else if (_locations->set_state (*child, version)) {
1283 if ((location = _locations->auto_loop_location()) != 0) {
1284 set_auto_loop_location (location);
1287 if ((location = _locations->auto_punch_location()) != 0) {
1288 set_auto_punch_location (location);
1291 if ((location = _locations->session_range_location()) != 0) {
1292 delete _session_range_location;
1293 _session_range_location = location;
1296 if (_session_range_location) {
1297 AudioFileSource::set_header_position_offset (_session_range_location->start());
1300 if ((child = find_named_node (node, "Regions")) == 0) {
1301 error << _("Session: XML state has no Regions section") << endmsg;
1303 } else if (load_regions (*child)) {
1307 if ((child = find_named_node (node, "Playlists")) == 0) {
1308 error << _("Session: XML state has no playlists section") << endmsg;
1310 } else if (playlists->load (*this, *child)) {
1314 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1316 } else if (playlists->load_unused (*this, *child)) {
1320 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1321 if (load_compounds (*child)) {
1326 if (version >= 3000) {
1327 if ((child = find_named_node (node, "Bundles")) == 0) {
1328 warning << _("Session: XML state has no bundles section") << endmsg;
1331 /* We can't load Bundles yet as they need to be able
1332 to convert from port names to Port objects, which can't happen until
1334 _bundle_xml_node = new XMLNode (*child);
1338 if (version < 3000) {
1339 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1340 error << _("Session: XML state has no diskstreams section") << endmsg;
1342 } else if (load_diskstreams_2X (*child, version)) {
1347 if ((child = find_named_node (node, "Routes")) == 0) {
1348 error << _("Session: XML state has no routes section") << endmsg;
1350 } else if (load_routes (*child, version)) {
1354 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1355 _diskstreams_2X.clear ();
1357 if (version >= 3000) {
1359 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1360 error << _("Session: XML state has no route groups section") << endmsg;
1362 } else if (load_route_groups (*child, version)) {
1366 } else if (version < 3000) {
1368 if ((child = find_named_node (node, "EditGroups")) == 0) {
1369 error << _("Session: XML state has no edit groups section") << endmsg;
1371 } else if (load_route_groups (*child, version)) {
1375 if ((child = find_named_node (node, "MixGroups")) == 0) {
1376 error << _("Session: XML state has no mix groups section") << endmsg;
1378 } else if (load_route_groups (*child, version)) {
1383 if ((child = find_named_node (node, "Click")) == 0) {
1384 warning << _("Session: XML state has no click section") << endmsg;
1385 } else if (_click_io) {
1386 const XMLNodeList& children (child->children());
1387 XMLNodeList::const_iterator i = children.begin();
1388 _click_io->set_state (**i, version);
1390 if (i != children.end()) {
1391 _click_gain->set_state (**i, version);
1395 if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
1396 ControlProtocolManager::instance().set_state (*child, version);
1399 update_have_rec_enabled_track ();
1401 /* here beginneth the second phase ... */
1403 StateReady (); /* EMIT SIGNAL */
1412 Session::load_routes (const XMLNode& node, int version)
1415 XMLNodeConstIterator niter;
1416 RouteList new_routes;
1418 nlist = node.children();
1422 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1424 boost::shared_ptr<Route> route;
1425 if (version < 3000) {
1426 route = XMLRouteFactory_2X (**niter, version);
1428 route = XMLRouteFactory (**niter, version);
1432 error << _("Session: cannot create Route from XML description.") << endmsg;
1436 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1438 new_routes.push_back (route);
1441 add_routes (new_routes, false, false, false);
1446 boost::shared_ptr<Route>
1447 Session::XMLRouteFactory (const XMLNode& node, int version)
1449 boost::shared_ptr<Route> ret;
1451 if (node.name() != "Route") {
1455 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1457 DataType type = DataType::AUDIO;
1458 const XMLProperty* prop = node.property("default-type");
1461 type = DataType (prop->value());
1464 assert (type != DataType::NIL);
1468 boost::shared_ptr<Track> track;
1470 if (type == DataType::AUDIO) {
1471 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1473 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1476 if (track->init()) {
1480 if (track->set_state (node, version)) {
1484 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1485 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1490 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1492 if (r->init () == 0 && r->set_state (node, version) == 0) {
1493 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1494 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1503 boost::shared_ptr<Route>
1504 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1506 boost::shared_ptr<Route> ret;
1508 if (node.name() != "Route") {
1512 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1514 ds_prop = node.property (X_("diskstream"));
1517 DataType type = DataType::AUDIO;
1518 const XMLProperty* prop = node.property("default-type");
1521 type = DataType (prop->value());
1524 assert (type != DataType::NIL);
1528 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1529 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1533 if (i == _diskstreams_2X.end()) {
1534 error << _("Could not find diskstream for route") << endmsg;
1535 return boost::shared_ptr<Route> ();
1538 boost::shared_ptr<Track> track;
1540 if (type == DataType::AUDIO) {
1541 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1543 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1546 if (track->init()) {
1550 if (track->set_state (node, version)) {
1554 track->set_diskstream (*i);
1556 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1557 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1562 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1564 if (r->init () == 0 && r->set_state (node, version) == 0) {
1565 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1566 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1576 Session::load_regions (const XMLNode& node)
1579 XMLNodeConstIterator niter;
1580 boost::shared_ptr<Region> region;
1582 nlist = node.children();
1586 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1587 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1588 error << _("Session: cannot create Region from XML description.");
1589 const XMLProperty *name = (**niter).property("name");
1592 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1603 Session::load_compounds (const XMLNode& node)
1605 XMLNodeList calist = node.children();
1606 XMLNodeConstIterator caiter;
1607 XMLProperty *caprop;
1609 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1610 XMLNode* ca = *caiter;
1614 if ((caprop = ca->property (X_("original"))) == 0) {
1617 orig_id = caprop->value();
1619 if ((caprop = ca->property (X_("copy"))) == 0) {
1622 copy_id = caprop->value();
1624 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1625 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1627 if (!orig || !copy) {
1628 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1634 RegionFactory::add_compound_association (orig, copy);
1641 Session::load_nested_sources (const XMLNode& node)
1644 XMLNodeConstIterator niter;
1646 nlist = node.children();
1648 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1649 if ((*niter)->name() == "Source") {
1651 /* it may already exist, so don't recreate it unnecessarily
1654 XMLProperty* prop = (*niter)->property (X_("id"));
1656 error << _("Nested source has no ID info in session file! (ignored)") << endmsg;
1660 ID source_id (prop->value());
1662 if (!source_by_id (source_id)) {
1665 SourceFactory::create (*this, **niter, true);
1667 catch (failed_constructor& err) {
1668 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1675 boost::shared_ptr<Region>
1676 Session::XMLRegionFactory (const XMLNode& node, bool full)
1678 const XMLProperty* type = node.property("type");
1682 const XMLNodeList& nlist = node.children();
1684 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1685 XMLNode *child = (*niter);
1686 if (child->name() == "NestedSource") {
1687 load_nested_sources (*child);
1691 if (!type || type->value() == "audio") {
1692 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1693 } else if (type->value() == "midi") {
1694 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1697 } catch (failed_constructor& err) {
1698 return boost::shared_ptr<Region> ();
1701 return boost::shared_ptr<Region> ();
1704 boost::shared_ptr<AudioRegion>
1705 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1707 const XMLProperty* prop;
1708 boost::shared_ptr<Source> source;
1709 boost::shared_ptr<AudioSource> as;
1711 SourceList master_sources;
1712 uint32_t nchans = 1;
1715 if (node.name() != X_("Region")) {
1716 return boost::shared_ptr<AudioRegion>();
1719 if ((prop = node.property (X_("channels"))) != 0) {
1720 nchans = atoi (prop->value().c_str());
1723 if ((prop = node.property ("name")) == 0) {
1724 cerr << "no name for this region\n";
1728 if ((prop = node.property (X_("source-0"))) == 0) {
1729 if ((prop = node.property ("source")) == 0) {
1730 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1731 return boost::shared_ptr<AudioRegion>();
1735 PBD::ID s_id (prop->value());
1737 if ((source = source_by_id (s_id)) == 0) {
1738 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1739 return boost::shared_ptr<AudioRegion>();
1742 as = boost::dynamic_pointer_cast<AudioSource>(source);
1744 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1745 return boost::shared_ptr<AudioRegion>();
1748 sources.push_back (as);
1750 /* pickup other channels */
1752 for (uint32_t n=1; n < nchans; ++n) {
1753 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1754 if ((prop = node.property (buf)) != 0) {
1756 PBD::ID id2 (prop->value());
1758 if ((source = source_by_id (id2)) == 0) {
1759 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1760 return boost::shared_ptr<AudioRegion>();
1763 as = boost::dynamic_pointer_cast<AudioSource>(source);
1765 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1766 return boost::shared_ptr<AudioRegion>();
1768 sources.push_back (as);
1772 for (uint32_t n = 0; n < nchans; ++n) {
1773 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1774 if ((prop = node.property (buf)) != 0) {
1776 PBD::ID id2 (prop->value());
1778 if ((source = source_by_id (id2)) == 0) {
1779 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1780 return boost::shared_ptr<AudioRegion>();
1783 as = boost::dynamic_pointer_cast<AudioSource>(source);
1785 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1786 return boost::shared_ptr<AudioRegion>();
1788 master_sources.push_back (as);
1793 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1795 /* a final detail: this is the one and only place that we know how long missing files are */
1797 if (region->whole_file()) {
1798 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1799 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1801 sfp->set_length (region->length());
1806 if (!master_sources.empty()) {
1807 if (master_sources.size() != nchans) {
1808 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1810 region->set_master_sources (master_sources);
1818 catch (failed_constructor& err) {
1819 return boost::shared_ptr<AudioRegion>();
1823 boost::shared_ptr<MidiRegion>
1824 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1826 const XMLProperty* prop;
1827 boost::shared_ptr<Source> source;
1828 boost::shared_ptr<MidiSource> ms;
1831 if (node.name() != X_("Region")) {
1832 return boost::shared_ptr<MidiRegion>();
1835 if ((prop = node.property ("name")) == 0) {
1836 cerr << "no name for this region\n";
1840 if ((prop = node.property (X_("source-0"))) == 0) {
1841 if ((prop = node.property ("source")) == 0) {
1842 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1843 return boost::shared_ptr<MidiRegion>();
1847 PBD::ID s_id (prop->value());
1849 if ((source = source_by_id (s_id)) == 0) {
1850 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1851 return boost::shared_ptr<MidiRegion>();
1854 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1856 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1857 return boost::shared_ptr<MidiRegion>();
1860 sources.push_back (ms);
1863 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1864 /* a final detail: this is the one and only place that we know how long missing files are */
1866 if (region->whole_file()) {
1867 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1868 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1870 sfp->set_length (region->length());
1878 catch (failed_constructor& err) {
1879 return boost::shared_ptr<MidiRegion>();
1884 Session::get_sources_as_xml ()
1887 XMLNode* node = new XMLNode (X_("Sources"));
1888 Glib::Threads::Mutex::Lock lm (source_lock);
1890 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1891 node->add_child_nocopy (i->second->get_state());
1898 Session::path_from_region_name (DataType type, string name, string identifier)
1900 char buf[PATH_MAX+1];
1902 SessionDirectory sdir(get_best_session_directory_for_new_source());
1903 std::string source_dir = ((type == DataType::AUDIO)
1904 ? sdir.sound_path() : sdir.midi_path());
1906 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1908 for (n = 0; n < 999999; ++n) {
1909 if (identifier.length()) {
1910 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1911 identifier.c_str(), n, ext.c_str());
1913 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1917 std::string source_path = Glib::build_filename (source_dir, buf);
1919 if (!Glib::file_test (source_path, Glib::FILE_TEST_EXISTS)) {
1924 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1933 Session::load_sources (const XMLNode& node)
1936 XMLNodeConstIterator niter;
1937 boost::shared_ptr<Source> source;
1939 nlist = node.children();
1943 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1946 if ((source = XMLSourceFactory (**niter)) == 0) {
1947 error << _("Session: cannot create Source from XML description.") << endmsg;
1950 } catch (MissingSource& err) {
1954 if (!no_questions_about_missing_files) {
1955 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1960 switch (user_choice) {
1962 /* user added a new search location, so try again */
1967 /* user asked to quit the entire session load
1972 no_questions_about_missing_files = true;
1976 no_questions_about_missing_files = true;
1981 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1982 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1991 boost::shared_ptr<Source>
1992 Session::XMLSourceFactory (const XMLNode& node)
1994 if (node.name() != "Source") {
1995 return boost::shared_ptr<Source>();
1999 /* note: do peak building in another thread when loading session state */
2000 return SourceFactory::create (*this, node, true);
2003 catch (failed_constructor& err) {
2004 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2005 return boost::shared_ptr<Source>();
2010 Session::save_template (string template_name)
2014 if (_state_of_the_state & CannotSave) {
2018 std::string user_template_dir(user_template_directory());
2020 if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
2021 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2022 user_template_dir, g_strerror (errno)) << endmsg;
2026 tree.set_root (&get_template());
2028 std::string template_dir_path(user_template_dir);
2030 /* directory to put the template in */
2031 template_dir_path = Glib::build_filename (template_dir_path, template_name);
2033 if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
2034 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2035 template_dir_path) << endmsg;
2039 if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
2040 error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
2041 template_dir_path, g_strerror (errno)) << endmsg;
2046 std::string template_file_path(template_dir_path);
2047 template_file_path = Glib::build_filename (template_file_path, template_name + template_suffix);
2049 if (!tree.write (template_file_path)) {
2050 error << _("template not saved") << endmsg;
2054 /* copy plugin state directory */
2056 std::string template_plugin_state_path(template_dir_path);
2057 template_plugin_state_path = Glib::build_filename (template_plugin_state_path, X_("plugins"));
2059 if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
2060 error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
2061 template_plugin_state_path, g_strerror (errno)) << endmsg;
2065 copy_files (plugins_dir(), template_plugin_state_path);
2071 Session::refresh_disk_space ()
2073 #if __APPLE__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
2075 Glib::Threads::Mutex::Lock lm (space_lock);
2077 /* get freespace on every FS that is part of the session path */
2079 _total_free_4k_blocks = 0;
2080 _total_free_4k_blocks_uncertain = false;
2082 for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2084 struct statfs statfsbuf;
2085 statfs (i->path.c_str(), &statfsbuf);
2087 double const scale = statfsbuf.f_bsize / 4096.0;
2089 /* See if this filesystem is read-only */
2090 struct statvfs statvfsbuf;
2091 statvfs (i->path.c_str(), &statvfsbuf);
2093 /* f_bavail can be 0 if it is undefined for whatever
2094 filesystem we are looking at; Samba shares mounted
2095 via GVFS are an example of this.
2097 if (statfsbuf.f_bavail == 0) {
2098 /* block count unknown */
2100 i->blocks_unknown = true;
2101 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2102 /* read-only filesystem */
2104 i->blocks_unknown = false;
2106 /* read/write filesystem with known space */
2107 i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2108 i->blocks_unknown = false;
2111 _total_free_4k_blocks += i->blocks;
2112 if (i->blocks_unknown) {
2113 _total_free_4k_blocks_uncertain = true;
2120 Session::get_best_session_directory_for_new_source ()
2122 vector<space_and_path>::iterator i;
2123 string result = _session_dir->root_path();
2125 /* handle common case without system calls */
2127 if (session_dirs.size() == 1) {
2131 /* OK, here's the algorithm we're following here:
2133 We want to select which directory to use for
2134 the next file source to be created. Ideally,
2135 we'd like to use a round-robin process so as to
2136 get maximum performance benefits from splitting
2137 the files across multiple disks.
2139 However, in situations without much diskspace, an
2140 RR approach may end up filling up a filesystem
2141 with new files while others still have space.
2142 Its therefore important to pay some attention to
2143 the freespace in the filesystem holding each
2144 directory as well. However, if we did that by
2145 itself, we'd keep creating new files in the file
2146 system with the most space until it was as full
2147 as all others, thus negating any performance
2148 benefits of this RAID-1 like approach.
2150 So, we use a user-configurable space threshold. If
2151 there are at least 2 filesystems with more than this
2152 much space available, we use RR selection between them.
2153 If not, then we pick the filesystem with the most space.
2155 This gets a good balance between the two
2159 refresh_disk_space ();
2161 int free_enough = 0;
2163 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2164 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2169 if (free_enough >= 2) {
2170 /* use RR selection process, ensuring that the one
2174 i = last_rr_session_dir;
2177 if (++i == session_dirs.end()) {
2178 i = session_dirs.begin();
2181 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2182 SessionDirectory sdir(i->path);
2183 if (sdir.create ()) {
2185 last_rr_session_dir = i;
2190 } while (i != last_rr_session_dir);
2194 /* pick FS with the most freespace (and that
2195 seems to actually work ...)
2198 vector<space_and_path> sorted;
2199 space_and_path_ascending_cmp cmp;
2201 sorted = session_dirs;
2202 sort (sorted.begin(), sorted.end(), cmp);
2204 for (i = sorted.begin(); i != sorted.end(); ++i) {
2205 SessionDirectory sdir(i->path);
2206 if (sdir.create ()) {
2208 last_rr_session_dir = i;
2218 Session::automation_dir () const
2220 return Glib::build_filename (_path, "automation");
2224 Session::analysis_dir () const
2226 return Glib::build_filename (_path, "analysis");
2230 Session::plugins_dir () const
2232 return Glib::build_filename (_path, "plugins");
2236 Session::externals_dir () const
2238 return Glib::build_filename (_path, "externals");
2242 Session::load_bundles (XMLNode const & node)
2244 XMLNodeList nlist = node.children();
2245 XMLNodeConstIterator niter;
2249 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2250 if ((*niter)->name() == "InputBundle") {
2251 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2252 } else if ((*niter)->name() == "OutputBundle") {
2253 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2255 error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
2264 Session::load_route_groups (const XMLNode& node, int version)
2266 XMLNodeList nlist = node.children();
2267 XMLNodeConstIterator niter;
2271 if (version >= 3000) {
2273 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2274 if ((*niter)->name() == "RouteGroup") {
2275 RouteGroup* rg = new RouteGroup (*this, "");
2276 add_route_group (rg);
2277 rg->set_state (**niter, version);
2281 } else if (version < 3000) {
2283 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2284 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2285 RouteGroup* rg = new RouteGroup (*this, "");
2286 add_route_group (rg);
2287 rg->set_state (**niter, version);
2296 Session::auto_save()
2298 save_state (_current_snapshot_name);
2302 state_file_filter (const string &str, void */*arg*/)
2304 return (str.length() > strlen(statefile_suffix) &&
2305 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2309 bool operator()(const string* a, const string* b) {
2315 remove_end(string* state)
2317 string statename(*state);
2319 string::size_type start,end;
2320 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2321 statename = statename.substr (start+1);
2324 if ((end = statename.rfind(".ardour")) == string::npos) {
2325 end = statename.length();
2328 return new string(statename.substr (0, end));
2332 Session::possible_states (string path)
2334 PathScanner scanner;
2335 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2337 transform(states->begin(), states->end(), states->begin(), remove_end);
2340 sort (states->begin(), states->end(), cmp);
2346 Session::possible_states () const
2348 return possible_states(_path);
2352 Session::add_route_group (RouteGroup* g)
2354 _route_groups.push_back (g);
2355 route_group_added (g); /* EMIT SIGNAL */
2357 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2358 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2359 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2365 Session::remove_route_group (RouteGroup& rg)
2367 list<RouteGroup*>::iterator i;
2369 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2370 _route_groups.erase (i);
2373 route_group_removed (); /* EMIT SIGNAL */
2377 /** Set a new order for our route groups, without adding or removing any.
2378 * @param groups Route group list in the new order.
2381 Session::reorder_route_groups (list<RouteGroup*> groups)
2383 _route_groups = groups;
2385 route_groups_reordered (); /* EMIT SIGNAL */
2391 Session::route_group_by_name (string name)
2393 list<RouteGroup *>::iterator i;
2395 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2396 if ((*i)->name() == name) {
2404 Session::all_route_group() const
2406 return *_all_route_group;
2410 Session::add_commands (vector<Command*> const & cmds)
2412 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2418 Session::begin_reversible_command (const string& name)
2420 begin_reversible_command (g_quark_from_string (name.c_str ()));
2423 /** Begin a reversible command using a GQuark to identify it.
2424 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2425 * but there must be as many begin...()s as there are commit...()s.
2428 Session::begin_reversible_command (GQuark q)
2430 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2431 to hold all the commands that are committed. This keeps the order of
2432 commands correct in the history.
2435 if (_current_trans == 0) {
2436 /* start a new transaction */
2437 assert (_current_trans_quarks.empty ());
2438 _current_trans = new UndoTransaction();
2439 _current_trans->set_name (g_quark_to_string (q));
2442 _current_trans_quarks.push_front (q);
2446 Session::commit_reversible_command (Command *cmd)
2448 assert (_current_trans);
2449 assert (!_current_trans_quarks.empty ());
2454 _current_trans->add_command (cmd);
2457 _current_trans_quarks.pop_front ();
2459 if (!_current_trans_quarks.empty ()) {
2460 /* the transaction we're committing is not the top-level one */
2464 if (_current_trans->empty()) {
2465 /* no commands were added to the transaction, so just get rid of it */
2466 delete _current_trans;
2471 gettimeofday (&now, 0);
2472 _current_trans->set_timestamp (now);
2474 _history.add (_current_trans);
2479 accept_all_audio_files (const string& path, void */*arg*/)
2481 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2485 if (!AudioFileSource::safe_audio_file_extension (path)) {
2493 accept_all_midi_files (const string& path, void */*arg*/)
2495 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2499 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2500 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2501 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2505 accept_all_state_files (const string& path, void */*arg*/)
2507 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2511 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2515 Session::find_all_sources (string path, set<string>& result)
2520 if (!tree.read (path)) {
2524 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2529 XMLNodeConstIterator niter;
2531 nlist = node->children();
2535 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2539 if ((prop = (*niter)->property (X_("type"))) == 0) {
2543 DataType type (prop->value());
2545 if ((prop = (*niter)->property (X_("name"))) == 0) {
2549 if (Glib::path_is_absolute (prop->value())) {
2550 /* external file, ignore */
2558 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2559 result.insert (found_path);
2567 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2569 PathScanner scanner;
2570 vector<string*>* state_files;
2572 string this_snapshot_path;
2578 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2579 ripped = ripped.substr (0, ripped.length() - 1);
2582 state_files = scanner (ripped, accept_all_state_files, (void *) 0, true, true);
2584 if (state_files == 0) {
2589 this_snapshot_path = _path;
2590 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2591 this_snapshot_path += statefile_suffix;
2593 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2595 if (exclude_this_snapshot && **i == this_snapshot_path) {
2599 if (find_all_sources (**i, result) < 0) {
2607 struct RegionCounter {
2608 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2609 AudioSourceList::iterator iter;
2610 boost::shared_ptr<Region> region;
2613 RegionCounter() : count (0) {}
2617 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2619 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2620 return r.get_value_or (1);
2624 Session::cleanup_regions ()
2626 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2628 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2630 uint32_t used = playlists->region_use_count (i->second);
2632 if (used == 0 && !i->second->automatic ()) {
2633 RegionFactory::map_remove (i->second);
2637 /* dump the history list */
2644 Session::cleanup_sources (CleanupReport& rep)
2646 // FIXME: needs adaptation to midi
2648 vector<boost::shared_ptr<Source> > dead_sources;
2649 PathScanner scanner;
2652 vector<space_and_path>::iterator i;
2653 vector<space_and_path>::iterator nexti;
2654 vector<string*>* candidates;
2655 vector<string*>* candidates2;
2656 vector<string> unused;
2657 set<string> all_sources;
2664 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2666 /* consider deleting all unused playlists */
2668 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2673 /* sync the "all regions" property of each playlist with its current state
2676 playlists->sync_all_regions_with_regions ();
2678 /* find all un-used sources */
2683 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2685 SourceMap::iterator tmp;
2690 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2694 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2695 dead_sources.push_back (i->second);
2696 i->second->drop_references ();
2702 /* build a list of all the possible audio directories for the session */
2704 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2709 SessionDirectory sdir ((*i).path);
2710 audio_path += sdir.sound_path();
2712 if (nexti != session_dirs.end()) {
2720 /* build a list of all the possible midi directories for the session */
2722 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2727 SessionDirectory sdir ((*i).path);
2728 midi_path += sdir.midi_path();
2730 if (nexti != session_dirs.end()) {
2737 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2738 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2744 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2745 candidates->push_back (*i);
2750 candidates = candidates2; // might still be null
2753 /* find all sources, but don't use this snapshot because the
2754 state file on disk still references sources we may have already
2758 find_all_sources_across_snapshots (all_sources, true);
2760 /* add our current source list
2763 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2764 boost::shared_ptr<FileSource> fs;
2765 SourceMap::iterator tmp = i;
2768 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2769 if (playlists->source_use_count (fs) != 0) {
2770 all_sources.insert (fs->path());
2773 /* we might not remove this source from disk, because it may be used
2774 by other snapshots, but its not being used in this version
2775 so lets get rid of it now, along with any representative regions
2779 RegionFactory::remove_regions_using_source (i->second);
2788 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2793 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2795 tmppath1 = canonical_path (spath);
2796 tmppath2 = canonical_path ((*i));
2798 if (tmppath1 == tmppath2) {
2805 unused.push_back (spath);
2814 /* now try to move all unused files into the "dead" directory(ies) */
2816 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2817 struct stat statbuf;
2821 /* don't move the file across filesystems, just
2822 stick it in the `dead_dir_name' directory
2823 on whichever filesystem it was already on.
2826 if ((*x).find ("/sounds/") != string::npos) {
2828 /* old school, go up 1 level */
2830 newpath = Glib::path_get_dirname (*x); // "sounds"
2831 newpath = Glib::path_get_dirname (newpath); // "session-name"
2835 /* new school, go up 4 levels */
2837 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2838 newpath = Glib::path_get_dirname (newpath); // "session-name"
2839 newpath = Glib::path_get_dirname (newpath); // "interchange"
2840 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2843 newpath = Glib::build_filename (newpath, dead_dir_name);
2845 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2846 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2850 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2852 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2854 /* the new path already exists, try versioning */
2856 char buf[PATH_MAX+1];
2860 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2863 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2864 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2868 if (version == 999) {
2869 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2873 newpath = newpath_v;
2878 /* it doesn't exist, or we can't read it or something */
2882 stat ((*x).c_str(), &statbuf);
2884 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2885 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2886 (*x), newpath, strerror (errno))
2891 /* see if there an easy to find peakfile for this file, and remove it.
2894 string base = basename_nosuffix (*x);
2895 base += "%A"; /* this is what we add for the channel suffix of all native files,
2896 or for the first channel of embedded files. it will miss
2897 some peakfiles for other channels
2899 string peakpath = peak_path (base);
2901 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2902 if (::unlink (peakpath.c_str()) != 0) {
2903 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2904 peakpath, _path, strerror (errno))
2906 /* try to back out */
2907 ::rename (newpath.c_str(), _path.c_str());
2912 rep.paths.push_back (*x);
2913 rep.space += statbuf.st_size;
2916 /* dump the history list */
2920 /* save state so we don't end up a session file
2921 referring to non-existent sources.
2928 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2934 Session::cleanup_trash_sources (CleanupReport& rep)
2936 // FIXME: needs adaptation for MIDI
2938 vector<space_and_path>::iterator i;
2944 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2946 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2948 clear_directory (dead_dir, &rep.space, &rep.paths);
2955 Session::set_dirty ()
2957 bool was_dirty = dirty();
2959 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2963 DirtyChanged(); /* EMIT SIGNAL */
2969 Session::set_clean ()
2971 bool was_dirty = dirty();
2973 _state_of_the_state = Clean;
2977 DirtyChanged(); /* EMIT SIGNAL */
2982 Session::set_deletion_in_progress ()
2984 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2988 Session::clear_deletion_in_progress ()
2990 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2994 Session::add_controllable (boost::shared_ptr<Controllable> c)
2996 /* this adds a controllable to the list managed by the Session.
2997 this is a subset of those managed by the Controllable class
2998 itself, and represents the only ones whose state will be saved
2999 as part of the session.
3002 Glib::Threads::Mutex::Lock lm (controllables_lock);
3003 controllables.insert (c);
3006 struct null_deleter { void operator()(void const *) const {} };
3009 Session::remove_controllable (Controllable* c)
3011 if (_state_of_the_state & Deletion) {
3015 Glib::Threads::Mutex::Lock lm (controllables_lock);
3017 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3019 if (x != controllables.end()) {
3020 controllables.erase (x);
3024 boost::shared_ptr<Controllable>
3025 Session::controllable_by_id (const PBD::ID& id)
3027 Glib::Threads::Mutex::Lock lm (controllables_lock);
3029 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3030 if ((*i)->id() == id) {
3035 return boost::shared_ptr<Controllable>();
3038 boost::shared_ptr<Controllable>
3039 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3041 boost::shared_ptr<Controllable> c;
3042 boost::shared_ptr<Route> r;
3044 switch (desc.top_level_type()) {
3045 case ControllableDescriptor::NamedRoute:
3047 std::string str = desc.top_level_name();
3048 if (str == "master") {
3050 } else if (str == "control" || str == "listen") {
3053 r = route_by_name (desc.top_level_name());
3058 case ControllableDescriptor::RemoteControlID:
3059 r = route_by_remote_id (desc.rid());
3067 switch (desc.subtype()) {
3068 case ControllableDescriptor::Gain:
3069 c = r->gain_control ();
3072 case ControllableDescriptor::Solo:
3073 c = r->solo_control();
3076 case ControllableDescriptor::Mute:
3077 c = r->mute_control();
3080 case ControllableDescriptor::Recenable:
3082 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3085 c = t->rec_enable_control ();
3090 case ControllableDescriptor::PanDirection:
3092 c = r->pannable()->pan_azimuth_control;
3096 case ControllableDescriptor::PanWidth:
3098 c = r->pannable()->pan_width_control;
3102 case ControllableDescriptor::PanElevation:
3104 c = r->pannable()->pan_elevation_control;
3108 case ControllableDescriptor::Balance:
3109 /* XXX simple pan control */
3112 case ControllableDescriptor::PluginParameter:
3114 uint32_t plugin = desc.target (0);
3115 uint32_t parameter_index = desc.target (1);
3117 /* revert to zero based counting */
3123 if (parameter_index > 0) {
3127 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3130 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3131 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3136 case ControllableDescriptor::SendGain:
3138 uint32_t send = desc.target (0);
3140 /* revert to zero-based counting */
3146 boost::shared_ptr<Processor> p = r->nth_send (send);
3149 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3150 boost::shared_ptr<Amp> a = s->amp();
3153 c = s->amp()->gain_control();
3160 /* relax and return a null pointer */
3168 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3171 Stateful::add_instant_xml (node, _path);
3174 if (write_to_config) {
3175 Config->add_instant_xml (node);
3180 Session::instant_xml (const string& node_name)
3182 return Stateful::instant_xml (node_name, _path);
3186 Session::save_history (string snapshot_name)
3194 if (snapshot_name.empty()) {
3195 snapshot_name = _current_snapshot_name;
3198 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3199 const string backup_filename = history_filename + backup_suffix;
3200 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3201 const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3203 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3204 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3205 error << _("could not backup old history file, current history not saved") << endmsg;
3210 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3214 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3216 if (!tree.write (xml_path))
3218 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3220 if (g_remove (xml_path.c_str()) != 0) {
3221 error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3222 xml_path, g_strerror (errno)) << endmsg;
3224 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3225 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3226 backup_path, g_strerror (errno)) << endmsg;
3236 Session::restore_history (string snapshot_name)
3240 if (snapshot_name.empty()) {
3241 snapshot_name = _current_snapshot_name;
3244 const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3245 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3247 info << "Loading history from " << xml_path << endmsg;
3249 if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3250 info << string_compose (_("%1: no history file \"%2\" for this session."),
3251 _name, xml_path) << endmsg;
3255 if (!tree.read (xml_path)) {
3256 error << string_compose (_("Could not understand session history file \"%1\""),
3257 xml_path) << endmsg;
3264 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3267 UndoTransaction* ut = new UndoTransaction ();
3270 ut->set_name(t->property("name")->value());
3271 stringstream ss(t->property("tv-sec")->value());
3273 ss.str(t->property("tv-usec")->value());
3275 ut->set_timestamp(tv);
3277 for (XMLNodeConstIterator child_it = t->children().begin();
3278 child_it != t->children().end(); child_it++)
3280 XMLNode *n = *child_it;
3283 if (n->name() == "MementoCommand" ||
3284 n->name() == "MementoUndoCommand" ||
3285 n->name() == "MementoRedoCommand") {
3287 if ((c = memento_command_factory(n))) {
3291 } else if (n->name() == "NoteDiffCommand") {
3292 PBD::ID id (n->property("midi-source")->value());
3293 boost::shared_ptr<MidiSource> midi_source =
3294 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3296 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3298 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3301 } else if (n->name() == "SysExDiffCommand") {
3303 PBD::ID id (n->property("midi-source")->value());
3304 boost::shared_ptr<MidiSource> midi_source =
3305 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3307 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3309 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3312 } else if (n->name() == "PatchChangeDiffCommand") {
3314 PBD::ID id (n->property("midi-source")->value());
3315 boost::shared_ptr<MidiSource> midi_source =
3316 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3318 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3320 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3323 } else if (n->name() == "StatefulDiffCommand") {
3324 if ((c = stateful_diff_command_factory (n))) {
3325 ut->add_command (c);
3328 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3339 Session::config_changed (std::string p, bool ours)
3345 if (p == "seamless-loop") {
3347 } else if (p == "rf-speed") {
3349 } else if (p == "auto-loop") {
3351 } else if (p == "auto-input") {
3353 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3354 /* auto-input only makes a difference if we're rolling */
3355 set_track_monitor_input_status (!config.get_auto_input());
3358 } else if (p == "punch-in") {
3362 if ((location = _locations->auto_punch_location()) != 0) {
3364 if (config.get_punch_in ()) {
3365 replace_event (SessionEvent::PunchIn, location->start());
3367 remove_event (location->start(), SessionEvent::PunchIn);
3371 } else if (p == "punch-out") {
3375 if ((location = _locations->auto_punch_location()) != 0) {
3377 if (config.get_punch_out()) {
3378 replace_event (SessionEvent::PunchOut, location->end());
3380 clear_events (SessionEvent::PunchOut);
3384 } else if (p == "edit-mode") {
3386 Glib::Threads::Mutex::Lock lm (playlists->lock);
3388 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3389 (*i)->set_edit_mode (Config->get_edit_mode ());
3392 } else if (p == "use-video-sync") {
3394 waiting_for_sync_offset = config.get_use_video_sync();
3396 } else if (p == "mmc-control") {
3398 //poke_midi_thread ();
3400 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3402 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3404 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3406 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3408 } else if (p == "midi-control") {
3410 //poke_midi_thread ();
3412 } else if (p == "raid-path") {
3414 setup_raid_path (config.get_raid_path());
3416 } else if (p == "timecode-format") {
3420 } else if (p == "video-pullup") {
3424 } else if (p == "seamless-loop") {
3426 if (play_loop && transport_rolling()) {
3427 // to reset diskstreams etc
3428 request_play_loop (true);
3431 } else if (p == "rf-speed") {
3433 cumulative_rf_motion = 0;
3436 } else if (p == "click-sound") {
3438 setup_click_sounds (1);
3440 } else if (p == "click-emphasis-sound") {
3442 setup_click_sounds (-1);
3444 } else if (p == "clicking") {
3446 if (Config->get_clicking()) {
3447 if (_click_io && click_data) { // don't require emphasis data
3454 } else if (p == "click-gain") {
3457 _click_gain->set_gain (Config->get_click_gain(), this);
3460 } else if (p == "send-mtc") {
3462 if (Config->get_send_mtc ()) {
3463 /* mark us ready to send */
3464 next_quarter_frame_to_send = 0;
3467 } else if (p == "send-mmc") {
3469 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3471 } else if (p == "midi-feedback") {
3473 session_midi_feedback = Config->get_midi_feedback();
3475 } else if (p == "jack-time-master") {
3477 engine().reset_timebase ();
3479 } else if (p == "native-file-header-format") {
3481 if (!first_file_header_format_reset) {
3482 reset_native_file_format ();
3485 first_file_header_format_reset = false;
3487 } else if (p == "native-file-data-format") {
3489 if (!first_file_data_format_reset) {
3490 reset_native_file_format ();
3493 first_file_data_format_reset = false;
3495 } else if (p == "external-sync") {
3496 if (!config.get_external_sync()) {
3497 drop_sync_source ();
3499 switch_to_sync_source (Config->get_sync_source());
3501 } else if (p == "denormal-model") {
3503 } else if (p == "history-depth") {
3504 set_history_depth (Config->get_history_depth());
3505 } else if (p == "remote-model") {
3506 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
3509 } else if (p == "sync-all-route-ordering") {
3511 /* sync to editor order unless mixer is used for remote IDs
3514 switch (Config->get_remote_model()) {
3516 sync_order_keys (EditorSort);
3519 sync_order_keys (EditorSort);
3522 sync_order_keys (MixerSort);
3525 } else if (p == "initial-program-change") {
3527 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3530 buf[0] = MIDI::program; // channel zero by default
3531 buf[1] = (Config->get_initial_program_change() & 0x7f);
3533 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3535 } else if (p == "solo-mute-override") {
3536 // catch_up_on_solo_mute_override ();
3537 } else if (p == "listen-position" || p == "pfl-position") {
3538 listen_position_changed ();
3539 } else if (p == "solo-control-is-listen-control") {
3540 solo_control_mode_changed ();
3541 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3542 last_timecode_valid = false;
3543 } else if (p == "playback-buffer-seconds") {
3544 AudioSource::allocate_working_buffers (frame_rate());
3545 } else if (p == "automation-thinning-factor") {
3546 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3547 } else if (p == "ltc-source-port") {
3548 reconnect_ltc_input ();
3549 } else if (p == "ltc-sink-port") {
3550 reconnect_ltc_output ();
3551 } else if (p == "timecode-generator-offset") {
3552 ltc_tx_parse_offset();
3559 Session::set_history_depth (uint32_t d)
3561 _history.set_depth (d);
3565 Session::load_diskstreams_2X (XMLNode const & node, int)
3568 XMLNodeConstIterator citer;
3570 clist = node.children();
3572 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3575 /* diskstreams added automatically by DiskstreamCreated handler */
3576 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3577 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3578 _diskstreams_2X.push_back (dsp);
3580 error << _("Session: unknown diskstream type in XML") << endmsg;
3584 catch (failed_constructor& err) {
3585 error << _("Session: could not load diskstream via XML state") << endmsg;
3593 /** Connect things to the MMC object */
3595 Session::setup_midi_machine_control ()
3597 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3599 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3600 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3601 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3602 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3603 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3604 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3605 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3606 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3607 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3608 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3609 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3610 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3611 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3613 /* also handle MIDI SPP because its so common */
3615 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3616 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3617 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3620 boost::shared_ptr<Controllable>
3621 Session::solo_cut_control() const
3623 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3624 controls in Ardour that currently get presented to the user in the GUI that require
3625 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3627 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3628 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3632 return _solo_cut_control;
3636 Session::rename (const std::string& new_name)
3638 string legal_name = legalize_for_path (new_name);
3644 string const old_sources_root = _session_dir->sources_root();
3646 #define RENAME ::rename
3651 * interchange subdirectory
3655 * Backup files are left unchanged and not renamed.
3658 /* pass one: not 100% safe check that the new directory names don't
3662 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3667 /* this is a stupid hack because Glib::path_get_dirname() is
3668 * lexical-only, and so passing it /a/b/c/ gives a different
3669 * result than passing it /a/b/c ...
3672 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3673 oldstr = oldstr.substr (0, oldstr.length() - 1);
3676 string base = Glib::path_get_dirname (oldstr);
3677 string p = Glib::path_get_basename (oldstr);
3679 newstr = Glib::build_filename (base, legal_name);
3681 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3688 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3693 /* this is a stupid hack because Glib::path_get_dirname() is
3694 * lexical-only, and so passing it /a/b/c/ gives a different
3695 * result than passing it /a/b/c ...
3698 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3699 oldstr = oldstr.substr (0, oldstr.length() - 1);
3702 string base = Glib::path_get_dirname (oldstr);
3703 string p = Glib::path_get_basename (oldstr);
3705 newstr = Glib::build_filename (base, legal_name);
3707 cerr << "Rename " << oldstr << " => " << newstr << endl;
3709 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3714 (*_session_dir) = newstr;
3719 /* directory below interchange */
3721 v.push_back (newstr);
3722 v.push_back (interchange_dir_name);
3725 oldstr = Glib::build_filename (v);
3728 v.push_back (newstr);
3729 v.push_back (interchange_dir_name);
3730 v.push_back (legal_name);
3732 newstr = Glib::build_filename (v);
3734 cerr << "Rename " << oldstr << " => " << newstr << endl;
3736 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3743 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3744 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3746 cerr << "Rename " << oldstr << " => " << newstr << endl;
3748 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3755 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3757 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3758 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3760 cerr << "Rename " << oldstr << " => " << newstr << endl;
3762 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3767 /* update file source paths */
3769 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3770 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3772 string p = fs->path ();
3773 boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3778 /* remove old name from recent sessions */
3780 remove_recent_sessions (_path);
3783 _current_snapshot_name = new_name;
3788 /* save state again to get everything just right */
3790 save_state (_current_snapshot_name);
3793 /* add to recent sessions */
3795 store_recent_sessions (new_name, _path);