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 */
44 #include <sys/param.h>
45 #include <sys/mount.h>
48 #ifdef HAVE_SYS_STATVFS_H
49 #include <sys/statvfs.h>
53 #include <glib/gstdio.h>
56 #include <glibmm/threads.h>
58 #include <boost/algorithm/string.hpp>
60 #include "midi++/mmc.h"
61 #include "midi++/port.h"
62 #include "midi++/manager.h"
64 #include "evoral/SMF.hpp"
66 #include "pbd/boost_debug.h"
67 #include "pbd/basename.h"
68 #include "pbd/controllable_descriptor.h"
69 #include "pbd/enumwriter.h"
70 #include "pbd/error.h"
71 #include "pbd/file_utils.h"
72 #include "pbd/pathexpand.h"
73 #include "pbd/pathscanner.h"
74 #include "pbd/pthread_utils.h"
75 #include "pbd/stacktrace.h"
76 #include "pbd/convert.h"
77 #include "pbd/clear_dir.h"
78 #include "pbd/localtime_r.h"
80 #include "ardour/amp.h"
81 #include "ardour/audio_diskstream.h"
82 #include "ardour/audio_track.h"
83 #include "ardour/audioengine.h"
84 #include "ardour/audiofilesource.h"
85 #include "ardour/audioregion.h"
86 #include "ardour/automation_control.h"
87 #include "ardour/butler.h"
88 #include "ardour/control_protocol_manager.h"
89 #include "ardour/directory_names.h"
90 #include "ardour/filename_extensions.h"
91 #include "ardour/location.h"
92 #include "ardour/midi_model.h"
93 #include "ardour/midi_patch_manager.h"
94 #include "ardour/midi_region.h"
95 #include "ardour/midi_source.h"
96 #include "ardour/midi_track.h"
97 #include "ardour/pannable.h"
98 #include "ardour/playlist_factory.h"
99 #include "ardour/port.h"
100 #include "ardour/processor.h"
101 #include "ardour/proxy_controllable.h"
102 #include "ardour/recent_sessions.h"
103 #include "ardour/region_factory.h"
104 #include "ardour/route_group.h"
105 #include "ardour/send.h"
106 #include "ardour/session.h"
107 #include "ardour/session_directory.h"
108 #include "ardour/session_metadata.h"
109 #include "ardour/session_playlists.h"
110 #include "ardour/session_state_utils.h"
111 #include "ardour/silentfilesource.h"
112 #include "ardour/sndfilesource.h"
113 #include "ardour/source_factory.h"
114 #include "ardour/speakers.h"
115 #include "ardour/template_utils.h"
116 #include "ardour/tempo.h"
117 #include "ardour/ticker.h"
118 #include "ardour/user_bundle.h"
120 #include "control_protocol/control_protocol.h"
126 using namespace ARDOUR;
129 /** @param snapshot_name Snapshot name, without the .ardour prefix */
131 Session::first_stage_init (string fullpath, string snapshot_name)
133 if (fullpath.length() == 0) {
135 throw failed_constructor();
138 _path = canonical_path (fullpath);
140 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
141 _path += G_DIR_SEPARATOR;
144 /* these two are just provisional settings. set_state()
145 will likely override them.
148 _name = _current_snapshot_name = snapshot_name;
150 set_history_depth (Config->get_history_depth());
152 _current_frame_rate = _engine.frame_rate ();
153 _nominal_frame_rate = _current_frame_rate;
154 _base_frame_rate = _current_frame_rate;
156 _tempo_map = new TempoMap (_current_frame_rate);
157 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
160 _non_soloed_outs_muted = false;
162 _solo_isolated_cnt = 0;
163 g_atomic_int_set (&processing_prohibited, 0);
164 _transport_speed = 0;
165 _default_transport_speed = 1.0;
166 _last_transport_speed = 0;
167 _target_transport_speed = 0;
168 auto_play_legal = false;
169 transport_sub_state = 0;
170 _transport_frame = 0;
171 _requested_return_frame = -1;
172 _session_range_location = 0;
173 g_atomic_int_set (&_record_status, Disabled);
174 loop_changing = false;
177 _last_roll_location = 0;
178 _last_roll_or_reversal_location = 0;
179 _last_record_location = 0;
180 pending_locate_frame = 0;
181 pending_locate_roll = false;
182 pending_locate_flush = false;
183 state_was_pending = false;
185 outbound_mtc_timecode_frame = 0;
186 next_quarter_frame_to_send = -1;
187 current_block_size = 0;
188 solo_update_disabled = false;
189 _have_captured = false;
190 _worst_output_latency = 0;
191 _worst_input_latency = 0;
192 _worst_track_latency = 0;
193 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
194 _was_seamless = Config->get_seamless_loop ();
196 _send_qf_mtc = false;
197 _pframes_since_last_mtc = 0;
198 g_atomic_int_set (&_playback_load, 100);
199 g_atomic_int_set (&_capture_load, 100);
202 pending_abort = false;
203 _adding_routes_in_progress = false;
204 destructive_index = 0;
205 first_file_data_format_reset = true;
206 first_file_header_format_reset = true;
207 post_export_sync = false;
210 no_questions_about_missing_files = false;
211 _speakers.reset (new Speakers);
213 ignore_route_processor_changes = false;
214 _pre_export_mmc_enabled = false;
216 AudioDiskstream::allocate_working_buffers();
218 /* default short fade = 15ms */
220 SndFileSource::setup_standard_crossfades (*this, frame_rate());
222 last_mmc_step.tv_sec = 0;
223 last_mmc_step.tv_usec = 0;
226 /* click sounds are unset by default, which causes us to internal
227 waveforms for clicks.
231 click_emphasis_length = 0;
234 process_function = &Session::process_with_events;
236 if (config.get_use_video_sync()) {
237 waiting_for_sync_offset = true;
239 waiting_for_sync_offset = false;
242 last_timecode_when = 0;
243 last_timecode_valid = false;
247 last_rr_session_dir = session_dirs.begin();
248 refresh_disk_space ();
250 /* default: assume simple stereo speaker configuration */
252 _speakers->setup_default_speakers (2);
256 average_slave_delta = 1800; // !!! why 1800 ????
257 have_first_delta_accumulator = false;
258 delta_accumulator_cnt = 0;
259 _slave_state = Stopped;
261 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
262 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
263 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
264 add_controllable (_solo_cut_control);
266 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
268 /* These are all static "per-class" signals */
270 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
271 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
272 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
273 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
274 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
276 /* stop IO objects from doing stuff until we're ready for them */
278 Delivery::disable_panners ();
279 IO::disable_connecting ();
283 Session::second_stage_init ()
285 AudioFileSource::set_peak_dir (_session_dir->peak_path());
288 if (load_state (_current_snapshot_name)) {
293 if (_butler->start_thread()) {
297 if (start_midi_thread ()) {
301 setup_midi_machine_control ();
303 // set_state() will call setup_raid_path(), but if it's a new session we need
304 // to call setup_raid_path() here.
307 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
311 setup_raid_path(_path);
314 /* we can't save till after ::when_engine_running() is called,
315 because otherwise we save state with no connections made.
316 therefore, we reset _state_of_the_state because ::set_state()
317 will have cleared it.
319 we also have to include Loading so that any events that get
320 generated between here and the end of ::when_engine_running()
321 will be processed directly rather than queued.
324 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
326 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
327 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
328 setup_click_sounds (0);
329 setup_midi_control ();
331 /* Pay attention ... */
333 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
334 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
336 midi_clock = new MidiClockTicker ();
337 midi_clock->set_session (this);
340 when_engine_running ();
343 /* handle this one in a different way than all others, so that its clear what happened */
345 catch (AudioEngine::PortRegistrationFailure& err) {
346 error << err.what() << endmsg;
354 BootMessage (_("Reset Remote Controls"));
356 send_full_time_code (0);
357 _engine.transport_locate (0);
359 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
360 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
362 MIDI::Name::MidiPatchManager::instance().set_session (this);
365 /* initial program change will be delivered later; see ::config_changed() */
367 _state_of_the_state = Clean;
369 Port::set_connecting_blocked (false);
371 DirtyChanged (); /* EMIT SIGNAL */
373 if (state_was_pending) {
374 save_state (_current_snapshot_name);
375 remove_pending_capture_state ();
376 state_was_pending = false;
379 BootMessage (_("Session loading complete"));
385 Session::raid_path () const
387 SearchPath raid_search_path;
389 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
390 raid_search_path += (*i).path;
393 return raid_search_path.to_string ();
397 Session::setup_raid_path (string path)
406 session_dirs.clear ();
408 SearchPath search_path(path);
409 SearchPath sound_search_path;
410 SearchPath midi_search_path;
412 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
414 sp.blocks = 0; // not needed
415 session_dirs.push_back (sp);
417 SessionDirectory sdir(sp.path);
419 sound_search_path += sdir.sound_path ();
420 midi_search_path += sdir.midi_path ();
423 // reset the round-robin soundfile path thingie
424 last_rr_session_dir = session_dirs.begin();
428 Session::path_is_within_session (const std::string& path)
430 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
431 if (PBD::path_is_within (i->path, path)) {
439 Session::ensure_subdirs ()
443 dir = session_directory().peak_path();
445 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
446 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
450 dir = session_directory().sound_path();
452 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
453 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
457 dir = session_directory().midi_path();
459 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
460 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
464 dir = session_directory().dead_path();
466 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
467 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
471 dir = session_directory().export_path();
473 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
474 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
478 dir = analysis_dir ();
480 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
481 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
485 dir = plugins_dir ();
487 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
488 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
492 dir = externals_dir ();
494 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
495 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
502 /** @param session_template directory containing session template, or empty.
503 * Caller must not hold process lock.
506 Session::create (const string& session_template, BusProfile* bus_profile)
508 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
509 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
513 if (ensure_subdirs ()) {
517 _writable = exists_and_writable (_path);
519 if (!session_template.empty()) {
520 std::string in_path = session_template_dir_to_file (session_template);
522 ifstream in(in_path.c_str());
525 string out_path = _path;
527 out_path += statefile_suffix;
529 ofstream out(out_path.c_str());
535 /* Copy plugin state files from template to new session */
536 std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
537 copy_files (template_plugins, plugins_dir ());
542 error << string_compose (_("Could not open %1 for writing session template"), out_path)
548 error << string_compose (_("Could not open session template %1 for reading"), in_path)
555 /* set initial start + end point */
557 _state_of_the_state = Clean;
559 /* set up Master Out and Control Out if necessary */
564 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
566 if (bus_profile->master_out_channels) {
567 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
571 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
572 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
575 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
576 r->input()->ensure_io (count, false, this);
577 r->output()->ensure_io (count, false, this);
583 /* prohibit auto-connect to master, because there isn't one */
584 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
588 add_routes (rl, false, false, false);
591 /* this allows the user to override settings with an environment variable.
594 if (no_auto_connect()) {
595 bus_profile->input_ac = AutoConnectOption (0);
596 bus_profile->output_ac = AutoConnectOption (0);
599 Config->set_input_auto_connect (bus_profile->input_ac);
600 Config->set_output_auto_connect (bus_profile->output_ac);
603 if (Config->get_use_monitor_bus() && bus_profile) {
604 add_monitor_section ();
613 Session::maybe_write_autosave()
615 if (dirty() && record_status() != Recording) {
616 save_state("", true);
621 Session::remove_pending_capture_state ()
623 std::string pending_state_file_path(_session_dir->root_path());
625 pending_state_file_path = Glib::build_filename (pending_state_file_path, legalize_for_path (_current_snapshot_name) + pending_suffix);
627 if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS)) return;
629 if (g_remove (pending_state_file_path.c_str()) != 0) {
630 error << string_compose(_("Could not remove pending capture state at path \"%1\" (%2)"),
631 pending_state_file_path, g_strerror (errno)) << endmsg;
635 /** Rename a state file.
636 * @param old_name Old snapshot name.
637 * @param new_name New snapshot name.
640 Session::rename_state (string old_name, string new_name)
642 if (old_name == _current_snapshot_name || old_name == _name) {
643 /* refuse to rename the current snapshot or the "main" one */
647 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
648 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
650 const std::string old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
651 const std::string new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
653 if (::g_rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
654 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
655 old_name, new_name, g_strerror(errno)) << endmsg;
659 /** Remove a state file.
660 * @param snapshot_name Snapshot name.
663 Session::remove_state (string snapshot_name)
665 if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
666 // refuse to remove the current snapshot or the "main" one
670 std::string xml_path(_session_dir->root_path());
672 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
674 if (!create_backup_file (xml_path)) {
675 // don't remove it if a backup can't be made
676 // create_backup_file will log the error.
681 if (g_remove (xml_path.c_str()) != 0) {
682 error << string_compose(_("Could not remove session file at path \"%1\" (%2)"),
683 xml_path, g_strerror (errno)) << endmsg;
687 #ifdef HAVE_JACK_SESSION
689 Session::jack_session_event (jack_session_event_t * event)
691 char timebuf[128], *tmp;
693 struct tm local_time;
696 localtime_r (&n, &local_time);
697 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
699 while ((tmp = strchr(timebuf, ':'))) { *tmp = '.'; }
701 if (event->type == JackSessionSaveTemplate)
703 if (save_template( timebuf )) {
704 event->flags = JackSessionSaveError;
706 string cmd ("ardour3 -P -U ");
707 cmd += event->client_uuid;
711 event->command_line = strdup (cmd.c_str());
716 if (save_state (timebuf)) {
717 event->flags = JackSessionSaveError;
719 std::string xml_path (_session_dir->root_path());
720 std::string legalized_filename = legalize_for_path (timebuf) + statefile_suffix;
721 xml_path = Glib::build_filename (xml_path, legalized_filename);
723 string cmd ("ardour3 -P -U ");
724 cmd += event->client_uuid;
729 event->command_line = strdup (cmd.c_str());
733 jack_session_reply (_engine.jack(), event);
735 if (event->type == JackSessionSaveAndQuit) {
736 Quit (); /* EMIT SIGNAL */
739 jack_session_event_free( event );
743 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
745 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
748 std::string xml_path(_session_dir->root_path());
750 if (!_writable || (_state_of_the_state & CannotSave)) {
754 if (!_engine.connected ()) {
755 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
761 /* tell sources we're saving first, in case they write out to a new file
762 * which should be saved with the state rather than the old one */
763 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
765 i->second->session_saved();
766 } catch (Evoral::SMF::FileError& e) {
767 error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
771 SaveSession (); /* EMIT SIGNAL */
773 tree.set_root (&get_state());
775 if (snapshot_name.empty()) {
776 snapshot_name = _current_snapshot_name;
777 } else if (switch_to_snapshot) {
778 _current_snapshot_name = snapshot_name;
783 /* proper save: use statefile_suffix (.ardour in English) */
785 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
787 /* make a backup copy of the old file */
789 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) {
790 // create_backup_file will log the error
796 /* pending save: use pending_suffix (.pending in English) */
797 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
800 std::string tmp_path(_session_dir->root_path());
801 tmp_path = Glib::build_filename (tmp_path, legalize_for_path (snapshot_name) + temp_suffix);
803 // cerr << "actually writing state to " << xml_path << endl;
805 if (!tree.write (tmp_path)) {
806 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
807 if (g_remove (tmp_path.c_str()) != 0) {
808 error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
809 tmp_path, g_strerror (errno)) << endmsg;
815 if (::g_rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
816 error << string_compose (_("could not rename temporary session file %1 to %2 (%3)"),
817 tmp_path, xml_path, g_strerror(errno)) << endmsg;
818 if (g_remove (tmp_path.c_str()) != 0) {
819 error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
820 tmp_path, g_strerror (errno)) << endmsg;
828 save_history (snapshot_name);
830 bool was_dirty = dirty();
832 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
835 DirtyChanged (); /* EMIT SIGNAL */
838 StateSaved (snapshot_name); /* EMIT SIGNAL */
845 Session::restore_state (string snapshot_name)
847 if (load_state (snapshot_name) == 0) {
848 set_state (*state_tree->root(), Stateful::loading_state_version);
855 Session::load_state (string snapshot_name)
860 state_was_pending = false;
862 /* check for leftover pending state from a crashed capture attempt */
864 std::string xmlpath(_session_dir->root_path());
865 xmlpath = Glib::build_filename (xmlpath, legalize_for_path (snapshot_name) + pending_suffix);
867 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
869 /* there is pending state from a crashed capture attempt */
871 boost::optional<int> r = AskAboutPendingState();
872 if (r.get_value_or (1)) {
873 state_was_pending = true;
877 if (!state_was_pending) {
878 xmlpath = Glib::build_filename (_session_dir->root_path(), snapshot_name);
881 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
882 xmlpath = Glib::build_filename (_session_dir->root_path(), legalize_for_path (snapshot_name) + statefile_suffix);
883 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
884 error << string_compose(_("%1: session file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
889 state_tree = new XMLTree;
893 _writable = exists_and_writable (xmlpath);
895 if (!state_tree->read (xmlpath)) {
896 error << string_compose(_("Could not understand session file %1"), xmlpath) << endmsg;
902 XMLNode& root (*state_tree->root());
904 if (root.name() != X_("Session")) {
905 error << string_compose (_("Session file %1 is not a session"), xmlpath) << endmsg;
911 const XMLProperty* prop;
913 if ((prop = root.property ("version")) == 0) {
914 /* no version implies very old version of Ardour */
915 Stateful::loading_state_version = 1000;
917 if (prop->value().find ('.') != string::npos) {
918 /* old school version format */
919 if (prop->value()[0] == '2') {
920 Stateful::loading_state_version = 2000;
922 Stateful::loading_state_version = 3000;
925 Stateful::loading_state_version = atoi (prop->value());
929 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
931 std::string backup_path(_session_dir->root_path());
932 std::string backup_filename = string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
933 backup_path = Glib::build_filename (backup_path, backup_filename);
935 // only create a backup for a given statefile version once
937 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
939 VersionMismatch (xmlpath, backup_path);
941 if (!copy_file (xmlpath, backup_path)) {;
951 Session::load_options (const XMLNode& node)
953 LocaleGuard lg (X_("POSIX"));
954 config.set_variables (node);
965 Session::get_template()
967 /* if we don't disable rec-enable, diskstreams
968 will believe they need to store their capture
969 sources in their state node.
972 disable_record (false);
978 Session::state (bool full_state)
980 XMLNode* node = new XMLNode("Session");
984 snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
985 node->add_property("version", buf);
987 /* store configuration settings */
991 node->add_property ("name", _name);
992 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
993 node->add_property ("sample-rate", buf);
995 if (session_dirs.size() > 1) {
999 vector<space_and_path>::iterator i = session_dirs.begin();
1000 vector<space_and_path>::iterator next;
1002 ++i; /* skip the first one */
1006 while (i != session_dirs.end()) {
1010 if (next != session_dirs.end()) {
1020 child = node->add_child ("Path");
1021 child->add_content (p);
1025 /* save the ID counter */
1027 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1028 node->add_property ("id-counter", buf);
1030 /* save the event ID counter */
1032 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1033 node->add_property ("event-counter", buf);
1035 /* various options */
1037 node->add_child_nocopy (config.get_variables ());
1039 node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
1041 child = node->add_child ("Sources");
1044 Glib::Threads::Mutex::Lock sl (source_lock);
1046 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1048 /* Don't save information about non-file Sources, or
1049 * about non-destructive file sources that are empty
1050 * and unused by any regions.
1053 boost::shared_ptr<FileSource> fs;
1055 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1057 if (!fs->destructive()) {
1058 if (fs->empty() && !fs->used()) {
1063 child->add_child_nocopy (siter->second->get_state());
1068 child = node->add_child ("Regions");
1071 Glib::Threads::Mutex::Lock rl (region_lock);
1072 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1073 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1074 boost::shared_ptr<Region> r = i->second;
1075 /* only store regions not attached to playlists */
1076 if (r->playlist() == 0) {
1077 if (boost::dynamic_pointer_cast<AudioRegion>(r)) {
1078 child->add_child_nocopy ((boost::dynamic_pointer_cast<AudioRegion>(r))->get_basic_state ());
1080 child->add_child_nocopy (r->get_state ());
1085 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1087 if (!cassocs.empty()) {
1088 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1090 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1092 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1093 i->first->id().print (buf, sizeof (buf));
1094 can->add_property (X_("copy"), buf);
1095 i->second->id().print (buf, sizeof (buf));
1096 can->add_property (X_("original"), buf);
1097 ca->add_child_nocopy (*can);
1103 node->add_child_nocopy (_locations->get_state());
1105 // for a template, just create a new Locations, populate it
1106 // with the default start and end, and get the state for that.
1107 Locations loc (*this);
1108 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1109 range->set (max_framepos, 0);
1111 node->add_child_nocopy (loc.get_state());
1114 child = node->add_child ("Bundles");
1116 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1117 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1118 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1120 child->add_child_nocopy (b->get_state());
1125 child = node->add_child ("Routes");
1127 boost::shared_ptr<RouteList> r = routes.reader ();
1129 RoutePublicOrderSorter cmp;
1130 RouteList public_order (*r);
1131 public_order.sort (cmp);
1133 /* the sort should have put control outs first */
1136 assert (_monitor_out == public_order.front());
1139 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1140 if (!(*i)->is_auditioner()) {
1142 child->add_child_nocopy ((*i)->get_state());
1144 child->add_child_nocopy ((*i)->get_template());
1150 playlists->add_state (node, full_state);
1152 child = node->add_child ("RouteGroups");
1153 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1154 child->add_child_nocopy ((*i)->get_state());
1158 XMLNode* gain_child = node->add_child ("Click");
1159 gain_child->add_child_nocopy (_click_io->state (full_state));
1160 gain_child->add_child_nocopy (_click_gain->state (full_state));
1164 XMLNode* ltc_input_child = node->add_child ("LTC-In");
1165 ltc_input_child->add_child_nocopy (_ltc_input->state (full_state));
1169 XMLNode* ltc_output_child = node->add_child ("LTC-Out");
1170 ltc_output_child->add_child_nocopy (_ltc_output->state (full_state));
1173 node->add_child_nocopy (_speakers->get_state());
1174 node->add_child_nocopy (_tempo_map->get_state());
1175 node->add_child_nocopy (get_control_protocol_state());
1178 node->add_child_copy (*_extra_xml);
1185 Session::get_control_protocol_state ()
1187 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1188 return cpm.get_state();
1192 Session::set_state (const XMLNode& node, int version)
1196 const XMLProperty* prop;
1199 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1201 if (node.name() != X_("Session")) {
1202 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1206 if ((prop = node.property ("name")) != 0) {
1207 _name = prop->value ();
1210 if ((prop = node.property (X_("sample-rate"))) != 0) {
1212 _nominal_frame_rate = atoi (prop->value());
1214 if (_nominal_frame_rate != _current_frame_rate) {
1215 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1216 if (r.get_value_or (0)) {
1222 setup_raid_path(_session_dir->root_path());
1224 if ((prop = node.property (X_("id-counter"))) != 0) {
1226 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1227 ID::init_counter (x);
1229 /* old sessions used a timebased counter, so fake
1230 the startup ID counter based on a standard
1235 ID::init_counter (now);
1238 if ((prop = node.property (X_("event-counter"))) != 0) {
1239 Evoral::init_event_id_counter (atoi (prop->value()));
1242 IO::disable_connecting ();
1244 Stateful::save_extra_xml (node);
1246 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1247 load_options (*child);
1248 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1249 load_options (*child);
1251 error << _("Session: XML state has no options section") << endmsg;
1254 if (version >= 3000) {
1255 if ((child = find_named_node (node, "Metadata")) == 0) {
1256 warning << _("Session: XML state has no metadata section") << endmsg;
1257 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1262 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1263 _speakers->set_state (*child, version);
1266 if ((child = find_named_node (node, "Sources")) == 0) {
1267 error << _("Session: XML state has no sources section") << endmsg;
1269 } else if (load_sources (*child)) {
1273 if ((child = find_named_node (node, "TempoMap")) == 0) {
1274 error << _("Session: XML state has no Tempo Map section") << endmsg;
1276 } else if (_tempo_map->set_state (*child, version)) {
1280 if ((child = find_named_node (node, "Locations")) == 0) {
1281 error << _("Session: XML state has no locations section") << endmsg;
1283 } else if (_locations->set_state (*child, version)) {
1289 if ((location = _locations->auto_loop_location()) != 0) {
1290 set_auto_loop_location (location);
1293 if ((location = _locations->auto_punch_location()) != 0) {
1294 set_auto_punch_location (location);
1297 if ((location = _locations->session_range_location()) != 0) {
1298 delete _session_range_location;
1299 _session_range_location = location;
1302 if (_session_range_location) {
1303 AudioFileSource::set_header_position_offset (_session_range_location->start());
1306 if ((child = find_named_node (node, "Regions")) == 0) {
1307 error << _("Session: XML state has no Regions section") << endmsg;
1309 } else if (load_regions (*child)) {
1313 if ((child = find_named_node (node, "Playlists")) == 0) {
1314 error << _("Session: XML state has no playlists section") << endmsg;
1316 } else if (playlists->load (*this, *child)) {
1320 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1322 } else if (playlists->load_unused (*this, *child)) {
1326 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1327 if (load_compounds (*child)) {
1332 if (version >= 3000) {
1333 if ((child = find_named_node (node, "Bundles")) == 0) {
1334 warning << _("Session: XML state has no bundles section") << endmsg;
1337 /* We can't load Bundles yet as they need to be able
1338 to convert from port names to Port objects, which can't happen until
1340 _bundle_xml_node = new XMLNode (*child);
1344 if (version < 3000) {
1345 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1346 error << _("Session: XML state has no diskstreams section") << endmsg;
1348 } else if (load_diskstreams_2X (*child, version)) {
1353 if ((child = find_named_node (node, "Routes")) == 0) {
1354 error << _("Session: XML state has no routes section") << endmsg;
1356 } else if (load_routes (*child, version)) {
1360 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1361 _diskstreams_2X.clear ();
1363 if (version >= 3000) {
1365 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1366 error << _("Session: XML state has no route groups section") << endmsg;
1368 } else if (load_route_groups (*child, version)) {
1372 } else if (version < 3000) {
1374 if ((child = find_named_node (node, "EditGroups")) == 0) {
1375 error << _("Session: XML state has no edit groups section") << endmsg;
1377 } else if (load_route_groups (*child, version)) {
1381 if ((child = find_named_node (node, "MixGroups")) == 0) {
1382 error << _("Session: XML state has no mix groups section") << endmsg;
1384 } else if (load_route_groups (*child, version)) {
1389 if ((child = find_named_node (node, "Click")) == 0) {
1390 warning << _("Session: XML state has no click section") << endmsg;
1391 } else if (_click_io) {
1392 const XMLNodeList& children (child->children());
1393 XMLNodeList::const_iterator i = children.begin();
1394 _click_io->set_state (**i, version);
1396 if (i != children.end()) {
1397 _click_gain->set_state (**i, version);
1401 if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
1402 ControlProtocolManager::instance().set_state (*child, version);
1405 update_have_rec_enabled_track ();
1407 /* here beginneth the second phase ... */
1409 StateReady (); /* EMIT SIGNAL */
1418 Session::load_routes (const XMLNode& node, int version)
1421 XMLNodeConstIterator niter;
1422 RouteList new_routes;
1424 nlist = node.children();
1428 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1430 boost::shared_ptr<Route> route;
1431 if (version < 3000) {
1432 route = XMLRouteFactory_2X (**niter, version);
1434 route = XMLRouteFactory (**niter, version);
1438 error << _("Session: cannot create Route from XML description.") << endmsg;
1442 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1444 new_routes.push_back (route);
1447 add_routes (new_routes, false, false, false);
1452 boost::shared_ptr<Route>
1453 Session::XMLRouteFactory (const XMLNode& node, int version)
1455 boost::shared_ptr<Route> ret;
1457 if (node.name() != "Route") {
1461 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1463 DataType type = DataType::AUDIO;
1464 const XMLProperty* prop = node.property("default-type");
1467 type = DataType (prop->value());
1470 assert (type != DataType::NIL);
1474 boost::shared_ptr<Track> track;
1476 if (type == DataType::AUDIO) {
1477 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1479 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1482 if (track->init()) {
1486 if (track->set_state (node, version)) {
1490 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1491 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1496 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1498 if (r->init () == 0 && r->set_state (node, version) == 0) {
1499 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1500 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1509 boost::shared_ptr<Route>
1510 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1512 boost::shared_ptr<Route> ret;
1514 if (node.name() != "Route") {
1518 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1520 ds_prop = node.property (X_("diskstream"));
1523 DataType type = DataType::AUDIO;
1524 const XMLProperty* prop = node.property("default-type");
1527 type = DataType (prop->value());
1530 assert (type != DataType::NIL);
1534 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1535 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1539 if (i == _diskstreams_2X.end()) {
1540 error << _("Could not find diskstream for route") << endmsg;
1541 return boost::shared_ptr<Route> ();
1544 boost::shared_ptr<Track> track;
1546 if (type == DataType::AUDIO) {
1547 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1549 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1552 if (track->init()) {
1556 if (track->set_state (node, version)) {
1560 track->set_diskstream (*i);
1562 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1563 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1568 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1570 if (r->init () == 0 && r->set_state (node, version) == 0) {
1571 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1572 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1582 Session::load_regions (const XMLNode& node)
1585 XMLNodeConstIterator niter;
1586 boost::shared_ptr<Region> region;
1588 nlist = node.children();
1592 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1593 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1594 error << _("Session: cannot create Region from XML description.");
1595 const XMLProperty *name = (**niter).property("name");
1598 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1609 Session::load_compounds (const XMLNode& node)
1611 XMLNodeList calist = node.children();
1612 XMLNodeConstIterator caiter;
1613 XMLProperty *caprop;
1615 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1616 XMLNode* ca = *caiter;
1620 if ((caprop = ca->property (X_("original"))) == 0) {
1623 orig_id = caprop->value();
1625 if ((caprop = ca->property (X_("copy"))) == 0) {
1628 copy_id = caprop->value();
1630 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1631 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1633 if (!orig || !copy) {
1634 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1640 RegionFactory::add_compound_association (orig, copy);
1647 Session::load_nested_sources (const XMLNode& node)
1650 XMLNodeConstIterator niter;
1652 nlist = node.children();
1654 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1655 if ((*niter)->name() == "Source") {
1657 /* it may already exist, so don't recreate it unnecessarily
1660 XMLProperty* prop = (*niter)->property (X_("id"));
1662 error << _("Nested source has no ID info in session file! (ignored)") << endmsg;
1666 ID source_id (prop->value());
1668 if (!source_by_id (source_id)) {
1671 SourceFactory::create (*this, **niter, true);
1673 catch (failed_constructor& err) {
1674 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1681 boost::shared_ptr<Region>
1682 Session::XMLRegionFactory (const XMLNode& node, bool full)
1684 const XMLProperty* type = node.property("type");
1688 const XMLNodeList& nlist = node.children();
1690 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1691 XMLNode *child = (*niter);
1692 if (child->name() == "NestedSource") {
1693 load_nested_sources (*child);
1697 if (!type || type->value() == "audio") {
1698 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1699 } else if (type->value() == "midi") {
1700 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1703 } catch (failed_constructor& err) {
1704 return boost::shared_ptr<Region> ();
1707 return boost::shared_ptr<Region> ();
1710 boost::shared_ptr<AudioRegion>
1711 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1713 const XMLProperty* prop;
1714 boost::shared_ptr<Source> source;
1715 boost::shared_ptr<AudioSource> as;
1717 SourceList master_sources;
1718 uint32_t nchans = 1;
1721 if (node.name() != X_("Region")) {
1722 return boost::shared_ptr<AudioRegion>();
1725 if ((prop = node.property (X_("channels"))) != 0) {
1726 nchans = atoi (prop->value().c_str());
1729 if ((prop = node.property ("name")) == 0) {
1730 cerr << "no name for this region\n";
1734 if ((prop = node.property (X_("source-0"))) == 0) {
1735 if ((prop = node.property ("source")) == 0) {
1736 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1737 return boost::shared_ptr<AudioRegion>();
1741 PBD::ID s_id (prop->value());
1743 if ((source = source_by_id (s_id)) == 0) {
1744 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1745 return boost::shared_ptr<AudioRegion>();
1748 as = boost::dynamic_pointer_cast<AudioSource>(source);
1750 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1751 return boost::shared_ptr<AudioRegion>();
1754 sources.push_back (as);
1756 /* pickup other channels */
1758 for (uint32_t n=1; n < nchans; ++n) {
1759 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1760 if ((prop = node.property (buf)) != 0) {
1762 PBD::ID id2 (prop->value());
1764 if ((source = source_by_id (id2)) == 0) {
1765 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1766 return boost::shared_ptr<AudioRegion>();
1769 as = boost::dynamic_pointer_cast<AudioSource>(source);
1771 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1772 return boost::shared_ptr<AudioRegion>();
1774 sources.push_back (as);
1778 for (uint32_t n = 0; n < nchans; ++n) {
1779 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1780 if ((prop = node.property (buf)) != 0) {
1782 PBD::ID id2 (prop->value());
1784 if ((source = source_by_id (id2)) == 0) {
1785 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1786 return boost::shared_ptr<AudioRegion>();
1789 as = boost::dynamic_pointer_cast<AudioSource>(source);
1791 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1792 return boost::shared_ptr<AudioRegion>();
1794 master_sources.push_back (as);
1799 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1801 /* a final detail: this is the one and only place that we know how long missing files are */
1803 if (region->whole_file()) {
1804 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1805 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1807 sfp->set_length (region->length());
1812 if (!master_sources.empty()) {
1813 if (master_sources.size() != nchans) {
1814 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1816 region->set_master_sources (master_sources);
1824 catch (failed_constructor& err) {
1825 return boost::shared_ptr<AudioRegion>();
1829 boost::shared_ptr<MidiRegion>
1830 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1832 const XMLProperty* prop;
1833 boost::shared_ptr<Source> source;
1834 boost::shared_ptr<MidiSource> ms;
1837 if (node.name() != X_("Region")) {
1838 return boost::shared_ptr<MidiRegion>();
1841 if ((prop = node.property ("name")) == 0) {
1842 cerr << "no name for this region\n";
1846 if ((prop = node.property (X_("source-0"))) == 0) {
1847 if ((prop = node.property ("source")) == 0) {
1848 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1849 return boost::shared_ptr<MidiRegion>();
1853 PBD::ID s_id (prop->value());
1855 if ((source = source_by_id (s_id)) == 0) {
1856 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1857 return boost::shared_ptr<MidiRegion>();
1860 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1862 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1863 return boost::shared_ptr<MidiRegion>();
1866 sources.push_back (ms);
1869 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1870 /* a final detail: this is the one and only place that we know how long missing files are */
1872 if (region->whole_file()) {
1873 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1874 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1876 sfp->set_length (region->length());
1884 catch (failed_constructor& err) {
1885 return boost::shared_ptr<MidiRegion>();
1890 Session::get_sources_as_xml ()
1893 XMLNode* node = new XMLNode (X_("Sources"));
1894 Glib::Threads::Mutex::Lock lm (source_lock);
1896 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1897 node->add_child_nocopy (i->second->get_state());
1904 Session::path_from_region_name (DataType type, string name, string identifier)
1906 char buf[PATH_MAX+1];
1908 SessionDirectory sdir(get_best_session_directory_for_new_source());
1909 std::string source_dir = ((type == DataType::AUDIO)
1910 ? sdir.sound_path() : sdir.midi_path());
1912 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1914 for (n = 0; n < 999999; ++n) {
1915 if (identifier.length()) {
1916 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1917 identifier.c_str(), n, ext.c_str());
1919 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1923 std::string source_path = Glib::build_filename (source_dir, buf);
1925 if (!Glib::file_test (source_path, Glib::FILE_TEST_EXISTS)) {
1930 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1939 Session::load_sources (const XMLNode& node)
1942 XMLNodeConstIterator niter;
1943 boost::shared_ptr<Source> source;
1945 nlist = node.children();
1949 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1952 if ((source = XMLSourceFactory (**niter)) == 0) {
1953 error << _("Session: cannot create Source from XML description.") << endmsg;
1956 } catch (MissingSource& err) {
1960 if (!no_questions_about_missing_files) {
1961 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1966 switch (user_choice) {
1968 /* user added a new search location, so try again */
1973 /* user asked to quit the entire session load
1978 no_questions_about_missing_files = true;
1982 no_questions_about_missing_files = true;
1987 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1988 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1997 boost::shared_ptr<Source>
1998 Session::XMLSourceFactory (const XMLNode& node)
2000 if (node.name() != "Source") {
2001 return boost::shared_ptr<Source>();
2005 /* note: do peak building in another thread when loading session state */
2006 return SourceFactory::create (*this, node, true);
2009 catch (failed_constructor& err) {
2010 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2011 return boost::shared_ptr<Source>();
2016 Session::save_template (string template_name)
2020 if (_state_of_the_state & CannotSave) {
2024 std::string user_template_dir(user_template_directory());
2026 if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
2027 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2028 user_template_dir, g_strerror (errno)) << endmsg;
2032 tree.set_root (&get_template());
2034 std::string template_dir_path(user_template_dir);
2036 /* directory to put the template in */
2037 template_dir_path = Glib::build_filename (template_dir_path, template_name);
2039 if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
2040 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2041 template_dir_path) << endmsg;
2045 if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
2046 error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
2047 template_dir_path, g_strerror (errno)) << endmsg;
2052 std::string template_file_path(template_dir_path);
2053 template_file_path = Glib::build_filename (template_file_path, template_name + template_suffix);
2055 if (!tree.write (template_file_path)) {
2056 error << _("template not saved") << endmsg;
2060 /* copy plugin state directory */
2062 std::string template_plugin_state_path(template_dir_path);
2063 template_plugin_state_path = Glib::build_filename (template_plugin_state_path, X_("plugins"));
2065 if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
2066 error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
2067 template_plugin_state_path, g_strerror (errno)) << endmsg;
2071 copy_files (plugins_dir(), template_plugin_state_path);
2077 Session::refresh_disk_space ()
2079 #if __APPLE__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
2081 Glib::Threads::Mutex::Lock lm (space_lock);
2083 /* get freespace on every FS that is part of the session path */
2085 _total_free_4k_blocks = 0;
2086 _total_free_4k_blocks_uncertain = false;
2088 for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2090 struct statfs statfsbuf;
2091 statfs (i->path.c_str(), &statfsbuf);
2093 double const scale = statfsbuf.f_bsize / 4096.0;
2095 /* See if this filesystem is read-only */
2096 struct statvfs statvfsbuf;
2097 statvfs (i->path.c_str(), &statvfsbuf);
2099 /* f_bavail can be 0 if it is undefined for whatever
2100 filesystem we are looking at; Samba shares mounted
2101 via GVFS are an example of this.
2103 if (statfsbuf.f_bavail == 0) {
2104 /* block count unknown */
2106 i->blocks_unknown = true;
2107 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2108 /* read-only filesystem */
2110 i->blocks_unknown = false;
2112 /* read/write filesystem with known space */
2113 i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2114 i->blocks_unknown = false;
2117 _total_free_4k_blocks += i->blocks;
2118 if (i->blocks_unknown) {
2119 _total_free_4k_blocks_uncertain = true;
2122 #elif defined (COMPILER_MSVC)
2123 vector<string> scanned_volumes;
2124 vector<string>::iterator j;
2125 vector<space_and_path>::iterator i;
2126 DWORD nSectorsPerCluster, nBytesPerSector,
2127 nFreeClusters, nTotalClusters;
2131 _total_free_4k_blocks = 0;
2133 for (i = session_dirs.begin(); i != session_dirs.end(); i++) {
2134 strncpy (disk_drive, (*i).path.c_str(), 3);
2138 volume_found = false;
2139 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2141 int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2142 int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2143 i->blocks = (uint32_t)(nFreeBytes / 4096);
2145 for (j = scanned_volumes.begin(); j != scanned_volumes.end(); j++) {
2146 if (0 == j->compare(disk_drive)) {
2147 volume_found = true;
2152 if (!volume_found) {
2153 scanned_volumes.push_back(disk_drive);
2154 _total_free_4k_blocks += i->blocks;
2159 if (0 == _total_free_4k_blocks) {
2160 strncpy (disk_drive, path().c_str(), 3);
2163 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2165 int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2166 int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2167 _total_free_4k_blocks = (uint32_t)(nFreeBytes / 4096);
2174 Session::get_best_session_directory_for_new_source ()
2176 vector<space_and_path>::iterator i;
2177 string result = _session_dir->root_path();
2179 /* handle common case without system calls */
2181 if (session_dirs.size() == 1) {
2185 /* OK, here's the algorithm we're following here:
2187 We want to select which directory to use for
2188 the next file source to be created. Ideally,
2189 we'd like to use a round-robin process so as to
2190 get maximum performance benefits from splitting
2191 the files across multiple disks.
2193 However, in situations without much diskspace, an
2194 RR approach may end up filling up a filesystem
2195 with new files while others still have space.
2196 Its therefore important to pay some attention to
2197 the freespace in the filesystem holding each
2198 directory as well. However, if we did that by
2199 itself, we'd keep creating new files in the file
2200 system with the most space until it was as full
2201 as all others, thus negating any performance
2202 benefits of this RAID-1 like approach.
2204 So, we use a user-configurable space threshold. If
2205 there are at least 2 filesystems with more than this
2206 much space available, we use RR selection between them.
2207 If not, then we pick the filesystem with the most space.
2209 This gets a good balance between the two
2213 refresh_disk_space ();
2215 int free_enough = 0;
2217 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2218 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2223 if (free_enough >= 2) {
2224 /* use RR selection process, ensuring that the one
2228 i = last_rr_session_dir;
2231 if (++i == session_dirs.end()) {
2232 i = session_dirs.begin();
2235 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2236 SessionDirectory sdir(i->path);
2237 if (sdir.create ()) {
2239 last_rr_session_dir = i;
2244 } while (i != last_rr_session_dir);
2248 /* pick FS with the most freespace (and that
2249 seems to actually work ...)
2252 vector<space_and_path> sorted;
2253 space_and_path_ascending_cmp cmp;
2255 sorted = session_dirs;
2256 sort (sorted.begin(), sorted.end(), cmp);
2258 for (i = sorted.begin(); i != sorted.end(); ++i) {
2259 SessionDirectory sdir(i->path);
2260 if (sdir.create ()) {
2262 last_rr_session_dir = i;
2272 Session::automation_dir () const
2274 return Glib::build_filename (_path, "automation");
2278 Session::analysis_dir () const
2280 return Glib::build_filename (_path, "analysis");
2284 Session::plugins_dir () const
2286 return Glib::build_filename (_path, "plugins");
2290 Session::externals_dir () const
2292 return Glib::build_filename (_path, "externals");
2296 Session::load_bundles (XMLNode const & node)
2298 XMLNodeList nlist = node.children();
2299 XMLNodeConstIterator niter;
2303 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2304 if ((*niter)->name() == "InputBundle") {
2305 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2306 } else if ((*niter)->name() == "OutputBundle") {
2307 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2309 error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
2318 Session::load_route_groups (const XMLNode& node, int version)
2320 XMLNodeList nlist = node.children();
2321 XMLNodeConstIterator niter;
2325 if (version >= 3000) {
2327 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2328 if ((*niter)->name() == "RouteGroup") {
2329 RouteGroup* rg = new RouteGroup (*this, "");
2330 add_route_group (rg);
2331 rg->set_state (**niter, version);
2335 } else if (version < 3000) {
2337 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2338 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2339 RouteGroup* rg = new RouteGroup (*this, "");
2340 add_route_group (rg);
2341 rg->set_state (**niter, version);
2350 Session::auto_save()
2352 save_state (_current_snapshot_name);
2356 state_file_filter (const string &str, void */*arg*/)
2358 return (str.length() > strlen(statefile_suffix) &&
2359 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2363 bool operator()(const string* a, const string* b) {
2369 remove_end(string* state)
2371 string statename(*state);
2373 string::size_type start,end;
2374 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2375 statename = statename.substr (start+1);
2378 if ((end = statename.rfind(".ardour")) == string::npos) {
2379 end = statename.length();
2382 return new string(statename.substr (0, end));
2386 Session::possible_states (string path)
2388 PathScanner scanner;
2389 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2391 transform(states->begin(), states->end(), states->begin(), remove_end);
2394 sort (states->begin(), states->end(), cmp);
2400 Session::possible_states () const
2402 return possible_states(_path);
2406 Session::add_route_group (RouteGroup* g)
2408 _route_groups.push_back (g);
2409 route_group_added (g); /* EMIT SIGNAL */
2411 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2412 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2413 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2419 Session::remove_route_group (RouteGroup& rg)
2421 list<RouteGroup*>::iterator i;
2423 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2424 _route_groups.erase (i);
2427 route_group_removed (); /* EMIT SIGNAL */
2431 /** Set a new order for our route groups, without adding or removing any.
2432 * @param groups Route group list in the new order.
2435 Session::reorder_route_groups (list<RouteGroup*> groups)
2437 _route_groups = groups;
2439 route_groups_reordered (); /* EMIT SIGNAL */
2445 Session::route_group_by_name (string name)
2447 list<RouteGroup *>::iterator i;
2449 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2450 if ((*i)->name() == name) {
2458 Session::all_route_group() const
2460 return *_all_route_group;
2464 Session::add_commands (vector<Command*> const & cmds)
2466 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2472 Session::begin_reversible_command (const string& name)
2474 begin_reversible_command (g_quark_from_string (name.c_str ()));
2477 /** Begin a reversible command using a GQuark to identify it.
2478 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2479 * but there must be as many begin...()s as there are commit...()s.
2482 Session::begin_reversible_command (GQuark q)
2484 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2485 to hold all the commands that are committed. This keeps the order of
2486 commands correct in the history.
2489 if (_current_trans == 0) {
2490 /* start a new transaction */
2491 assert (_current_trans_quarks.empty ());
2492 _current_trans = new UndoTransaction();
2493 _current_trans->set_name (g_quark_to_string (q));
2496 _current_trans_quarks.push_front (q);
2500 Session::commit_reversible_command (Command *cmd)
2502 assert (_current_trans);
2503 assert (!_current_trans_quarks.empty ());
2508 _current_trans->add_command (cmd);
2511 _current_trans_quarks.pop_front ();
2513 if (!_current_trans_quarks.empty ()) {
2514 /* the transaction we're committing is not the top-level one */
2518 if (_current_trans->empty()) {
2519 /* no commands were added to the transaction, so just get rid of it */
2520 delete _current_trans;
2525 gettimeofday (&now, 0);
2526 _current_trans->set_timestamp (now);
2528 _history.add (_current_trans);
2533 accept_all_audio_files (const string& path, void */*arg*/)
2535 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2539 if (!AudioFileSource::safe_audio_file_extension (path)) {
2547 accept_all_midi_files (const string& path, void */*arg*/)
2549 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2553 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2554 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2555 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2559 accept_all_state_files (const string& path, void */*arg*/)
2561 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2565 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2569 Session::find_all_sources (string path, set<string>& result)
2574 if (!tree.read (path)) {
2578 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2583 XMLNodeConstIterator niter;
2585 nlist = node->children();
2589 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2593 if ((prop = (*niter)->property (X_("type"))) == 0) {
2597 DataType type (prop->value());
2599 if ((prop = (*niter)->property (X_("name"))) == 0) {
2603 if (Glib::path_is_absolute (prop->value())) {
2604 /* external file, ignore */
2612 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2613 result.insert (found_path);
2621 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2623 PathScanner scanner;
2624 vector<string*>* state_files;
2626 string this_snapshot_path;
2632 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2633 ripped = ripped.substr (0, ripped.length() - 1);
2636 state_files = scanner (ripped, accept_all_state_files, (void *) 0, true, true);
2638 if (state_files == 0) {
2643 this_snapshot_path = _path;
2644 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2645 this_snapshot_path += statefile_suffix;
2647 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2649 if (exclude_this_snapshot && **i == this_snapshot_path) {
2653 if (find_all_sources (**i, result) < 0) {
2661 struct RegionCounter {
2662 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2663 AudioSourceList::iterator iter;
2664 boost::shared_ptr<Region> region;
2667 RegionCounter() : count (0) {}
2671 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2673 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2674 return r.get_value_or (1);
2678 Session::cleanup_regions ()
2680 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2682 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2684 uint32_t used = playlists->region_use_count (i->second);
2686 if (used == 0 && !i->second->automatic ()) {
2687 RegionFactory::map_remove (i->second);
2691 /* dump the history list */
2698 Session::cleanup_sources (CleanupReport& rep)
2700 // FIXME: needs adaptation to midi
2702 vector<boost::shared_ptr<Source> > dead_sources;
2703 PathScanner scanner;
2706 vector<space_and_path>::iterator i;
2707 vector<space_and_path>::iterator nexti;
2708 vector<string*>* candidates;
2709 vector<string*>* candidates2;
2710 vector<string> unused;
2711 set<string> all_sources;
2718 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2720 /* consider deleting all unused playlists */
2722 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2727 /* sync the "all regions" property of each playlist with its current state
2730 playlists->sync_all_regions_with_regions ();
2732 /* find all un-used sources */
2737 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2739 SourceMap::iterator tmp;
2744 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2748 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2749 dead_sources.push_back (i->second);
2750 i->second->drop_references ();
2756 /* build a list of all the possible audio directories for the session */
2758 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2763 SessionDirectory sdir ((*i).path);
2764 audio_path += sdir.sound_path();
2766 if (nexti != session_dirs.end()) {
2774 /* build a list of all the possible midi directories for the session */
2776 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2781 SessionDirectory sdir ((*i).path);
2782 midi_path += sdir.midi_path();
2784 if (nexti != session_dirs.end()) {
2791 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2792 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2798 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2799 candidates->push_back (*i);
2804 candidates = candidates2; // might still be null
2807 /* find all sources, but don't use this snapshot because the
2808 state file on disk still references sources we may have already
2812 find_all_sources_across_snapshots (all_sources, true);
2814 /* add our current source list
2817 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2818 boost::shared_ptr<FileSource> fs;
2819 SourceMap::iterator tmp = i;
2822 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2823 if (playlists->source_use_count (fs) != 0) {
2824 all_sources.insert (fs->path());
2827 /* we might not remove this source from disk, because it may be used
2828 by other snapshots, but its not being used in this version
2829 so lets get rid of it now, along with any representative regions
2833 RegionFactory::remove_regions_using_source (i->second);
2842 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2847 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2849 tmppath1 = canonical_path (spath);
2850 tmppath2 = canonical_path ((*i));
2852 if (tmppath1 == tmppath2) {
2859 unused.push_back (spath);
2868 /* now try to move all unused files into the "dead" directory(ies) */
2870 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2871 struct stat statbuf;
2875 /* don't move the file across filesystems, just
2876 stick it in the `dead_dir_name' directory
2877 on whichever filesystem it was already on.
2880 if ((*x).find ("/sounds/") != string::npos) {
2882 /* old school, go up 1 level */
2884 newpath = Glib::path_get_dirname (*x); // "sounds"
2885 newpath = Glib::path_get_dirname (newpath); // "session-name"
2889 /* new school, go up 4 levels */
2891 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2892 newpath = Glib::path_get_dirname (newpath); // "session-name"
2893 newpath = Glib::path_get_dirname (newpath); // "interchange"
2894 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2897 newpath = Glib::build_filename (newpath, dead_dir_name);
2899 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2900 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2904 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2906 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2908 /* the new path already exists, try versioning */
2910 char buf[PATH_MAX+1];
2914 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2917 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2918 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2922 if (version == 999) {
2923 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2927 newpath = newpath_v;
2932 /* it doesn't exist, or we can't read it or something */
2936 stat ((*x).c_str(), &statbuf);
2938 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2939 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2940 (*x), newpath, strerror (errno))
2945 /* see if there an easy to find peakfile for this file, and remove it.
2948 string base = basename_nosuffix (*x);
2949 base += "%A"; /* this is what we add for the channel suffix of all native files,
2950 or for the first channel of embedded files. it will miss
2951 some peakfiles for other channels
2953 string peakpath = peak_path (base);
2955 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2956 if (::g_unlink (peakpath.c_str()) != 0) {
2957 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2958 peakpath, _path, strerror (errno))
2960 /* try to back out */
2961 ::rename (newpath.c_str(), _path.c_str());
2966 rep.paths.push_back (*x);
2967 rep.space += statbuf.st_size;
2970 /* dump the history list */
2974 /* save state so we don't end up a session file
2975 referring to non-existent sources.
2982 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2988 Session::cleanup_trash_sources (CleanupReport& rep)
2990 // FIXME: needs adaptation for MIDI
2992 vector<space_and_path>::iterator i;
2998 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3000 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
3002 clear_directory (dead_dir, &rep.space, &rep.paths);
3009 Session::set_dirty ()
3011 bool was_dirty = dirty();
3013 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3017 DirtyChanged(); /* EMIT SIGNAL */
3023 Session::set_clean ()
3025 bool was_dirty = dirty();
3027 _state_of_the_state = Clean;
3031 DirtyChanged(); /* EMIT SIGNAL */
3036 Session::set_deletion_in_progress ()
3038 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3042 Session::clear_deletion_in_progress ()
3044 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3048 Session::add_controllable (boost::shared_ptr<Controllable> c)
3050 /* this adds a controllable to the list managed by the Session.
3051 this is a subset of those managed by the Controllable class
3052 itself, and represents the only ones whose state will be saved
3053 as part of the session.
3056 Glib::Threads::Mutex::Lock lm (controllables_lock);
3057 controllables.insert (c);
3060 struct null_deleter { void operator()(void const *) const {} };
3063 Session::remove_controllable (Controllable* c)
3065 if (_state_of_the_state & Deletion) {
3069 Glib::Threads::Mutex::Lock lm (controllables_lock);
3071 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3073 if (x != controllables.end()) {
3074 controllables.erase (x);
3078 boost::shared_ptr<Controllable>
3079 Session::controllable_by_id (const PBD::ID& id)
3081 Glib::Threads::Mutex::Lock lm (controllables_lock);
3083 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3084 if ((*i)->id() == id) {
3089 return boost::shared_ptr<Controllable>();
3092 boost::shared_ptr<Controllable>
3093 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3095 boost::shared_ptr<Controllable> c;
3096 boost::shared_ptr<Route> r;
3098 switch (desc.top_level_type()) {
3099 case ControllableDescriptor::NamedRoute:
3101 std::string str = desc.top_level_name();
3102 if (str == "master") {
3104 } else if (str == "control" || str == "listen") {
3107 r = route_by_name (desc.top_level_name());
3112 case ControllableDescriptor::RemoteControlID:
3113 r = route_by_remote_id (desc.rid());
3121 switch (desc.subtype()) {
3122 case ControllableDescriptor::Gain:
3123 c = r->gain_control ();
3126 case ControllableDescriptor::Solo:
3127 c = r->solo_control();
3130 case ControllableDescriptor::Mute:
3131 c = r->mute_control();
3134 case ControllableDescriptor::Recenable:
3136 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3139 c = t->rec_enable_control ();
3144 case ControllableDescriptor::PanDirection:
3146 c = r->pannable()->pan_azimuth_control;
3150 case ControllableDescriptor::PanWidth:
3152 c = r->pannable()->pan_width_control;
3156 case ControllableDescriptor::PanElevation:
3158 c = r->pannable()->pan_elevation_control;
3162 case ControllableDescriptor::Balance:
3163 /* XXX simple pan control */
3166 case ControllableDescriptor::PluginParameter:
3168 uint32_t plugin = desc.target (0);
3169 uint32_t parameter_index = desc.target (1);
3171 /* revert to zero based counting */
3177 if (parameter_index > 0) {
3181 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3184 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3185 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3190 case ControllableDescriptor::SendGain:
3192 uint32_t send = desc.target (0);
3194 /* revert to zero-based counting */
3200 boost::shared_ptr<Processor> p = r->nth_send (send);
3203 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3204 boost::shared_ptr<Amp> a = s->amp();
3207 c = s->amp()->gain_control();
3214 /* relax and return a null pointer */
3222 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3225 Stateful::add_instant_xml (node, _path);
3228 if (write_to_config) {
3229 Config->add_instant_xml (node);
3234 Session::instant_xml (const string& node_name)
3236 return Stateful::instant_xml (node_name, _path);
3240 Session::save_history (string snapshot_name)
3248 if (snapshot_name.empty()) {
3249 snapshot_name = _current_snapshot_name;
3252 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3253 const string backup_filename = history_filename + backup_suffix;
3254 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3255 const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3257 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3258 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3259 error << _("could not backup old history file, current history not saved") << endmsg;
3264 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3268 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3270 if (!tree.write (xml_path))
3272 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3274 if (g_remove (xml_path.c_str()) != 0) {
3275 error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3276 xml_path, g_strerror (errno)) << endmsg;
3278 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3279 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3280 backup_path, g_strerror (errno)) << endmsg;
3290 Session::restore_history (string snapshot_name)
3294 if (snapshot_name.empty()) {
3295 snapshot_name = _current_snapshot_name;
3298 const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3299 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3301 info << "Loading history from " << xml_path << endmsg;
3303 if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3304 info << string_compose (_("%1: no history file \"%2\" for this session."),
3305 _name, xml_path) << endmsg;
3309 if (!tree.read (xml_path)) {
3310 error << string_compose (_("Could not understand session history file \"%1\""),
3311 xml_path) << endmsg;
3318 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3321 UndoTransaction* ut = new UndoTransaction ();
3324 ut->set_name(t->property("name")->value());
3325 stringstream ss(t->property("tv-sec")->value());
3327 ss.str(t->property("tv-usec")->value());
3329 ut->set_timestamp(tv);
3331 for (XMLNodeConstIterator child_it = t->children().begin();
3332 child_it != t->children().end(); child_it++)
3334 XMLNode *n = *child_it;
3337 if (n->name() == "MementoCommand" ||
3338 n->name() == "MementoUndoCommand" ||
3339 n->name() == "MementoRedoCommand") {
3341 if ((c = memento_command_factory(n))) {
3345 } else if (n->name() == "NoteDiffCommand") {
3346 PBD::ID id (n->property("midi-source")->value());
3347 boost::shared_ptr<MidiSource> midi_source =
3348 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3350 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3352 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3355 } else if (n->name() == "SysExDiffCommand") {
3357 PBD::ID id (n->property("midi-source")->value());
3358 boost::shared_ptr<MidiSource> midi_source =
3359 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3361 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3363 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3366 } else if (n->name() == "PatchChangeDiffCommand") {
3368 PBD::ID id (n->property("midi-source")->value());
3369 boost::shared_ptr<MidiSource> midi_source =
3370 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3372 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3374 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3377 } else if (n->name() == "StatefulDiffCommand") {
3378 if ((c = stateful_diff_command_factory (n))) {
3379 ut->add_command (c);
3382 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3393 Session::config_changed (std::string p, bool ours)
3399 if (p == "seamless-loop") {
3401 } else if (p == "rf-speed") {
3403 } else if (p == "auto-loop") {
3405 } else if (p == "auto-input") {
3407 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3408 /* auto-input only makes a difference if we're rolling */
3409 set_track_monitor_input_status (!config.get_auto_input());
3412 } else if (p == "punch-in") {
3416 if ((location = _locations->auto_punch_location()) != 0) {
3418 if (config.get_punch_in ()) {
3419 replace_event (SessionEvent::PunchIn, location->start());
3421 remove_event (location->start(), SessionEvent::PunchIn);
3425 } else if (p == "punch-out") {
3429 if ((location = _locations->auto_punch_location()) != 0) {
3431 if (config.get_punch_out()) {
3432 replace_event (SessionEvent::PunchOut, location->end());
3434 clear_events (SessionEvent::PunchOut);
3438 } else if (p == "edit-mode") {
3440 Glib::Threads::Mutex::Lock lm (playlists->lock);
3442 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3443 (*i)->set_edit_mode (Config->get_edit_mode ());
3446 } else if (p == "use-video-sync") {
3448 waiting_for_sync_offset = config.get_use_video_sync();
3450 } else if (p == "mmc-control") {
3452 //poke_midi_thread ();
3454 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3456 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3458 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3460 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3462 } else if (p == "midi-control") {
3464 //poke_midi_thread ();
3466 } else if (p == "raid-path") {
3468 setup_raid_path (config.get_raid_path());
3470 } else if (p == "timecode-format") {
3474 } else if (p == "video-pullup") {
3478 } else if (p == "seamless-loop") {
3480 if (play_loop && transport_rolling()) {
3481 // to reset diskstreams etc
3482 request_play_loop (true);
3485 } else if (p == "rf-speed") {
3487 cumulative_rf_motion = 0;
3490 } else if (p == "click-sound") {
3492 setup_click_sounds (1);
3494 } else if (p == "click-emphasis-sound") {
3496 setup_click_sounds (-1);
3498 } else if (p == "clicking") {
3500 if (Config->get_clicking()) {
3501 if (_click_io && click_data) { // don't require emphasis data
3508 } else if (p == "click-gain") {
3511 _click_gain->set_gain (Config->get_click_gain(), this);
3514 } else if (p == "send-mtc") {
3516 if (Config->get_send_mtc ()) {
3517 /* mark us ready to send */
3518 next_quarter_frame_to_send = 0;
3521 } else if (p == "send-mmc") {
3523 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3525 } else if (p == "midi-feedback") {
3527 session_midi_feedback = Config->get_midi_feedback();
3529 } else if (p == "jack-time-master") {
3531 engine().reset_timebase ();
3533 } else if (p == "native-file-header-format") {
3535 if (!first_file_header_format_reset) {
3536 reset_native_file_format ();
3539 first_file_header_format_reset = false;
3541 } else if (p == "native-file-data-format") {
3543 if (!first_file_data_format_reset) {
3544 reset_native_file_format ();
3547 first_file_data_format_reset = false;
3549 } else if (p == "external-sync") {
3550 if (!config.get_external_sync()) {
3551 drop_sync_source ();
3553 switch_to_sync_source (Config->get_sync_source());
3555 } else if (p == "denormal-model") {
3557 } else if (p == "history-depth") {
3558 set_history_depth (Config->get_history_depth());
3559 } else if (p == "remote-model") {
3560 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
3563 } else if (p == "sync-all-route-ordering") {
3565 /* sync to editor order unless mixer is used for remote IDs
3568 switch (Config->get_remote_model()) {
3570 sync_order_keys (EditorSort);
3573 sync_order_keys (EditorSort);
3576 sync_order_keys (MixerSort);
3579 } else if (p == "initial-program-change") {
3581 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3584 buf[0] = MIDI::program; // channel zero by default
3585 buf[1] = (Config->get_initial_program_change() & 0x7f);
3587 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3589 } else if (p == "solo-mute-override") {
3590 // catch_up_on_solo_mute_override ();
3591 } else if (p == "listen-position" || p == "pfl-position") {
3592 listen_position_changed ();
3593 } else if (p == "solo-control-is-listen-control") {
3594 solo_control_mode_changed ();
3595 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3596 last_timecode_valid = false;
3597 } else if (p == "playback-buffer-seconds") {
3598 AudioSource::allocate_working_buffers (frame_rate());
3599 } else if (p == "automation-thinning-factor") {
3600 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3601 } else if (p == "ltc-source-port") {
3602 reconnect_ltc_input ();
3603 } else if (p == "ltc-sink-port") {
3604 reconnect_ltc_output ();
3605 } else if (p == "timecode-generator-offset") {
3606 ltc_tx_parse_offset();
3613 Session::set_history_depth (uint32_t d)
3615 _history.set_depth (d);
3619 Session::load_diskstreams_2X (XMLNode const & node, int)
3622 XMLNodeConstIterator citer;
3624 clist = node.children();
3626 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3629 /* diskstreams added automatically by DiskstreamCreated handler */
3630 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3631 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3632 _diskstreams_2X.push_back (dsp);
3634 error << _("Session: unknown diskstream type in XML") << endmsg;
3638 catch (failed_constructor& err) {
3639 error << _("Session: could not load diskstream via XML state") << endmsg;
3647 /** Connect things to the MMC object */
3649 Session::setup_midi_machine_control ()
3651 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3653 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3654 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3655 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3656 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3657 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3658 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3659 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3660 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3661 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3662 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3663 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3664 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3665 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3667 /* also handle MIDI SPP because its so common */
3669 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3670 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3671 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3674 boost::shared_ptr<Controllable>
3675 Session::solo_cut_control() const
3677 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3678 controls in Ardour that currently get presented to the user in the GUI that require
3679 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3681 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3682 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3686 return _solo_cut_control;
3690 Session::rename (const std::string& new_name)
3692 string legal_name = legalize_for_path (new_name);
3698 string const old_sources_root = _session_dir->sources_root();
3700 #define RENAME ::rename
3705 * interchange subdirectory
3709 * Backup files are left unchanged and not renamed.
3712 /* pass one: not 100% safe check that the new directory names don't
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 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3742 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3747 /* this is a stupid hack because Glib::path_get_dirname() is
3748 * lexical-only, and so passing it /a/b/c/ gives a different
3749 * result than passing it /a/b/c ...
3752 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3753 oldstr = oldstr.substr (0, oldstr.length() - 1);
3756 string base = Glib::path_get_dirname (oldstr);
3757 string p = Glib::path_get_basename (oldstr);
3759 newstr = Glib::build_filename (base, legal_name);
3761 cerr << "Rename " << oldstr << " => " << newstr << endl;
3763 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3768 (*_session_dir) = newstr;
3773 /* directory below interchange */
3775 v.push_back (newstr);
3776 v.push_back (interchange_dir_name);
3779 oldstr = Glib::build_filename (v);
3782 v.push_back (newstr);
3783 v.push_back (interchange_dir_name);
3784 v.push_back (legal_name);
3786 newstr = Glib::build_filename (v);
3788 cerr << "Rename " << oldstr << " => " << newstr << endl;
3790 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3797 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3798 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3800 cerr << "Rename " << oldstr << " => " << newstr << endl;
3802 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3809 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3811 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3812 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3814 cerr << "Rename " << oldstr << " => " << newstr << endl;
3816 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3821 /* update file source paths */
3823 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3824 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3826 string p = fs->path ();
3827 boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3832 /* remove old name from recent sessions */
3834 remove_recent_sessions (_path);
3837 _current_snapshot_name = new_name;
3842 /* save state again to get everything just right */
3844 save_state (_current_snapshot_name);
3847 /* add to recent sessions */
3849 store_recent_sessions (new_name, _path);