2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "libardour-config.h"
31 #include <cstdio> /* snprintf(3) ... grrr */
45 #include <sys/param.h>
46 #include <sys/mount.h>
49 #ifdef HAVE_SYS_STATVFS_H
50 #include <sys/statvfs.h>
54 #include <glib/gstdio.h>
57 #include <glibmm/threads.h>
59 #include <boost/algorithm/string.hpp>
61 #include "midi++/mmc.h"
62 #include "midi++/port.h"
63 #include "midi++/manager.h"
65 #include "evoral/SMF.hpp"
67 #include "pbd/boost_debug.h"
68 #include "pbd/basename.h"
69 #include "pbd/controllable_descriptor.h"
70 #include "pbd/enumwriter.h"
71 #include "pbd/error.h"
72 #include "pbd/file_utils.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"
79 #include "ardour/amp.h"
80 #include "ardour/audio_diskstream.h"
81 #include "ardour/audio_track.h"
82 #include "ardour/audioengine.h"
83 #include "ardour/audiofilesource.h"
84 #include "ardour/audioregion.h"
85 #include "ardour/automation_control.h"
86 #include "ardour/butler.h"
87 #include "ardour/control_protocol_manager.h"
88 #include "ardour/directory_names.h"
89 #include "ardour/filename_extensions.h"
90 #include "ardour/location.h"
91 #include "ardour/midi_model.h"
92 #include "ardour/midi_patch_manager.h"
93 #include "ardour/midi_region.h"
94 #include "ardour/midi_source.h"
95 #include "ardour/midi_track.h"
96 #include "ardour/pannable.h"
97 #include "ardour/playlist_factory.h"
98 #include "ardour/port.h"
99 #include "ardour/processor.h"
100 #include "ardour/proxy_controllable.h"
101 #include "ardour/recent_sessions.h"
102 #include "ardour/region_factory.h"
103 #include "ardour/route_group.h"
104 #include "ardour/send.h"
105 #include "ardour/session.h"
106 #include "ardour/session_directory.h"
107 #include "ardour/session_metadata.h"
108 #include "ardour/session_playlists.h"
109 #include "ardour/session_state_utils.h"
110 #include "ardour/silentfilesource.h"
111 #include "ardour/sndfilesource.h"
112 #include "ardour/source_factory.h"
113 #include "ardour/speakers.h"
114 #include "ardour/template_utils.h"
115 #include "ardour/tempo.h"
116 #include "ardour/ticker.h"
117 #include "ardour/user_bundle.h"
119 #include "control_protocol/control_protocol.h"
125 using namespace ARDOUR;
128 /** @param snapshot_name Snapshot name, without the .ardour prefix */
130 Session::first_stage_init (string fullpath, string snapshot_name)
132 if (fullpath.length() == 0) {
134 throw failed_constructor();
137 char buf[PATH_MAX+1];
138 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
139 error << string_compose(_("Could not use path %1 (%2)"), buf, strerror(errno)) << endmsg;
141 throw failed_constructor();
146 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
147 _path += G_DIR_SEPARATOR;
150 /* these two are just provisional settings. set_state()
151 will likely override them.
154 _name = _current_snapshot_name = snapshot_name;
156 set_history_depth (Config->get_history_depth());
158 _current_frame_rate = _engine.sample_rate ();
159 _nominal_frame_rate = _current_frame_rate;
160 _base_frame_rate = _current_frame_rate;
162 _tempo_map = new TempoMap (_current_frame_rate);
163 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
166 _non_soloed_outs_muted = false;
168 _solo_isolated_cnt = 0;
169 g_atomic_int_set (&processing_prohibited, 0);
170 _transport_speed = 0;
171 _default_transport_speed = 1.0;
172 _last_transport_speed = 0;
173 _target_transport_speed = 0;
174 auto_play_legal = false;
175 transport_sub_state = 0;
176 _transport_frame = 0;
177 _requested_return_frame = -1;
178 _session_range_location = 0;
179 g_atomic_int_set (&_record_status, Disabled);
180 loop_changing = false;
183 _last_roll_location = 0;
184 _last_roll_or_reversal_location = 0;
185 _last_record_location = 0;
186 pending_locate_frame = 0;
187 pending_locate_roll = false;
188 pending_locate_flush = false;
189 state_was_pending = false;
191 outbound_mtc_timecode_frame = 0;
192 next_quarter_frame_to_send = -1;
193 current_block_size = 0;
194 solo_update_disabled = false;
195 _have_captured = false;
196 _worst_output_latency = 0;
197 _worst_input_latency = 0;
198 _worst_track_latency = 0;
199 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
200 _was_seamless = Config->get_seamless_loop ();
202 _send_qf_mtc = false;
203 _pframes_since_last_mtc = 0;
204 g_atomic_int_set (&_playback_load, 100);
205 g_atomic_int_set (&_capture_load, 100);
208 pending_abort = false;
209 _adding_routes_in_progress = false;
210 destructive_index = 0;
211 first_file_data_format_reset = true;
212 first_file_header_format_reset = true;
213 post_export_sync = false;
216 no_questions_about_missing_files = false;
217 _speakers.reset (new Speakers);
219 ignore_route_processor_changes = false;
220 _pre_export_mmc_enabled = false;
222 AudioDiskstream::allocate_working_buffers();
224 /* default short fade = 15ms */
226 SndFileSource::setup_standard_crossfades (*this, frame_rate());
228 last_mmc_step.tv_sec = 0;
229 last_mmc_step.tv_usec = 0;
232 /* click sounds are unset by default, which causes us to internal
233 waveforms for clicks.
237 click_emphasis_length = 0;
240 process_function = &Session::process_with_events;
242 if (config.get_use_video_sync()) {
243 waiting_for_sync_offset = true;
245 waiting_for_sync_offset = false;
248 last_timecode_when = 0;
249 last_timecode_valid = false;
253 last_rr_session_dir = session_dirs.begin();
254 refresh_disk_space ();
256 /* default: assume simple stereo speaker configuration */
258 _speakers->setup_default_speakers (2);
262 average_slave_delta = 1800; // !!! why 1800 ????
263 have_first_delta_accumulator = false;
264 delta_accumulator_cnt = 0;
265 _slave_state = Stopped;
267 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
268 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
269 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
270 add_controllable (_solo_cut_control);
272 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
274 /* These are all static "per-class" signals */
276 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
277 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
278 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
279 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
280 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
282 /* stop IO objects from doing stuff until we're ready for them */
284 Delivery::disable_panners ();
285 IO::disable_connecting ();
289 Session::second_stage_init ()
291 AudioFileSource::set_peak_dir (_session_dir->peak_path());
294 if (load_state (_current_snapshot_name)) {
299 if (_butler->start_thread()) {
303 if (start_midi_thread ()) {
307 setup_midi_machine_control ();
309 // set_state() will call setup_raid_path(), but if it's a new session we need
310 // to call setup_raid_path() here.
313 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
317 setup_raid_path(_path);
320 /* we can't save till after ::when_engine_running() is called,
321 because otherwise we save state with no connections made.
322 therefore, we reset _state_of_the_state because ::set_state()
323 will have cleared it.
325 we also have to include Loading so that any events that get
326 generated between here and the end of ::when_engine_running()
327 will be processed directly rather than queued.
330 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
332 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
333 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
334 setup_click_sounds (0);
335 setup_midi_control ();
337 /* Pay attention ... */
339 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
340 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
342 midi_clock = new MidiClockTicker ();
343 midi_clock->set_session (this);
346 when_engine_running ();
349 /* handle this one in a different way than all others, so that its clear what happened */
351 catch (AudioEngine::PortRegistrationFailure& err) {
352 error << err.what() << endmsg;
360 BootMessage (_("Reset Remote Controls"));
362 send_full_time_code (0);
363 _engine.transport_locate (0);
365 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
366 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
368 MIDI::Name::MidiPatchManager::instance().set_session (this);
371 /* initial program change will be delivered later; see ::config_changed() */
373 _state_of_the_state = Clean;
375 Port::set_connecting_blocked (false);
377 DirtyChanged (); /* EMIT SIGNAL */
379 if (state_was_pending) {
380 save_state (_current_snapshot_name);
381 remove_pending_capture_state ();
382 state_was_pending = false;
385 BootMessage (_("Session loading complete"));
391 Session::raid_path () const
393 SearchPath raid_search_path;
395 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
396 raid_search_path += (*i).path;
399 return raid_search_path.to_string ();
403 Session::setup_raid_path (string path)
412 session_dirs.clear ();
414 SearchPath search_path(path);
415 SearchPath sound_search_path;
416 SearchPath midi_search_path;
418 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
420 sp.blocks = 0; // not needed
421 session_dirs.push_back (sp);
423 SessionDirectory sdir(sp.path);
425 sound_search_path += sdir.sound_path ();
426 midi_search_path += sdir.midi_path ();
429 // reset the round-robin soundfile path thingie
430 last_rr_session_dir = session_dirs.begin();
434 Session::path_is_within_session (const std::string& path)
436 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
437 if (PBD::path_is_within (i->path, path)) {
445 Session::ensure_subdirs ()
449 dir = session_directory().peak_path();
451 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
452 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
456 dir = session_directory().sound_path();
458 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
459 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
463 dir = session_directory().midi_path();
465 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
466 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
470 dir = session_directory().dead_path();
472 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
473 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
477 dir = session_directory().export_path();
479 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
480 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
484 dir = analysis_dir ();
486 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
487 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
491 dir = plugins_dir ();
493 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
494 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
498 dir = externals_dir ();
500 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
501 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
508 /** @param session_template directory containing session template, or empty.
509 * Caller must not hold process lock.
512 Session::create (const string& session_template, BusProfile* bus_profile)
514 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
515 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
519 if (ensure_subdirs ()) {
523 _writable = exists_and_writable (_path);
525 if (!session_template.empty()) {
526 std::string in_path = session_template_dir_to_file (session_template);
528 ifstream in(in_path.c_str());
531 string out_path = _path;
533 out_path += statefile_suffix;
535 ofstream out(out_path.c_str());
541 /* Copy plugin state files from template to new session */
542 std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
543 copy_files (template_plugins, plugins_dir ());
548 error << string_compose (_("Could not open %1 for writing session template"), out_path)
554 error << string_compose (_("Could not open session template %1 for reading"), in_path)
561 /* set initial start + end point */
563 _state_of_the_state = Clean;
565 /* set up Master Out and Control Out if necessary */
570 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
572 if (bus_profile->master_out_channels) {
573 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
577 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
578 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
581 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
582 r->input()->ensure_io (count, false, this);
583 r->output()->ensure_io (count, false, this);
589 /* prohibit auto-connect to master, because there isn't one */
590 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
594 add_routes (rl, false, false, false);
597 /* this allows the user to override settings with an environment variable.
600 if (no_auto_connect()) {
601 bus_profile->input_ac = AutoConnectOption (0);
602 bus_profile->output_ac = AutoConnectOption (0);
605 Config->set_input_auto_connect (bus_profile->input_ac);
606 Config->set_output_auto_connect (bus_profile->output_ac);
609 if (Config->get_use_monitor_bus() && bus_profile) {
610 add_monitor_section ();
619 Session::maybe_write_autosave()
621 if (dirty() && record_status() != Recording) {
622 save_state("", true);
627 Session::remove_pending_capture_state ()
629 std::string pending_state_file_path(_session_dir->root_path());
631 pending_state_file_path = Glib::build_filename (pending_state_file_path, legalize_for_path (_current_snapshot_name) + pending_suffix);
633 if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS)) return;
635 if (g_remove (pending_state_file_path.c_str()) != 0) {
636 error << string_compose(_("Could not remove pending capture state at path \"%1\" (%2)"),
637 pending_state_file_path, g_strerror (errno)) << endmsg;
641 /** Rename a state file.
642 * @param old_name Old snapshot name.
643 * @param new_name New snapshot name.
646 Session::rename_state (string old_name, string new_name)
648 if (old_name == _current_snapshot_name || old_name == _name) {
649 /* refuse to rename the current snapshot or the "main" one */
653 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
654 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
656 const std::string old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
657 const std::string new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
659 if (::g_rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
660 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
661 old_name, new_name, g_strerror(errno)) << endmsg;
665 /** Remove a state file.
666 * @param snapshot_name Snapshot name.
669 Session::remove_state (string snapshot_name)
671 if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
672 // refuse to remove the current snapshot or the "main" one
676 std::string xml_path(_session_dir->root_path());
678 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
680 if (!create_backup_file (xml_path)) {
681 // don't remove it if a backup can't be made
682 // create_backup_file will log the error.
687 if (g_remove (xml_path.c_str()) != 0) {
688 error << string_compose(_("Could not remove session file at path \"%1\" (%2)"),
689 xml_path, g_strerror (errno)) << endmsg;
693 #ifdef HAVE_JACK_SESSION
695 Session::jack_session_event (jack_session_event_t * event)
697 char timebuf[128], *tmp;
699 struct tm local_time;
702 localtime_r (&n, &local_time);
703 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
705 while ((tmp = strchr(timebuf, ':'))) { *tmp = '.'; }
707 if (event->type == JackSessionSaveTemplate)
709 if (save_template( timebuf )) {
710 event->flags = JackSessionSaveError;
712 string cmd ("ardour3 -P -U ");
713 cmd += event->client_uuid;
717 event->command_line = strdup (cmd.c_str());
722 if (save_state (timebuf)) {
723 event->flags = JackSessionSaveError;
725 std::string xml_path (_session_dir->root_path());
726 std::string legalized_filename = legalize_for_path (timebuf) + statefile_suffix;
727 xml_path = Glib::build_filename (xml_path, legalized_filename);
729 string cmd ("ardour3 -P -U ");
730 cmd += event->client_uuid;
735 event->command_line = strdup (cmd.c_str());
739 /* this won't be called if the port engine in use is not JACK, so we do
740 not have to worry about the type of PortEngine::private_handle()
743 jack_client_t* jack_client = (jack_client_t*) AudioEngine::instance()->port_engine().private_handle();
746 jack_session_reply (jack_client, event);
749 if (event->type == JackSessionSaveAndQuit) {
750 Quit (); /* EMIT SIGNAL */
753 jack_session_event_free( event );
757 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
759 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
762 std::string xml_path(_session_dir->root_path());
764 if (!_writable || (_state_of_the_state & CannotSave)) {
768 if (!_engine.connected ()) {
769 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
775 /* tell sources we're saving first, in case they write out to a new file
776 * which should be saved with the state rather than the old one */
777 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
779 i->second->session_saved();
780 } catch (Evoral::SMF::FileError& e) {
781 error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
785 SaveSession (); /* EMIT SIGNAL */
787 tree.set_root (&get_state());
789 if (snapshot_name.empty()) {
790 snapshot_name = _current_snapshot_name;
791 } else if (switch_to_snapshot) {
792 _current_snapshot_name = snapshot_name;
797 /* proper save: use statefile_suffix (.ardour in English) */
799 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
801 /* make a backup copy of the old file */
803 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) {
804 // create_backup_file will log the error
810 /* pending save: use pending_suffix (.pending in English) */
811 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
814 std::string tmp_path(_session_dir->root_path());
815 tmp_path = Glib::build_filename (tmp_path, legalize_for_path (snapshot_name) + temp_suffix);
817 // cerr << "actually writing state to " << xml_path << endl;
819 if (!tree.write (tmp_path)) {
820 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
821 if (g_remove (tmp_path.c_str()) != 0) {
822 error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
823 tmp_path, g_strerror (errno)) << endmsg;
829 if (::rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
830 error << string_compose (_("could not rename temporary session file %1 to %2"),
831 tmp_path, xml_path) << endmsg;
832 if (g_remove (tmp_path.c_str()) != 0) {
833 error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
834 tmp_path, g_strerror (errno)) << endmsg;
842 save_history (snapshot_name);
844 bool was_dirty = dirty();
846 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
849 DirtyChanged (); /* EMIT SIGNAL */
852 StateSaved (snapshot_name); /* EMIT SIGNAL */
859 Session::restore_state (string snapshot_name)
861 if (load_state (snapshot_name) == 0) {
862 set_state (*state_tree->root(), Stateful::loading_state_version);
869 Session::load_state (string snapshot_name)
874 state_was_pending = false;
876 /* check for leftover pending state from a crashed capture attempt */
878 std::string xmlpath(_session_dir->root_path());
879 xmlpath = Glib::build_filename (xmlpath, legalize_for_path (snapshot_name) + pending_suffix);
881 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
883 /* there is pending state from a crashed capture attempt */
885 boost::optional<int> r = AskAboutPendingState();
886 if (r.get_value_or (1)) {
887 state_was_pending = true;
891 if (!state_was_pending) {
892 xmlpath = Glib::build_filename (_session_dir->root_path(), snapshot_name);
895 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
896 xmlpath = Glib::build_filename (_session_dir->root_path(), legalize_for_path (snapshot_name) + statefile_suffix);
897 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
898 error << string_compose(_("%1: session file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
903 state_tree = new XMLTree;
907 _writable = exists_and_writable (xmlpath);
909 if (!state_tree->read (xmlpath)) {
910 error << string_compose(_("Could not understand session file %1"), xmlpath) << endmsg;
916 XMLNode& root (*state_tree->root());
918 if (root.name() != X_("Session")) {
919 error << string_compose (_("Session file %1 is not a session"), xmlpath) << endmsg;
925 const XMLProperty* prop;
927 if ((prop = root.property ("version")) == 0) {
928 /* no version implies very old version of Ardour */
929 Stateful::loading_state_version = 1000;
931 if (prop->value().find ('.') != string::npos) {
932 /* old school version format */
933 if (prop->value()[0] == '2') {
934 Stateful::loading_state_version = 2000;
936 Stateful::loading_state_version = 3000;
939 Stateful::loading_state_version = atoi (prop->value());
943 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
945 std::string backup_path(_session_dir->root_path());
946 std::string backup_filename = string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
947 backup_path = Glib::build_filename (backup_path, backup_filename);
949 // only create a backup for a given statefile version once
951 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
953 VersionMismatch (xmlpath, backup_path);
955 if (!copy_file (xmlpath, backup_path)) {;
965 Session::load_options (const XMLNode& node)
967 LocaleGuard lg (X_("POSIX"));
968 config.set_variables (node);
979 Session::get_template()
981 /* if we don't disable rec-enable, diskstreams
982 will believe they need to store their capture
983 sources in their state node.
986 disable_record (false);
992 Session::state (bool full_state)
994 XMLNode* node = new XMLNode("Session");
998 snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
999 node->add_property("version", buf);
1001 /* store configuration settings */
1005 node->add_property ("name", _name);
1006 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1007 node->add_property ("sample-rate", buf);
1009 if (session_dirs.size() > 1) {
1013 vector<space_and_path>::iterator i = session_dirs.begin();
1014 vector<space_and_path>::iterator next;
1016 ++i; /* skip the first one */
1020 while (i != session_dirs.end()) {
1024 if (next != session_dirs.end()) {
1034 child = node->add_child ("Path");
1035 child->add_content (p);
1039 /* save the ID counter */
1041 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1042 node->add_property ("id-counter", buf);
1044 /* save the event ID counter */
1046 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1047 node->add_property ("event-counter", buf);
1049 /* various options */
1051 node->add_child_nocopy (config.get_variables ());
1053 node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
1055 child = node->add_child ("Sources");
1058 Glib::Threads::Mutex::Lock sl (source_lock);
1060 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1062 /* Don't save information about non-file Sources, or
1063 * about non-destructive file sources that are empty
1064 * and unused by any regions.
1067 boost::shared_ptr<FileSource> fs;
1069 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1071 if (!fs->destructive()) {
1072 if (fs->empty() && !fs->used()) {
1077 child->add_child_nocopy (siter->second->get_state());
1082 child = node->add_child ("Regions");
1085 Glib::Threads::Mutex::Lock rl (region_lock);
1086 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1087 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1088 boost::shared_ptr<Region> r = i->second;
1089 /* only store regions not attached to playlists */
1090 if (r->playlist() == 0) {
1091 if (boost::dynamic_pointer_cast<AudioRegion>(r)) {
1092 child->add_child_nocopy ((boost::dynamic_pointer_cast<AudioRegion>(r))->get_basic_state ());
1094 child->add_child_nocopy (r->get_state ());
1099 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1101 if (!cassocs.empty()) {
1102 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1104 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1106 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1107 i->first->id().print (buf, sizeof (buf));
1108 can->add_property (X_("copy"), buf);
1109 i->second->id().print (buf, sizeof (buf));
1110 can->add_property (X_("original"), buf);
1111 ca->add_child_nocopy (*can);
1117 node->add_child_nocopy (_locations->get_state());
1119 // for a template, just create a new Locations, populate it
1120 // with the default start and end, and get the state for that.
1121 Locations loc (*this);
1122 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1123 range->set (max_framepos, 0);
1125 node->add_child_nocopy (loc.get_state());
1128 child = node->add_child ("Bundles");
1130 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1131 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1132 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1134 child->add_child_nocopy (b->get_state());
1139 child = node->add_child ("Routes");
1141 boost::shared_ptr<RouteList> r = routes.reader ();
1143 RoutePublicOrderSorter cmp;
1144 RouteList public_order (*r);
1145 public_order.sort (cmp);
1147 /* the sort should have put control outs first */
1150 assert (_monitor_out == public_order.front());
1153 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1154 if (!(*i)->is_auditioner()) {
1156 child->add_child_nocopy ((*i)->get_state());
1158 child->add_child_nocopy ((*i)->get_template());
1164 playlists->add_state (node, full_state);
1166 child = node->add_child ("RouteGroups");
1167 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1168 child->add_child_nocopy ((*i)->get_state());
1172 XMLNode* gain_child = node->add_child ("Click");
1173 gain_child->add_child_nocopy (_click_io->state (full_state));
1174 gain_child->add_child_nocopy (_click_gain->state (full_state));
1178 XMLNode* ltc_input_child = node->add_child ("LTC-In");
1179 ltc_input_child->add_child_nocopy (_ltc_input->state (full_state));
1183 XMLNode* ltc_output_child = node->add_child ("LTC-Out");
1184 ltc_output_child->add_child_nocopy (_ltc_output->state (full_state));
1187 node->add_child_nocopy (_speakers->get_state());
1188 node->add_child_nocopy (_tempo_map->get_state());
1189 node->add_child_nocopy (get_control_protocol_state());
1192 node->add_child_copy (*_extra_xml);
1199 Session::get_control_protocol_state ()
1201 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1202 return cpm.get_state();
1206 Session::set_state (const XMLNode& node, int version)
1210 const XMLProperty* prop;
1213 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1215 if (node.name() != X_("Session")) {
1216 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1220 if ((prop = node.property ("name")) != 0) {
1221 _name = prop->value ();
1224 if ((prop = node.property (X_("sample-rate"))) != 0) {
1226 _nominal_frame_rate = atoi (prop->value());
1228 if (_nominal_frame_rate != _current_frame_rate) {
1229 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1230 if (r.get_value_or (0)) {
1236 setup_raid_path(_session_dir->root_path());
1238 if ((prop = node.property (X_("id-counter"))) != 0) {
1240 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1241 ID::init_counter (x);
1243 /* old sessions used a timebased counter, so fake
1244 the startup ID counter based on a standard
1249 ID::init_counter (now);
1252 if ((prop = node.property (X_("event-counter"))) != 0) {
1253 Evoral::init_event_id_counter (atoi (prop->value()));
1256 IO::disable_connecting ();
1258 Stateful::save_extra_xml (node);
1260 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1261 load_options (*child);
1262 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1263 load_options (*child);
1265 error << _("Session: XML state has no options section") << endmsg;
1268 if (version >= 3000) {
1269 if ((child = find_named_node (node, "Metadata")) == 0) {
1270 warning << _("Session: XML state has no metadata section") << endmsg;
1271 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1276 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1277 _speakers->set_state (*child, version);
1280 if ((child = find_named_node (node, "Sources")) == 0) {
1281 error << _("Session: XML state has no sources section") << endmsg;
1283 } else if (load_sources (*child)) {
1287 if ((child = find_named_node (node, "TempoMap")) == 0) {
1288 error << _("Session: XML state has no Tempo Map section") << endmsg;
1290 } else if (_tempo_map->set_state (*child, version)) {
1294 if ((child = find_named_node (node, "Locations")) == 0) {
1295 error << _("Session: XML state has no locations section") << endmsg;
1297 } else if (_locations->set_state (*child, version)) {
1303 if ((location = _locations->auto_loop_location()) != 0) {
1304 set_auto_loop_location (location);
1307 if ((location = _locations->auto_punch_location()) != 0) {
1308 set_auto_punch_location (location);
1311 if ((location = _locations->session_range_location()) != 0) {
1312 delete _session_range_location;
1313 _session_range_location = location;
1316 if (_session_range_location) {
1317 AudioFileSource::set_header_position_offset (_session_range_location->start());
1320 if ((child = find_named_node (node, "Regions")) == 0) {
1321 error << _("Session: XML state has no Regions section") << endmsg;
1323 } else if (load_regions (*child)) {
1327 if ((child = find_named_node (node, "Playlists")) == 0) {
1328 error << _("Session: XML state has no playlists section") << endmsg;
1330 } else if (playlists->load (*this, *child)) {
1334 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1336 } else if (playlists->load_unused (*this, *child)) {
1340 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1341 if (load_compounds (*child)) {
1346 if (version >= 3000) {
1347 if ((child = find_named_node (node, "Bundles")) == 0) {
1348 warning << _("Session: XML state has no bundles section") << endmsg;
1351 /* We can't load Bundles yet as they need to be able
1352 to convert from port names to Port objects, which can't happen until
1354 _bundle_xml_node = new XMLNode (*child);
1358 if (version < 3000) {
1359 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1360 error << _("Session: XML state has no diskstreams section") << endmsg;
1362 } else if (load_diskstreams_2X (*child, version)) {
1367 if ((child = find_named_node (node, "Routes")) == 0) {
1368 error << _("Session: XML state has no routes section") << endmsg;
1370 } else if (load_routes (*child, version)) {
1374 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1375 _diskstreams_2X.clear ();
1377 if (version >= 3000) {
1379 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1380 error << _("Session: XML state has no route groups section") << endmsg;
1382 } else if (load_route_groups (*child, version)) {
1386 } else if (version < 3000) {
1388 if ((child = find_named_node (node, "EditGroups")) == 0) {
1389 error << _("Session: XML state has no edit groups section") << endmsg;
1391 } else if (load_route_groups (*child, version)) {
1395 if ((child = find_named_node (node, "MixGroups")) == 0) {
1396 error << _("Session: XML state has no mix groups section") << endmsg;
1398 } else if (load_route_groups (*child, version)) {
1403 if ((child = find_named_node (node, "Click")) == 0) {
1404 warning << _("Session: XML state has no click section") << endmsg;
1405 } else if (_click_io) {
1406 const XMLNodeList& children (child->children());
1407 XMLNodeList::const_iterator i = children.begin();
1408 _click_io->set_state (**i, version);
1410 if (i != children.end()) {
1411 _click_gain->set_state (**i, version);
1415 if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
1416 ControlProtocolManager::instance().set_state (*child, version);
1419 update_have_rec_enabled_track ();
1421 /* here beginneth the second phase ... */
1423 StateReady (); /* EMIT SIGNAL */
1432 Session::load_routes (const XMLNode& node, int version)
1435 XMLNodeConstIterator niter;
1436 RouteList new_routes;
1438 nlist = node.children();
1442 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1444 boost::shared_ptr<Route> route;
1445 if (version < 3000) {
1446 route = XMLRouteFactory_2X (**niter, version);
1448 route = XMLRouteFactory (**niter, version);
1452 error << _("Session: cannot create Route from XML description.") << endmsg;
1456 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1458 new_routes.push_back (route);
1461 add_routes (new_routes, false, false, false);
1466 boost::shared_ptr<Route>
1467 Session::XMLRouteFactory (const XMLNode& node, int version)
1469 boost::shared_ptr<Route> ret;
1471 if (node.name() != "Route") {
1475 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1477 DataType type = DataType::AUDIO;
1478 const XMLProperty* prop = node.property("default-type");
1481 type = DataType (prop->value());
1484 assert (type != DataType::NIL);
1488 boost::shared_ptr<Track> track;
1490 if (type == DataType::AUDIO) {
1491 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1493 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1496 if (track->init()) {
1500 if (track->set_state (node, version)) {
1504 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1505 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1510 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1512 if (r->init () == 0 && r->set_state (node, version) == 0) {
1513 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1514 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1523 boost::shared_ptr<Route>
1524 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1526 boost::shared_ptr<Route> ret;
1528 if (node.name() != "Route") {
1532 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1534 ds_prop = node.property (X_("diskstream"));
1537 DataType type = DataType::AUDIO;
1538 const XMLProperty* prop = node.property("default-type");
1541 type = DataType (prop->value());
1544 assert (type != DataType::NIL);
1548 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1549 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1553 if (i == _diskstreams_2X.end()) {
1554 error << _("Could not find diskstream for route") << endmsg;
1555 return boost::shared_ptr<Route> ();
1558 boost::shared_ptr<Track> track;
1560 if (type == DataType::AUDIO) {
1561 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1563 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1566 if (track->init()) {
1570 if (track->set_state (node, version)) {
1574 track->set_diskstream (*i);
1576 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1577 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1582 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1584 if (r->init () == 0 && r->set_state (node, version) == 0) {
1585 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1586 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1596 Session::load_regions (const XMLNode& node)
1599 XMLNodeConstIterator niter;
1600 boost::shared_ptr<Region> region;
1602 nlist = node.children();
1606 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1607 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1608 error << _("Session: cannot create Region from XML description.");
1609 const XMLProperty *name = (**niter).property("name");
1612 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1623 Session::load_compounds (const XMLNode& node)
1625 XMLNodeList calist = node.children();
1626 XMLNodeConstIterator caiter;
1627 XMLProperty *caprop;
1629 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1630 XMLNode* ca = *caiter;
1634 if ((caprop = ca->property (X_("original"))) == 0) {
1637 orig_id = caprop->value();
1639 if ((caprop = ca->property (X_("copy"))) == 0) {
1642 copy_id = caprop->value();
1644 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1645 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1647 if (!orig || !copy) {
1648 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1654 RegionFactory::add_compound_association (orig, copy);
1661 Session::load_nested_sources (const XMLNode& node)
1664 XMLNodeConstIterator niter;
1666 nlist = node.children();
1668 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1669 if ((*niter)->name() == "Source") {
1671 /* it may already exist, so don't recreate it unnecessarily
1674 XMLProperty* prop = (*niter)->property (X_("id"));
1676 error << _("Nested source has no ID info in session file! (ignored)") << endmsg;
1680 ID source_id (prop->value());
1682 if (!source_by_id (source_id)) {
1685 SourceFactory::create (*this, **niter, true);
1687 catch (failed_constructor& err) {
1688 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1695 boost::shared_ptr<Region>
1696 Session::XMLRegionFactory (const XMLNode& node, bool full)
1698 const XMLProperty* type = node.property("type");
1702 const XMLNodeList& nlist = node.children();
1704 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1705 XMLNode *child = (*niter);
1706 if (child->name() == "NestedSource") {
1707 load_nested_sources (*child);
1711 if (!type || type->value() == "audio") {
1712 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1713 } else if (type->value() == "midi") {
1714 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1717 } catch (failed_constructor& err) {
1718 return boost::shared_ptr<Region> ();
1721 return boost::shared_ptr<Region> ();
1724 boost::shared_ptr<AudioRegion>
1725 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1727 const XMLProperty* prop;
1728 boost::shared_ptr<Source> source;
1729 boost::shared_ptr<AudioSource> as;
1731 SourceList master_sources;
1732 uint32_t nchans = 1;
1735 if (node.name() != X_("Region")) {
1736 return boost::shared_ptr<AudioRegion>();
1739 if ((prop = node.property (X_("channels"))) != 0) {
1740 nchans = atoi (prop->value().c_str());
1743 if ((prop = node.property ("name")) == 0) {
1744 cerr << "no name for this region\n";
1748 if ((prop = node.property (X_("source-0"))) == 0) {
1749 if ((prop = node.property ("source")) == 0) {
1750 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1751 return boost::shared_ptr<AudioRegion>();
1755 PBD::ID s_id (prop->value());
1757 if ((source = source_by_id (s_id)) == 0) {
1758 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1759 return boost::shared_ptr<AudioRegion>();
1762 as = boost::dynamic_pointer_cast<AudioSource>(source);
1764 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1765 return boost::shared_ptr<AudioRegion>();
1768 sources.push_back (as);
1770 /* pickup other channels */
1772 for (uint32_t n=1; n < nchans; ++n) {
1773 snprintf (buf, sizeof(buf), X_("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 sources.push_back (as);
1792 for (uint32_t n = 0; n < nchans; ++n) {
1793 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1794 if ((prop = node.property (buf)) != 0) {
1796 PBD::ID id2 (prop->value());
1798 if ((source = source_by_id (id2)) == 0) {
1799 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1800 return boost::shared_ptr<AudioRegion>();
1803 as = boost::dynamic_pointer_cast<AudioSource>(source);
1805 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1806 return boost::shared_ptr<AudioRegion>();
1808 master_sources.push_back (as);
1813 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1815 /* a final detail: this is the one and only place that we know how long missing files are */
1817 if (region->whole_file()) {
1818 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1819 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1821 sfp->set_length (region->length());
1826 if (!master_sources.empty()) {
1827 if (master_sources.size() != nchans) {
1828 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1830 region->set_master_sources (master_sources);
1838 catch (failed_constructor& err) {
1839 return boost::shared_ptr<AudioRegion>();
1843 boost::shared_ptr<MidiRegion>
1844 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1846 const XMLProperty* prop;
1847 boost::shared_ptr<Source> source;
1848 boost::shared_ptr<MidiSource> ms;
1851 if (node.name() != X_("Region")) {
1852 return boost::shared_ptr<MidiRegion>();
1855 if ((prop = node.property ("name")) == 0) {
1856 cerr << "no name for this region\n";
1860 if ((prop = node.property (X_("source-0"))) == 0) {
1861 if ((prop = node.property ("source")) == 0) {
1862 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1863 return boost::shared_ptr<MidiRegion>();
1867 PBD::ID s_id (prop->value());
1869 if ((source = source_by_id (s_id)) == 0) {
1870 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1871 return boost::shared_ptr<MidiRegion>();
1874 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1876 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1877 return boost::shared_ptr<MidiRegion>();
1880 sources.push_back (ms);
1883 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1884 /* a final detail: this is the one and only place that we know how long missing files are */
1886 if (region->whole_file()) {
1887 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1888 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1890 sfp->set_length (region->length());
1898 catch (failed_constructor& err) {
1899 return boost::shared_ptr<MidiRegion>();
1904 Session::get_sources_as_xml ()
1907 XMLNode* node = new XMLNode (X_("Sources"));
1908 Glib::Threads::Mutex::Lock lm (source_lock);
1910 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1911 node->add_child_nocopy (i->second->get_state());
1918 Session::path_from_region_name (DataType type, string name, string identifier)
1920 char buf[PATH_MAX+1];
1922 SessionDirectory sdir(get_best_session_directory_for_new_source());
1923 std::string source_dir = ((type == DataType::AUDIO)
1924 ? sdir.sound_path() : sdir.midi_path());
1926 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1928 for (n = 0; n < 999999; ++n) {
1929 if (identifier.length()) {
1930 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1931 identifier.c_str(), n, ext.c_str());
1933 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1937 std::string source_path = Glib::build_filename (source_dir, buf);
1939 if (!Glib::file_test (source_path, Glib::FILE_TEST_EXISTS)) {
1944 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1953 Session::load_sources (const XMLNode& node)
1956 XMLNodeConstIterator niter;
1957 boost::shared_ptr<Source> source;
1959 nlist = node.children();
1963 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1966 if ((source = XMLSourceFactory (**niter)) == 0) {
1967 error << _("Session: cannot create Source from XML description.") << endmsg;
1970 } catch (MissingSource& err) {
1974 if (!no_questions_about_missing_files) {
1975 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1980 switch (user_choice) {
1982 /* user added a new search location, so try again */
1987 /* user asked to quit the entire session load
1992 no_questions_about_missing_files = true;
1996 no_questions_about_missing_files = true;
2001 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
2002 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2011 boost::shared_ptr<Source>
2012 Session::XMLSourceFactory (const XMLNode& node)
2014 if (node.name() != "Source") {
2015 return boost::shared_ptr<Source>();
2019 /* note: do peak building in another thread when loading session state */
2020 return SourceFactory::create (*this, node, true);
2023 catch (failed_constructor& err) {
2024 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2025 return boost::shared_ptr<Source>();
2030 Session::save_template (string template_name)
2034 if (_state_of_the_state & CannotSave) {
2038 std::string user_template_dir(user_template_directory());
2040 if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
2041 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2042 user_template_dir, g_strerror (errno)) << endmsg;
2046 tree.set_root (&get_template());
2048 std::string template_dir_path(user_template_dir);
2050 /* directory to put the template in */
2051 template_dir_path = Glib::build_filename (template_dir_path, template_name);
2053 if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
2054 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2055 template_dir_path) << endmsg;
2059 if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
2060 error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
2061 template_dir_path, g_strerror (errno)) << endmsg;
2066 std::string template_file_path(template_dir_path);
2067 template_file_path = Glib::build_filename (template_file_path, template_name + template_suffix);
2069 if (!tree.write (template_file_path)) {
2070 error << _("template not saved") << endmsg;
2074 /* copy plugin state directory */
2076 std::string template_plugin_state_path(template_dir_path);
2077 template_plugin_state_path = Glib::build_filename (template_plugin_state_path, X_("plugins"));
2079 if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
2080 error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
2081 template_plugin_state_path, g_strerror (errno)) << endmsg;
2085 copy_files (plugins_dir(), template_plugin_state_path);
2091 Session::refresh_disk_space ()
2093 #if __APPLE__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
2095 Glib::Threads::Mutex::Lock lm (space_lock);
2097 /* get freespace on every FS that is part of the session path */
2099 _total_free_4k_blocks = 0;
2100 _total_free_4k_blocks_uncertain = false;
2102 for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2104 struct statfs statfsbuf;
2105 statfs (i->path.c_str(), &statfsbuf);
2107 double const scale = statfsbuf.f_bsize / 4096.0;
2109 /* See if this filesystem is read-only */
2110 struct statvfs statvfsbuf;
2111 statvfs (i->path.c_str(), &statvfsbuf);
2113 /* f_bavail can be 0 if it is undefined for whatever
2114 filesystem we are looking at; Samba shares mounted
2115 via GVFS are an example of this.
2117 if (statfsbuf.f_bavail == 0) {
2118 /* block count unknown */
2120 i->blocks_unknown = true;
2121 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2122 /* read-only filesystem */
2124 i->blocks_unknown = false;
2126 /* read/write filesystem with known space */
2127 i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2128 i->blocks_unknown = false;
2131 _total_free_4k_blocks += i->blocks;
2132 if (i->blocks_unknown) {
2133 _total_free_4k_blocks_uncertain = true;
2140 Session::get_best_session_directory_for_new_source ()
2142 vector<space_and_path>::iterator i;
2143 string result = _session_dir->root_path();
2145 /* handle common case without system calls */
2147 if (session_dirs.size() == 1) {
2151 /* OK, here's the algorithm we're following here:
2153 We want to select which directory to use for
2154 the next file source to be created. Ideally,
2155 we'd like to use a round-robin process so as to
2156 get maximum performance benefits from splitting
2157 the files across multiple disks.
2159 However, in situations without much diskspace, an
2160 RR approach may end up filling up a filesystem
2161 with new files while others still have space.
2162 Its therefore important to pay some attention to
2163 the freespace in the filesystem holding each
2164 directory as well. However, if we did that by
2165 itself, we'd keep creating new files in the file
2166 system with the most space until it was as full
2167 as all others, thus negating any performance
2168 benefits of this RAID-1 like approach.
2170 So, we use a user-configurable space threshold. If
2171 there are at least 2 filesystems with more than this
2172 much space available, we use RR selection between them.
2173 If not, then we pick the filesystem with the most space.
2175 This gets a good balance between the two
2179 refresh_disk_space ();
2181 int free_enough = 0;
2183 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2184 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2189 if (free_enough >= 2) {
2190 /* use RR selection process, ensuring that the one
2194 i = last_rr_session_dir;
2197 if (++i == session_dirs.end()) {
2198 i = session_dirs.begin();
2201 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2202 SessionDirectory sdir(i->path);
2203 if (sdir.create ()) {
2205 last_rr_session_dir = i;
2210 } while (i != last_rr_session_dir);
2214 /* pick FS with the most freespace (and that
2215 seems to actually work ...)
2218 vector<space_and_path> sorted;
2219 space_and_path_ascending_cmp cmp;
2221 sorted = session_dirs;
2222 sort (sorted.begin(), sorted.end(), cmp);
2224 for (i = sorted.begin(); i != sorted.end(); ++i) {
2225 SessionDirectory sdir(i->path);
2226 if (sdir.create ()) {
2228 last_rr_session_dir = i;
2238 Session::automation_dir () const
2240 return Glib::build_filename (_path, "automation");
2244 Session::analysis_dir () const
2246 return Glib::build_filename (_path, "analysis");
2250 Session::plugins_dir () const
2252 return Glib::build_filename (_path, "plugins");
2256 Session::externals_dir () const
2258 return Glib::build_filename (_path, "externals");
2262 Session::load_bundles (XMLNode const & node)
2264 XMLNodeList nlist = node.children();
2265 XMLNodeConstIterator niter;
2269 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2270 if ((*niter)->name() == "InputBundle") {
2271 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2272 } else if ((*niter)->name() == "OutputBundle") {
2273 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2275 error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
2284 Session::load_route_groups (const XMLNode& node, int version)
2286 XMLNodeList nlist = node.children();
2287 XMLNodeConstIterator niter;
2291 if (version >= 3000) {
2293 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2294 if ((*niter)->name() == "RouteGroup") {
2295 RouteGroup* rg = new RouteGroup (*this, "");
2296 add_route_group (rg);
2297 rg->set_state (**niter, version);
2301 } else if (version < 3000) {
2303 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2304 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2305 RouteGroup* rg = new RouteGroup (*this, "");
2306 add_route_group (rg);
2307 rg->set_state (**niter, version);
2316 Session::auto_save()
2318 save_state (_current_snapshot_name);
2322 state_file_filter (const string &str, void */*arg*/)
2324 return (str.length() > strlen(statefile_suffix) &&
2325 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2329 bool operator()(const string* a, const string* b) {
2335 remove_end(string* state)
2337 string statename(*state);
2339 string::size_type start,end;
2340 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2341 statename = statename.substr (start+1);
2344 if ((end = statename.rfind(".ardour")) == string::npos) {
2345 end = statename.length();
2348 return new string(statename.substr (0, end));
2352 Session::possible_states (string path)
2354 PathScanner scanner;
2355 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2357 transform(states->begin(), states->end(), states->begin(), remove_end);
2360 sort (states->begin(), states->end(), cmp);
2366 Session::possible_states () const
2368 return possible_states(_path);
2372 Session::add_route_group (RouteGroup* g)
2374 _route_groups.push_back (g);
2375 route_group_added (g); /* EMIT SIGNAL */
2377 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2378 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2379 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2385 Session::remove_route_group (RouteGroup& rg)
2387 list<RouteGroup*>::iterator i;
2389 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2390 _route_groups.erase (i);
2393 route_group_removed (); /* EMIT SIGNAL */
2397 /** Set a new order for our route groups, without adding or removing any.
2398 * @param groups Route group list in the new order.
2401 Session::reorder_route_groups (list<RouteGroup*> groups)
2403 _route_groups = groups;
2405 route_groups_reordered (); /* EMIT SIGNAL */
2411 Session::route_group_by_name (string name)
2413 list<RouteGroup *>::iterator i;
2415 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2416 if ((*i)->name() == name) {
2424 Session::all_route_group() const
2426 return *_all_route_group;
2430 Session::add_commands (vector<Command*> const & cmds)
2432 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2438 Session::begin_reversible_command (const string& name)
2440 begin_reversible_command (g_quark_from_string (name.c_str ()));
2443 /** Begin a reversible command using a GQuark to identify it.
2444 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2445 * but there must be as many begin...()s as there are commit...()s.
2448 Session::begin_reversible_command (GQuark q)
2450 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2451 to hold all the commands that are committed. This keeps the order of
2452 commands correct in the history.
2455 if (_current_trans == 0) {
2456 /* start a new transaction */
2457 assert (_current_trans_quarks.empty ());
2458 _current_trans = new UndoTransaction();
2459 _current_trans->set_name (g_quark_to_string (q));
2462 _current_trans_quarks.push_front (q);
2466 Session::commit_reversible_command (Command *cmd)
2468 assert (_current_trans);
2469 assert (!_current_trans_quarks.empty ());
2474 _current_trans->add_command (cmd);
2477 _current_trans_quarks.pop_front ();
2479 if (!_current_trans_quarks.empty ()) {
2480 /* the transaction we're committing is not the top-level one */
2484 if (_current_trans->empty()) {
2485 /* no commands were added to the transaction, so just get rid of it */
2486 delete _current_trans;
2491 gettimeofday (&now, 0);
2492 _current_trans->set_timestamp (now);
2494 _history.add (_current_trans);
2499 accept_all_audio_files (const string& path, void */*arg*/)
2501 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2505 if (!AudioFileSource::safe_audio_file_extension (path)) {
2513 accept_all_midi_files (const string& path, void */*arg*/)
2515 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2519 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2520 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2521 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2525 accept_all_state_files (const string& path, void */*arg*/)
2527 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2531 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2535 Session::find_all_sources (string path, set<string>& result)
2540 if (!tree.read (path)) {
2544 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2549 XMLNodeConstIterator niter;
2551 nlist = node->children();
2555 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2559 if ((prop = (*niter)->property (X_("type"))) == 0) {
2563 DataType type (prop->value());
2565 if ((prop = (*niter)->property (X_("name"))) == 0) {
2569 if (Glib::path_is_absolute (prop->value())) {
2570 /* external file, ignore */
2578 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2579 result.insert (found_path);
2587 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2589 PathScanner scanner;
2590 vector<string*>* state_files;
2592 string this_snapshot_path;
2598 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2599 ripped = ripped.substr (0, ripped.length() - 1);
2602 state_files = scanner (ripped, accept_all_state_files, (void *) 0, true, true);
2604 if (state_files == 0) {
2609 this_snapshot_path = _path;
2610 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2611 this_snapshot_path += statefile_suffix;
2613 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2615 if (exclude_this_snapshot && **i == this_snapshot_path) {
2619 if (find_all_sources (**i, result) < 0) {
2627 struct RegionCounter {
2628 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2629 AudioSourceList::iterator iter;
2630 boost::shared_ptr<Region> region;
2633 RegionCounter() : count (0) {}
2637 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2639 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2640 return r.get_value_or (1);
2644 Session::cleanup_regions ()
2646 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2648 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2650 uint32_t used = playlists->region_use_count (i->second);
2652 if (used == 0 && !i->second->automatic ()) {
2653 RegionFactory::map_remove (i->second);
2657 /* dump the history list */
2664 Session::cleanup_sources (CleanupReport& rep)
2666 // FIXME: needs adaptation to midi
2668 vector<boost::shared_ptr<Source> > dead_sources;
2669 PathScanner scanner;
2672 vector<space_and_path>::iterator i;
2673 vector<space_and_path>::iterator nexti;
2674 vector<string*>* candidates;
2675 vector<string*>* candidates2;
2676 vector<string> unused;
2677 set<string> all_sources;
2682 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2684 /* consider deleting all unused playlists */
2686 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2691 /* sync the "all regions" property of each playlist with its current state
2694 playlists->sync_all_regions_with_regions ();
2696 /* find all un-used sources */
2701 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2703 SourceMap::iterator tmp;
2708 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2712 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2713 dead_sources.push_back (i->second);
2714 i->second->drop_references ();
2720 /* build a list of all the possible audio directories for the session */
2722 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2727 SessionDirectory sdir ((*i).path);
2728 audio_path += sdir.sound_path();
2730 if (nexti != session_dirs.end()) {
2738 /* build a list of all the possible midi directories for the session */
2740 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2745 SessionDirectory sdir ((*i).path);
2746 midi_path += sdir.midi_path();
2748 if (nexti != session_dirs.end()) {
2755 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2756 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2762 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2763 candidates->push_back (*i);
2768 candidates = candidates2; // might still be null
2771 /* find all sources, but don't use this snapshot because the
2772 state file on disk still references sources we may have already
2776 find_all_sources_across_snapshots (all_sources, true);
2778 /* add our current source list
2781 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2782 boost::shared_ptr<FileSource> fs;
2783 SourceMap::iterator tmp = i;
2786 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2787 if (playlists->source_use_count (fs) != 0) {
2788 all_sources.insert (fs->path());
2791 /* we might not remove this source from disk, because it may be used
2792 by other snapshots, but its not being used in this version
2793 so lets get rid of it now, along with any representative regions
2797 RegionFactory::remove_regions_using_source (i->second);
2805 char tmppath1[PATH_MAX+1];
2806 char tmppath2[PATH_MAX+1];
2809 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2814 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2816 if (realpath(spath.c_str(), tmppath1) == 0) {
2817 error << string_compose (_("Cannot expand path %1 (%2)"),
2818 spath, strerror (errno)) << endmsg;
2822 if (realpath((*i).c_str(), tmppath2) == 0) {
2823 error << string_compose (_("Cannot expand path %1 (%2)"),
2824 (*i), strerror (errno)) << endmsg;
2828 if (strcmp(tmppath1, tmppath2) == 0) {
2835 unused.push_back (spath);
2844 /* now try to move all unused files into the "dead" directory(ies) */
2846 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2847 struct stat statbuf;
2851 /* don't move the file across filesystems, just
2852 stick it in the `dead_dir_name' directory
2853 on whichever filesystem it was already on.
2856 if ((*x).find ("/sounds/") != string::npos) {
2858 /* old school, go up 1 level */
2860 newpath = Glib::path_get_dirname (*x); // "sounds"
2861 newpath = Glib::path_get_dirname (newpath); // "session-name"
2865 /* new school, go up 4 levels */
2867 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2868 newpath = Glib::path_get_dirname (newpath); // "session-name"
2869 newpath = Glib::path_get_dirname (newpath); // "interchange"
2870 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2873 newpath = Glib::build_filename (newpath, dead_dir_name);
2875 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2876 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2880 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2882 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2884 /* the new path already exists, try versioning */
2886 char buf[PATH_MAX+1];
2890 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2893 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2894 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2898 if (version == 999) {
2899 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2903 newpath = newpath_v;
2908 /* it doesn't exist, or we can't read it or something */
2912 stat ((*x).c_str(), &statbuf);
2914 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2915 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2916 (*x), newpath, strerror (errno))
2921 /* see if there an easy to find peakfile for this file, and remove it.
2924 string base = basename_nosuffix (*x);
2925 base += "%A"; /* this is what we add for the channel suffix of all native files,
2926 or for the first channel of embedded files. it will miss
2927 some peakfiles for other channels
2929 string peakpath = peak_path (base);
2931 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2932 if (::unlink (peakpath.c_str()) != 0) {
2933 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2934 peakpath, _path, strerror (errno))
2936 /* try to back out */
2937 ::rename (newpath.c_str(), _path.c_str());
2942 rep.paths.push_back (*x);
2943 rep.space += statbuf.st_size;
2946 /* dump the history list */
2950 /* save state so we don't end up a session file
2951 referring to non-existent sources.
2958 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2964 Session::cleanup_trash_sources (CleanupReport& rep)
2966 // FIXME: needs adaptation for MIDI
2968 vector<space_and_path>::iterator i;
2974 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2976 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2978 clear_directory (dead_dir, &rep.space, &rep.paths);
2985 Session::set_dirty ()
2987 bool was_dirty = dirty();
2989 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2993 DirtyChanged(); /* EMIT SIGNAL */
2999 Session::set_clean ()
3001 bool was_dirty = dirty();
3003 _state_of_the_state = Clean;
3007 DirtyChanged(); /* EMIT SIGNAL */
3012 Session::set_deletion_in_progress ()
3014 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3018 Session::clear_deletion_in_progress ()
3020 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3024 Session::add_controllable (boost::shared_ptr<Controllable> c)
3026 /* this adds a controllable to the list managed by the Session.
3027 this is a subset of those managed by the Controllable class
3028 itself, and represents the only ones whose state will be saved
3029 as part of the session.
3032 Glib::Threads::Mutex::Lock lm (controllables_lock);
3033 controllables.insert (c);
3036 struct null_deleter { void operator()(void const *) const {} };
3039 Session::remove_controllable (Controllable* c)
3041 if (_state_of_the_state & Deletion) {
3045 Glib::Threads::Mutex::Lock lm (controllables_lock);
3047 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3049 if (x != controllables.end()) {
3050 controllables.erase (x);
3054 boost::shared_ptr<Controllable>
3055 Session::controllable_by_id (const PBD::ID& id)
3057 Glib::Threads::Mutex::Lock lm (controllables_lock);
3059 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3060 if ((*i)->id() == id) {
3065 return boost::shared_ptr<Controllable>();
3068 boost::shared_ptr<Controllable>
3069 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3071 boost::shared_ptr<Controllable> c;
3072 boost::shared_ptr<Route> r;
3074 switch (desc.top_level_type()) {
3075 case ControllableDescriptor::NamedRoute:
3077 std::string str = desc.top_level_name();
3078 if (str == "master") {
3080 } else if (str == "control" || str == "listen") {
3083 r = route_by_name (desc.top_level_name());
3088 case ControllableDescriptor::RemoteControlID:
3089 r = route_by_remote_id (desc.rid());
3097 switch (desc.subtype()) {
3098 case ControllableDescriptor::Gain:
3099 c = r->gain_control ();
3102 case ControllableDescriptor::Solo:
3103 c = r->solo_control();
3106 case ControllableDescriptor::Mute:
3107 c = r->mute_control();
3110 case ControllableDescriptor::Recenable:
3112 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3115 c = t->rec_enable_control ();
3120 case ControllableDescriptor::PanDirection:
3122 c = r->pannable()->pan_azimuth_control;
3126 case ControllableDescriptor::PanWidth:
3128 c = r->pannable()->pan_width_control;
3132 case ControllableDescriptor::PanElevation:
3134 c = r->pannable()->pan_elevation_control;
3138 case ControllableDescriptor::Balance:
3139 /* XXX simple pan control */
3142 case ControllableDescriptor::PluginParameter:
3144 uint32_t plugin = desc.target (0);
3145 uint32_t parameter_index = desc.target (1);
3147 /* revert to zero based counting */
3153 if (parameter_index > 0) {
3157 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3160 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3161 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3166 case ControllableDescriptor::SendGain:
3168 uint32_t send = desc.target (0);
3170 /* revert to zero-based counting */
3176 boost::shared_ptr<Processor> p = r->nth_send (send);
3179 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3180 boost::shared_ptr<Amp> a = s->amp();
3183 c = s->amp()->gain_control();
3190 /* relax and return a null pointer */
3198 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3201 Stateful::add_instant_xml (node, _path);
3204 if (write_to_config) {
3205 Config->add_instant_xml (node);
3210 Session::instant_xml (const string& node_name)
3212 return Stateful::instant_xml (node_name, _path);
3216 Session::save_history (string snapshot_name)
3224 if (snapshot_name.empty()) {
3225 snapshot_name = _current_snapshot_name;
3228 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3229 const string backup_filename = history_filename + backup_suffix;
3230 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3231 const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3233 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3234 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3235 error << _("could not backup old history file, current history not saved") << endmsg;
3240 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3244 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3246 if (!tree.write (xml_path))
3248 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3250 if (g_remove (xml_path.c_str()) != 0) {
3251 error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3252 xml_path, g_strerror (errno)) << endmsg;
3254 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3255 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3256 backup_path, g_strerror (errno)) << endmsg;
3266 Session::restore_history (string snapshot_name)
3270 if (snapshot_name.empty()) {
3271 snapshot_name = _current_snapshot_name;
3274 const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3275 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3277 info << "Loading history from " << xml_path << endmsg;
3279 if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3280 info << string_compose (_("%1: no history file \"%2\" for this session."),
3281 _name, xml_path) << endmsg;
3285 if (!tree.read (xml_path)) {
3286 error << string_compose (_("Could not understand session history file \"%1\""),
3287 xml_path) << endmsg;
3294 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3297 UndoTransaction* ut = new UndoTransaction ();
3300 ut->set_name(t->property("name")->value());
3301 stringstream ss(t->property("tv-sec")->value());
3303 ss.str(t->property("tv-usec")->value());
3305 ut->set_timestamp(tv);
3307 for (XMLNodeConstIterator child_it = t->children().begin();
3308 child_it != t->children().end(); child_it++)
3310 XMLNode *n = *child_it;
3313 if (n->name() == "MementoCommand" ||
3314 n->name() == "MementoUndoCommand" ||
3315 n->name() == "MementoRedoCommand") {
3317 if ((c = memento_command_factory(n))) {
3321 } else if (n->name() == "NoteDiffCommand") {
3322 PBD::ID id (n->property("midi-source")->value());
3323 boost::shared_ptr<MidiSource> midi_source =
3324 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3326 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3328 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3331 } else if (n->name() == "SysExDiffCommand") {
3333 PBD::ID id (n->property("midi-source")->value());
3334 boost::shared_ptr<MidiSource> midi_source =
3335 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3337 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3339 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3342 } else if (n->name() == "PatchChangeDiffCommand") {
3344 PBD::ID id (n->property("midi-source")->value());
3345 boost::shared_ptr<MidiSource> midi_source =
3346 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3348 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3350 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3353 } else if (n->name() == "StatefulDiffCommand") {
3354 if ((c = stateful_diff_command_factory (n))) {
3355 ut->add_command (c);
3358 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3369 Session::config_changed (std::string p, bool ours)
3375 if (p == "seamless-loop") {
3377 } else if (p == "rf-speed") {
3379 } else if (p == "auto-loop") {
3381 } else if (p == "auto-input") {
3383 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3384 /* auto-input only makes a difference if we're rolling */
3385 set_track_monitor_input_status (!config.get_auto_input());
3388 } else if (p == "punch-in") {
3392 if ((location = _locations->auto_punch_location()) != 0) {
3394 if (config.get_punch_in ()) {
3395 replace_event (SessionEvent::PunchIn, location->start());
3397 remove_event (location->start(), SessionEvent::PunchIn);
3401 } else if (p == "punch-out") {
3405 if ((location = _locations->auto_punch_location()) != 0) {
3407 if (config.get_punch_out()) {
3408 replace_event (SessionEvent::PunchOut, location->end());
3410 clear_events (SessionEvent::PunchOut);
3414 } else if (p == "edit-mode") {
3416 Glib::Threads::Mutex::Lock lm (playlists->lock);
3418 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3419 (*i)->set_edit_mode (Config->get_edit_mode ());
3422 } else if (p == "use-video-sync") {
3424 waiting_for_sync_offset = config.get_use_video_sync();
3426 } else if (p == "mmc-control") {
3428 //poke_midi_thread ();
3430 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3432 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3434 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3436 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3438 } else if (p == "midi-control") {
3440 //poke_midi_thread ();
3442 } else if (p == "raid-path") {
3444 setup_raid_path (config.get_raid_path());
3446 } else if (p == "timecode-format") {
3450 } else if (p == "video-pullup") {
3454 } else if (p == "seamless-loop") {
3456 if (play_loop && transport_rolling()) {
3457 // to reset diskstreams etc
3458 request_play_loop (true);
3461 } else if (p == "rf-speed") {
3463 cumulative_rf_motion = 0;
3466 } else if (p == "click-sound") {
3468 setup_click_sounds (1);
3470 } else if (p == "click-emphasis-sound") {
3472 setup_click_sounds (-1);
3474 } else if (p == "clicking") {
3476 if (Config->get_clicking()) {
3477 if (_click_io && click_data) { // don't require emphasis data
3484 } else if (p == "click-gain") {
3487 _click_gain->set_gain (Config->get_click_gain(), this);
3490 } else if (p == "send-mtc") {
3492 if (Config->get_send_mtc ()) {
3493 /* mark us ready to send */
3494 next_quarter_frame_to_send = 0;
3497 } else if (p == "send-mmc") {
3499 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3501 } else if (p == "midi-feedback") {
3503 session_midi_feedback = Config->get_midi_feedback();
3505 } else if (p == "jack-time-master") {
3507 engine().reset_timebase ();
3509 } else if (p == "native-file-header-format") {
3511 if (!first_file_header_format_reset) {
3512 reset_native_file_format ();
3515 first_file_header_format_reset = false;
3517 } else if (p == "native-file-data-format") {
3519 if (!first_file_data_format_reset) {
3520 reset_native_file_format ();
3523 first_file_data_format_reset = false;
3525 } else if (p == "external-sync") {
3526 if (!config.get_external_sync()) {
3527 drop_sync_source ();
3529 switch_to_sync_source (Config->get_sync_source());
3531 } else if (p == "denormal-model") {
3533 } else if (p == "history-depth") {
3534 set_history_depth (Config->get_history_depth());
3535 } else if (p == "remote-model") {
3536 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
3539 } else if (p == "sync-all-route-ordering") {
3541 /* sync to editor order unless mixer is used for remote IDs
3544 switch (Config->get_remote_model()) {
3546 sync_order_keys (EditorSort);
3549 sync_order_keys (EditorSort);
3552 sync_order_keys (MixerSort);
3555 } else if (p == "initial-program-change") {
3557 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3560 buf[0] = MIDI::program; // channel zero by default
3561 buf[1] = (Config->get_initial_program_change() & 0x7f);
3563 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3565 } else if (p == "solo-mute-override") {
3566 // catch_up_on_solo_mute_override ();
3567 } else if (p == "listen-position" || p == "pfl-position") {
3568 listen_position_changed ();
3569 } else if (p == "solo-control-is-listen-control") {
3570 solo_control_mode_changed ();
3571 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3572 last_timecode_valid = false;
3573 } else if (p == "playback-buffer-seconds") {
3574 AudioSource::allocate_working_buffers (frame_rate());
3575 } else if (p == "automation-thinning-factor") {
3576 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3577 } else if (p == "ltc-source-port") {
3578 reconnect_ltc_input ();
3579 } else if (p == "ltc-sink-port") {
3580 reconnect_ltc_output ();
3581 } else if (p == "timecode-generator-offset") {
3582 ltc_tx_parse_offset();
3589 Session::set_history_depth (uint32_t d)
3591 _history.set_depth (d);
3595 Session::load_diskstreams_2X (XMLNode const & node, int)
3598 XMLNodeConstIterator citer;
3600 clist = node.children();
3602 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3605 /* diskstreams added automatically by DiskstreamCreated handler */
3606 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3607 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3608 _diskstreams_2X.push_back (dsp);
3610 error << _("Session: unknown diskstream type in XML") << endmsg;
3614 catch (failed_constructor& err) {
3615 error << _("Session: could not load diskstream via XML state") << endmsg;
3623 /** Connect things to the MMC object */
3625 Session::setup_midi_machine_control ()
3627 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3629 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3630 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3631 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3632 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3633 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3634 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3635 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3636 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3637 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3638 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3639 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3640 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3641 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3643 /* also handle MIDI SPP because its so common */
3645 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3646 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3647 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3650 boost::shared_ptr<Controllable>
3651 Session::solo_cut_control() const
3653 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3654 controls in Ardour that currently get presented to the user in the GUI that require
3655 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3657 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3658 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3662 return _solo_cut_control;
3666 Session::rename (const std::string& new_name)
3668 string legal_name = legalize_for_path (new_name);
3674 string const old_sources_root = _session_dir->sources_root();
3676 #define RENAME ::rename
3681 * interchange subdirectory
3685 * Backup files are left unchanged and not renamed.
3688 /* pass one: not 100% safe check that the new directory names don't
3692 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3697 /* this is a stupid hack because Glib::path_get_dirname() is
3698 * lexical-only, and so passing it /a/b/c/ gives a different
3699 * result than passing it /a/b/c ...
3702 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3703 oldstr = oldstr.substr (0, oldstr.length() - 1);
3706 string base = Glib::path_get_dirname (oldstr);
3707 string p = Glib::path_get_basename (oldstr);
3709 newstr = Glib::build_filename (base, legal_name);
3711 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3718 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3723 /* this is a stupid hack because Glib::path_get_dirname() is
3724 * lexical-only, and so passing it /a/b/c/ gives a different
3725 * result than passing it /a/b/c ...
3728 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3729 oldstr = oldstr.substr (0, oldstr.length() - 1);
3732 string base = Glib::path_get_dirname (oldstr);
3733 string p = Glib::path_get_basename (oldstr);
3735 newstr = Glib::build_filename (base, legal_name);
3737 cerr << "Rename " << oldstr << " => " << newstr << endl;
3739 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3744 (*_session_dir) = newstr;
3749 /* directory below interchange */
3751 v.push_back (newstr);
3752 v.push_back (interchange_dir_name);
3755 oldstr = Glib::build_filename (v);
3758 v.push_back (newstr);
3759 v.push_back (interchange_dir_name);
3760 v.push_back (legal_name);
3762 newstr = Glib::build_filename (v);
3764 cerr << "Rename " << oldstr << " => " << newstr << endl;
3766 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3773 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3774 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3776 cerr << "Rename " << oldstr << " => " << newstr << endl;
3778 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3785 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3787 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3788 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3790 cerr << "Rename " << oldstr << " => " << newstr << endl;
3792 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3797 /* update file source paths */
3799 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3800 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3802 string p = fs->path ();
3803 boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3808 /* remove old name from recent sessions */
3810 remove_recent_sessions (_path);
3813 _current_snapshot_name = new_name;
3818 /* save state again to get everything just right */
3820 save_state (_current_snapshot_name);
3823 /* add to recent sessions */
3825 store_recent_sessions (new_name, _path);