2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "libardour-config.h"
31 #include <cstdio> /* snprintf(3) ... grrr */
45 #include <sys/param.h>
46 #include <sys/mount.h>
49 #ifdef HAVE_SYS_STATVFS_H
50 #include <sys/statvfs.h>
54 #include <glib/gstdio.h>
57 #include <glibmm/thread.h>
59 #include <boost/algorithm/string.hpp>
61 #include "midi++/mmc.h"
62 #include "midi++/port.h"
63 #include "midi++/manager.h"
65 #include "evoral/SMF.hpp"
67 #include "pbd/boost_debug.h"
68 #include "pbd/basename.h"
69 #include "pbd/controllable_descriptor.h"
70 #include "pbd/enumwriter.h"
71 #include "pbd/error.h"
72 #include "pbd/filesystem.h"
73 #include "pbd/file_utils.h"
74 #include "pbd/pathscanner.h"
75 #include "pbd/pthread_utils.h"
76 #include "pbd/search_path.h"
77 #include "pbd/stacktrace.h"
78 #include "pbd/convert.h"
79 #include "pbd/clear_dir.h"
81 #include "ardour/amp.h"
82 #include "ardour/audio_diskstream.h"
83 #include "ardour/audio_track.h"
84 #include "ardour/audioengine.h"
85 #include "ardour/audiofilesource.h"
86 #include "ardour/audioregion.h"
87 #include "ardour/automation_control.h"
88 #include "ardour/butler.h"
89 #include "ardour/control_protocol_manager.h"
90 #include "ardour/directory_names.h"
91 #include "ardour/filename_extensions.h"
92 #include "ardour/location.h"
93 #include "ardour/midi_model.h"
94 #include "ardour/midi_patch_manager.h"
95 #include "ardour/midi_region.h"
96 #include "ardour/midi_source.h"
97 #include "ardour/midi_track.h"
98 #include "ardour/named_selection.h"
99 #include "ardour/pannable.h"
100 #include "ardour/playlist_factory.h"
101 #include "ardour/port.h"
102 #include "ardour/processor.h"
103 #include "ardour/proxy_controllable.h"
104 #include "ardour/recent_sessions.h"
105 #include "ardour/region_factory.h"
106 #include "ardour/route_group.h"
107 #include "ardour/send.h"
108 #include "ardour/session.h"
109 #include "ardour/session_directory.h"
110 #include "ardour/session_metadata.h"
111 #include "ardour/session_playlists.h"
112 #include "ardour/session_state_utils.h"
113 #include "ardour/session_utils.h"
114 #include "ardour/silentfilesource.h"
115 #include "ardour/sndfilesource.h"
116 #include "ardour/source_factory.h"
117 #include "ardour/speakers.h"
118 #include "ardour/template_utils.h"
119 #include "ardour/tempo.h"
120 #include "ardour/ticker.h"
121 #include "ardour/user_bundle.h"
123 #include "control_protocol/control_protocol.h"
129 using namespace ARDOUR;
132 /** @param snapshot_name Snapshot name, without the .ardour prefix */
134 Session::first_stage_init (string fullpath, string snapshot_name)
136 if (fullpath.length() == 0) {
138 throw failed_constructor();
141 char buf[PATH_MAX+1];
142 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
143 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
145 throw failed_constructor();
150 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
151 _path += G_DIR_SEPARATOR;
154 /* these two are just provisional settings. set_state()
155 will likely override them.
158 _name = _current_snapshot_name = snapshot_name;
160 set_history_depth (Config->get_history_depth());
162 _current_frame_rate = _engine.frame_rate ();
163 _nominal_frame_rate = _current_frame_rate;
164 _base_frame_rate = _current_frame_rate;
166 _tempo_map = new TempoMap (_current_frame_rate);
167 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
170 _non_soloed_outs_muted = false;
172 _solo_isolated_cnt = 0;
173 g_atomic_int_set (&processing_prohibited, 0);
174 _transport_speed = 0;
175 _default_transport_speed = 1.0;
176 _last_transport_speed = 0;
177 _target_transport_speed = 0;
178 auto_play_legal = false;
179 transport_sub_state = 0;
180 _transport_frame = 0;
181 _requested_return_frame = -1;
182 _session_range_location = 0;
183 g_atomic_int_set (&_record_status, Disabled);
184 loop_changing = false;
187 _last_roll_location = 0;
188 _last_roll_or_reversal_location = 0;
189 _last_record_location = 0;
190 pending_locate_frame = 0;
191 pending_locate_roll = false;
192 pending_locate_flush = false;
193 state_was_pending = false;
195 outbound_mtc_timecode_frame = 0;
196 next_quarter_frame_to_send = -1;
197 current_block_size = 0;
198 solo_update_disabled = false;
199 _have_captured = false;
200 _worst_output_latency = 0;
201 _worst_input_latency = 0;
202 _worst_track_latency = 0;
203 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
204 _was_seamless = Config->get_seamless_loop ();
206 _send_qf_mtc = false;
207 _pframes_since_last_mtc = 0;
208 g_atomic_int_set (&_playback_load, 100);
209 g_atomic_int_set (&_capture_load, 100);
212 pending_abort = false;
213 destructive_index = 0;
214 first_file_data_format_reset = true;
215 first_file_header_format_reset = true;
216 post_export_sync = false;
219 no_questions_about_missing_files = false;
220 _speakers.reset (new Speakers);
222 ignore_route_processor_changes = false;
223 _pre_export_mmc_enabled = false;
225 AudioDiskstream::allocate_working_buffers();
227 /* default short fade = 15ms */
229 SndFileSource::setup_standard_crossfades (*this, frame_rate());
231 last_mmc_step.tv_sec = 0;
232 last_mmc_step.tv_usec = 0;
235 /* click sounds are unset by default, which causes us to internal
236 waveforms for clicks.
240 click_emphasis_length = 0;
243 process_function = &Session::process_with_events;
245 if (config.get_use_video_sync()) {
246 waiting_for_sync_offset = true;
248 waiting_for_sync_offset = false;
251 last_timecode_when = 0;
252 last_timecode_valid = false;
256 last_rr_session_dir = session_dirs.begin();
257 refresh_disk_space ();
259 /* default: assume simple stereo speaker configuration */
261 _speakers->setup_default_speakers (2);
265 average_slave_delta = 1800; // !!! why 1800 ????
266 have_first_delta_accumulator = false;
267 delta_accumulator_cnt = 0;
268 _slave_state = Stopped;
270 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
271 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
272 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
273 add_controllable (_solo_cut_control);
275 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
277 /* These are all static "per-class" signals */
279 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
280 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
281 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
282 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
283 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
285 /* stop IO objects from doing stuff until we're ready for them */
287 Delivery::disable_panners ();
288 IO::disable_connecting ();
292 Session::second_stage_init ()
294 AudioFileSource::set_peak_dir (_session_dir->peak_path());
297 if (load_state (_current_snapshot_name)) {
302 if (_butler->start_thread()) {
306 if (start_midi_thread ()) {
310 setup_midi_machine_control ();
312 // set_state() will call setup_raid_path(), but if it's a new session we need
313 // to call setup_raid_path() here.
316 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
320 setup_raid_path(_path);
323 /* we can't save till after ::when_engine_running() is called,
324 because otherwise we save state with no connections made.
325 therefore, we reset _state_of_the_state because ::set_state()
326 will have cleared it.
328 we also have to include Loading so that any events that get
329 generated between here and the end of ::when_engine_running()
330 will be processed directly rather than queued.
333 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
335 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
336 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
337 setup_click_sounds (0);
338 setup_midi_control ();
340 /* Pay attention ... */
342 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
343 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
345 midi_clock = new MidiClockTicker ();
346 midi_clock->set_session (this);
349 when_engine_running ();
352 /* handle this one in a different way than all others, so that its clear what happened */
354 catch (AudioEngine::PortRegistrationFailure& err) {
355 error << err.what() << endmsg;
363 BootMessage (_("Reset Remote Controls"));
365 send_full_time_code (0);
366 _engine.transport_locate (0);
368 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
369 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
371 MIDI::Name::MidiPatchManager::instance().set_session (this);
373 /* initial program change will be delivered later; see ::config_changed() */
375 _state_of_the_state = Clean;
377 Port::set_connecting_blocked (false);
379 DirtyChanged (); /* EMIT SIGNAL */
381 if (state_was_pending) {
382 save_state (_current_snapshot_name);
383 remove_pending_capture_state ();
384 state_was_pending = false;
387 BootMessage (_("Session loading complete"));
393 Session::raid_path () const
395 SearchPath raid_search_path;
397 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
398 raid_search_path += (*i).path;
401 return raid_search_path.to_string ();
405 Session::setup_raid_path (string path)
414 session_dirs.clear ();
416 SearchPath search_path(path);
417 SearchPath sound_search_path;
418 SearchPath midi_search_path;
420 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
422 sp.blocks = 0; // not needed
423 session_dirs.push_back (sp);
425 SessionDirectory sdir(sp.path);
427 sound_search_path += sdir.sound_path ();
428 midi_search_path += sdir.midi_path ();
431 // reset the round-robin soundfile path thingie
432 last_rr_session_dir = session_dirs.begin();
436 Session::path_is_within_session (const std::string& path)
438 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
439 if (PBD::path_is_within (i->path, path)) {
447 Session::ensure_subdirs ()
451 dir = session_directory().peak_path();
453 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
454 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
458 dir = session_directory().sound_path();
460 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
461 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
465 dir = session_directory().midi_path();
467 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
468 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
472 dir = session_directory().dead_path();
474 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
475 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
479 dir = session_directory().export_path();
481 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
482 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
486 dir = analysis_dir ();
488 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
489 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
493 dir = plugins_dir ();
495 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
496 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
500 dir = externals_dir ();
502 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
503 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
510 /** @param session_template directory containing session template, or empty.
511 * Caller must not hold process lock.
514 Session::create (const string& session_template, BusProfile* bus_profile)
516 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
517 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
521 if (ensure_subdirs ()) {
525 _writable = exists_and_writable (_path);
527 if (!session_template.empty()) {
528 std::string in_path = session_template_dir_to_file (session_template);
530 ifstream in(in_path.c_str());
533 string out_path = _path;
535 out_path += statefile_suffix;
537 ofstream out(out_path.c_str());
543 /* Copy plugin state files from template to new session */
544 std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
545 copy_files (template_plugins, plugins_dir ());
550 error << string_compose (_("Could not open %1 for writing session template"), out_path)
556 error << string_compose (_("Could not open session template %1 for reading"), in_path)
563 /* set initial start + end point */
565 _state_of_the_state = Clean;
567 /* set up Master Out and Control Out if necessary */
572 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
574 if (bus_profile->master_out_channels) {
575 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
579 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
580 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
583 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
584 r->input()->ensure_io (count, false, this);
585 r->output()->ensure_io (count, false, this);
591 /* prohibit auto-connect to master, because there isn't one */
592 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
596 add_routes (rl, false, false, false);
599 /* this allows the user to override settings with an environment variable.
602 if (no_auto_connect()) {
603 bus_profile->input_ac = AutoConnectOption (0);
604 bus_profile->output_ac = AutoConnectOption (0);
607 Config->set_input_auto_connect (bus_profile->input_ac);
608 Config->set_output_auto_connect (bus_profile->output_ac);
611 if (Config->get_use_monitor_bus() && bus_profile) {
612 add_monitor_section ();
621 Session::maybe_write_autosave()
623 if (dirty() && record_status() != Recording) {
624 save_state("", true);
629 Session::remove_pending_capture_state ()
631 std::string pending_state_file_path(_session_dir->root_path());
633 pending_state_file_path = Glib::build_filename (pending_state_file_path, legalize_for_path (_current_snapshot_name) + pending_suffix);
635 if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS)) return;
637 if (g_remove (pending_state_file_path.c_str()) != 0) {
638 error << string_compose(_("Could not remove pending capture state at path \"%1\" (%2)"),
639 pending_state_file_path, g_strerror (errno)) << endmsg;
643 /** Rename a state file.
644 * @param old_name Old snapshot name.
645 * @param new_name New snapshot name.
648 Session::rename_state (string old_name, string new_name)
650 if (old_name == _current_snapshot_name || old_name == _name) {
651 /* refuse to rename the current snapshot or the "main" one */
655 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
656 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
658 const std::string old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
659 const std::string new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
661 if (::g_rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
662 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
663 old_name, new_name, g_strerror(errno)) << endmsg;
667 /** Remove a state file.
668 * @param snapshot_name Snapshot name.
671 Session::remove_state (string snapshot_name)
673 if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
674 // refuse to remove the current snapshot or the "main" one
678 std::string xml_path(_session_dir->root_path());
680 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
682 if (!create_backup_file (xml_path)) {
683 // don't remove it if a backup can't be made
684 // create_backup_file will log the error.
689 if (g_remove (xml_path.c_str()) != 0) {
690 error << string_compose(_("Could not remove state file at path \"%1\" (%2)"),
691 xml_path, g_strerror (errno)) << endmsg;
695 #ifdef HAVE_JACK_SESSION
697 Session::jack_session_event (jack_session_event_t * event)
701 struct tm local_time;
704 localtime_r (&n, &local_time);
705 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
707 if (event->type == JackSessionSaveTemplate)
709 if (save_template( timebuf )) {
710 event->flags = JackSessionSaveError;
712 string cmd ("ardour3 -P -U ");
713 cmd += event->client_uuid;
717 event->command_line = strdup (cmd.c_str());
722 if (save_state (timebuf)) {
723 event->flags = JackSessionSaveError;
725 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 jack_session_reply (_engine.jack(), event);
741 if (event->type == JackSessionSaveAndQuit) {
742 Quit (); /* EMIT SIGNAL */
745 jack_session_event_free( event );
749 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
751 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
754 std::string xml_path(_session_dir->root_path());
756 if (!_writable || (_state_of_the_state & CannotSave)) {
760 if (!_engine.connected ()) {
761 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
767 /* tell sources we're saving first, in case they write out to a new file
768 * which should be saved with the state rather than the old one */
769 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
771 i->second->session_saved();
772 } catch (Evoral::SMF::FileError& e) {
773 error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
777 tree.set_root (&get_state());
779 if (snapshot_name.empty()) {
780 snapshot_name = _current_snapshot_name;
781 } else if (switch_to_snapshot) {
782 _current_snapshot_name = snapshot_name;
787 /* proper save: use statefile_suffix (.ardour in English) */
789 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
791 /* make a backup copy of the old file */
793 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) {
794 // create_backup_file will log the error
800 /* pending save: use pending_suffix (.pending in English) */
801 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
804 sys::path tmp_path(_session_dir->root_path());
806 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
808 // cerr << "actually writing state to " << xml_path.to_string() << endl;
810 if (!tree.write (tmp_path.to_string())) {
811 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
812 if (g_remove (tmp_path.to_string().c_str()) != 0) {
813 error << string_compose(_("Could not remove temporary state file at path \"%1\" (%2)"),
814 tmp_path.to_string(), g_strerror (errno)) << endmsg;
820 if (::rename (tmp_path.to_string().c_str(), xml_path.c_str()) != 0) {
821 error << string_compose (_("could not rename temporary session file %1 to %2"),
822 tmp_path.to_string(), xml_path) << endmsg;
823 if (g_remove (tmp_path.to_string().c_str()) != 0) {
824 error << string_compose(_("Could not remove temporary state file at path \"%1\" (%2)"),
825 tmp_path.to_string(), g_strerror (errno)) << endmsg;
833 save_history (snapshot_name);
835 bool was_dirty = dirty();
837 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
840 DirtyChanged (); /* EMIT SIGNAL */
843 StateSaved (snapshot_name); /* EMIT SIGNAL */
850 Session::restore_state (string snapshot_name)
852 if (load_state (snapshot_name) == 0) {
853 set_state (*state_tree->root(), Stateful::loading_state_version);
860 Session::load_state (string snapshot_name)
865 state_was_pending = false;
867 /* check for leftover pending state from a crashed capture attempt */
869 sys::path xmlpath(_session_dir->root_path());
870 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
872 if (Glib::file_test (xmlpath.to_string(), Glib::FILE_TEST_EXISTS)) {
874 /* there is pending state from a crashed capture attempt */
876 boost::optional<int> r = AskAboutPendingState();
877 if (r.get_value_or (1)) {
878 state_was_pending = true;
882 if (!state_was_pending) {
883 xmlpath = _session_dir->root_path();
884 xmlpath /= snapshot_name;
887 if (!Glib::file_test (xmlpath.to_string(), Glib::FILE_TEST_EXISTS)) {
888 xmlpath = _session_dir->root_path();
889 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
890 if (!Glib::file_test (xmlpath.to_string(), Glib::FILE_TEST_EXISTS)) {
891 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
896 state_tree = new XMLTree;
900 _writable = exists_and_writable (xmlpath.to_string());
902 if (!state_tree->read (xmlpath.to_string())) {
903 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
909 XMLNode& root (*state_tree->root());
911 if (root.name() != X_("Session")) {
912 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
918 const XMLProperty* prop;
920 if ((prop = root.property ("version")) == 0) {
921 /* no version implies very old version of Ardour */
922 Stateful::loading_state_version = 1000;
924 if (prop->value().find ('.') != string::npos) {
925 /* old school version format */
926 if (prop->value()[0] == '2') {
927 Stateful::loading_state_version = 2000;
929 Stateful::loading_state_version = 3000;
932 Stateful::loading_state_version = atoi (prop->value());
936 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
938 sys::path backup_path(_session_dir->root_path());
940 backup_path /= string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
942 // only create a backup for a given statefile version once
944 if (!Glib::file_test (backup_path.to_string(), Glib::FILE_TEST_EXISTS)) {
946 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
947 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
950 if (!copy_file (xmlpath.to_string(), backup_path.to_string())) {;
960 Session::load_options (const XMLNode& node)
962 LocaleGuard lg (X_("POSIX"));
963 config.set_variables (node);
974 Session::get_template()
976 /* if we don't disable rec-enable, diskstreams
977 will believe they need to store their capture
978 sources in their state node.
981 disable_record (false);
987 Session::state (bool full_state)
989 XMLNode* node = new XMLNode("Session");
993 snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
994 node->add_property("version", buf);
996 /* store configuration settings */
1000 node->add_property ("name", _name);
1001 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1002 node->add_property ("sample-rate", buf);
1004 if (session_dirs.size() > 1) {
1008 vector<space_and_path>::iterator i = session_dirs.begin();
1009 vector<space_and_path>::iterator next;
1011 ++i; /* skip the first one */
1015 while (i != session_dirs.end()) {
1019 if (next != session_dirs.end()) {
1029 child = node->add_child ("Path");
1030 child->add_content (p);
1034 /* save the ID counter */
1036 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1037 node->add_property ("id-counter", buf);
1039 /* save the event ID counter */
1041 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1042 node->add_property ("event-counter", buf);
1044 /* various options */
1046 node->add_child_nocopy (config.get_variables ());
1048 node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
1050 child = node->add_child ("Sources");
1053 Glib::Mutex::Lock sl (source_lock);
1055 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1057 /* Don't save information about non-file Sources, or
1058 * about non-destructive file sources that are empty
1059 * and unused by any regions.
1062 boost::shared_ptr<FileSource> fs;
1064 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1066 if (!fs->destructive()) {
1067 if (fs->empty() && !fs->used()) {
1072 child->add_child_nocopy (siter->second->get_state());
1077 child = node->add_child ("Regions");
1080 Glib::Mutex::Lock rl (region_lock);
1081 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1082 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1083 boost::shared_ptr<Region> r = i->second;
1084 /* only store regions not attached to playlists */
1085 if (r->playlist() == 0) {
1086 child->add_child_nocopy (r->state ());
1090 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1092 if (!cassocs.empty()) {
1093 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1095 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1097 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1098 i->first->id().print (buf, sizeof (buf));
1099 can->add_property (X_("copy"), buf);
1100 i->second->id().print (buf, sizeof (buf));
1101 can->add_property (X_("original"), buf);
1102 ca->add_child_nocopy (*can);
1108 node->add_child_nocopy (_locations->get_state());
1110 // for a template, just create a new Locations, populate it
1111 // with the default start and end, and get the state for that.
1112 Locations loc (*this);
1113 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1114 range->set (max_framepos, 0);
1116 node->add_child_nocopy (loc.get_state());
1119 child = node->add_child ("Bundles");
1121 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1122 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1123 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1125 child->add_child_nocopy (b->get_state());
1130 child = node->add_child ("Routes");
1132 boost::shared_ptr<RouteList> r = routes.reader ();
1134 RoutePublicOrderSorter cmp;
1135 RouteList public_order (*r);
1136 public_order.sort (cmp);
1138 /* the sort should have put control outs first */
1141 assert (_monitor_out == public_order.front());
1144 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1145 if (!(*i)->is_hidden()) {
1147 child->add_child_nocopy ((*i)->get_state());
1149 child->add_child_nocopy ((*i)->get_template());
1155 playlists->add_state (node, full_state);
1157 child = node->add_child ("RouteGroups");
1158 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1159 child->add_child_nocopy ((*i)->get_state());
1163 XMLNode* gain_child = node->add_child ("Click");
1164 gain_child->add_child_nocopy (_click_io->state (full_state));
1165 gain_child->add_child_nocopy (_click_gain->state (full_state));
1169 XMLNode* ns_child = node->add_child ("NamedSelections");
1170 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1172 ns_child->add_child_nocopy ((*i)->get_state());
1177 node->add_child_nocopy (_speakers->get_state());
1178 node->add_child_nocopy (_tempo_map->get_state());
1179 node->add_child_nocopy (get_control_protocol_state());
1182 node->add_child_copy (*_extra_xml);
1189 Session::get_control_protocol_state ()
1191 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1192 return cpm.get_state();
1196 Session::set_state (const XMLNode& node, int version)
1200 const XMLProperty* prop;
1203 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1205 if (node.name() != X_("Session")) {
1206 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1210 if ((prop = node.property ("name")) != 0) {
1211 _name = prop->value ();
1214 if ((prop = node.property (X_("sample-rate"))) != 0) {
1216 _nominal_frame_rate = atoi (prop->value());
1218 if (_nominal_frame_rate != _current_frame_rate) {
1219 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1220 if (r.get_value_or (0)) {
1226 setup_raid_path(_session_dir->root_path());
1228 if ((prop = node.property (X_("id-counter"))) != 0) {
1230 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1231 ID::init_counter (x);
1233 /* old sessions used a timebased counter, so fake
1234 the startup ID counter based on a standard
1239 ID::init_counter (now);
1242 if ((prop = node.property (X_("event-counter"))) != 0) {
1243 Evoral::init_event_id_counter (atoi (prop->value()));
1246 IO::disable_connecting ();
1248 Stateful::save_extra_xml (node);
1250 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1251 load_options (*child);
1252 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1253 load_options (*child);
1255 error << _("Session: XML state has no options section") << endmsg;
1258 if (version >= 3000) {
1259 if ((child = find_named_node (node, "Metadata")) == 0) {
1260 warning << _("Session: XML state has no metadata section") << endmsg;
1261 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1266 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1267 _speakers->set_state (*child, version);
1270 if ((child = find_named_node (node, "Sources")) == 0) {
1271 error << _("Session: XML state has no sources section") << endmsg;
1273 } else if (load_sources (*child)) {
1277 if ((child = find_named_node (node, "TempoMap")) == 0) {
1278 error << _("Session: XML state has no Tempo Map section") << endmsg;
1280 } else if (_tempo_map->set_state (*child, version)) {
1284 if ((child = find_named_node (node, "Locations")) == 0) {
1285 error << _("Session: XML state has no locations section") << endmsg;
1287 } else if (_locations->set_state (*child, version)) {
1293 if ((location = _locations->auto_loop_location()) != 0) {
1294 set_auto_loop_location (location);
1297 if ((location = _locations->auto_punch_location()) != 0) {
1298 set_auto_punch_location (location);
1301 if ((location = _locations->session_range_location()) != 0) {
1302 delete _session_range_location;
1303 _session_range_location = location;
1306 if (_session_range_location) {
1307 AudioFileSource::set_header_position_offset (_session_range_location->start());
1310 if ((child = find_named_node (node, "Regions")) == 0) {
1311 error << _("Session: XML state has no Regions section") << endmsg;
1313 } else if (load_regions (*child)) {
1317 if ((child = find_named_node (node, "Playlists")) == 0) {
1318 error << _("Session: XML state has no playlists section") << endmsg;
1320 } else if (playlists->load (*this, *child)) {
1324 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1326 } else if (playlists->load_unused (*this, *child)) {
1330 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1331 if (load_compounds (*child)) {
1336 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1337 if (load_named_selections (*child)) {
1342 if (version >= 3000) {
1343 if ((child = find_named_node (node, "Bundles")) == 0) {
1344 warning << _("Session: XML state has no bundles section") << endmsg;
1347 /* We can't load Bundles yet as they need to be able
1348 to convert from port names to Port objects, which can't happen until
1350 _bundle_xml_node = new XMLNode (*child);
1354 if (version < 3000) {
1355 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1356 error << _("Session: XML state has no diskstreams section") << endmsg;
1358 } else if (load_diskstreams_2X (*child, version)) {
1363 if ((child = find_named_node (node, "Routes")) == 0) {
1364 error << _("Session: XML state has no routes section") << endmsg;
1366 } else if (load_routes (*child, version)) {
1370 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1371 _diskstreams_2X.clear ();
1373 if (version >= 3000) {
1375 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1376 error << _("Session: XML state has no route groups section") << endmsg;
1378 } else if (load_route_groups (*child, version)) {
1382 } else if (version < 3000) {
1384 if ((child = find_named_node (node, "EditGroups")) == 0) {
1385 error << _("Session: XML state has no edit groups section") << endmsg;
1387 } else if (load_route_groups (*child, version)) {
1391 if ((child = find_named_node (node, "MixGroups")) == 0) {
1392 error << _("Session: XML state has no mix groups section") << endmsg;
1394 } else if (load_route_groups (*child, version)) {
1399 if ((child = find_named_node (node, "Click")) == 0) {
1400 warning << _("Session: XML state has no click section") << endmsg;
1401 } else if (_click_io) {
1402 const XMLNodeList& children (child->children());
1403 XMLNodeList::const_iterator i = children.begin();
1404 _click_io->set_state (**i, version);
1406 if (i != children.end()) {
1407 _click_gain->set_state (**i, version);
1411 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1412 ControlProtocolManager::instance().set_protocol_states (*child);
1415 update_have_rec_enabled_track ();
1417 /* here beginneth the second phase ... */
1419 StateReady (); /* EMIT SIGNAL */
1428 Session::load_routes (const XMLNode& node, int version)
1431 XMLNodeConstIterator niter;
1432 RouteList new_routes;
1434 nlist = node.children();
1438 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1440 boost::shared_ptr<Route> route;
1441 if (version < 3000) {
1442 route = XMLRouteFactory_2X (**niter, version);
1444 route = XMLRouteFactory (**niter, version);
1448 error << _("Session: cannot create Route from XML description.") << endmsg;
1452 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1454 new_routes.push_back (route);
1457 add_routes (new_routes, false, false, false);
1462 boost::shared_ptr<Route>
1463 Session::XMLRouteFactory (const XMLNode& node, int version)
1465 boost::shared_ptr<Route> ret;
1467 if (node.name() != "Route") {
1471 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1473 DataType type = DataType::AUDIO;
1474 const XMLProperty* prop = node.property("default-type");
1477 type = DataType (prop->value());
1480 assert (type != DataType::NIL);
1484 boost::shared_ptr<Track> track;
1486 if (type == DataType::AUDIO) {
1487 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1489 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1492 if (track->init()) {
1496 if (track->set_state (node, version)) {
1500 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1501 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1506 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1508 if (r->init () == 0 && r->set_state (node, version) == 0) {
1509 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1510 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1519 boost::shared_ptr<Route>
1520 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1522 boost::shared_ptr<Route> ret;
1524 if (node.name() != "Route") {
1528 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1530 ds_prop = node.property (X_("diskstream"));
1533 DataType type = DataType::AUDIO;
1534 const XMLProperty* prop = node.property("default-type");
1537 type = DataType (prop->value());
1540 assert (type != DataType::NIL);
1544 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1545 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1549 if (i == _diskstreams_2X.end()) {
1550 error << _("Could not find diskstream for route") << endmsg;
1551 return boost::shared_ptr<Route> ();
1554 boost::shared_ptr<Track> track;
1556 if (type == DataType::AUDIO) {
1557 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1559 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1562 if (track->init()) {
1566 if (track->set_state (node, version)) {
1570 track->set_diskstream (*i);
1572 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1573 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1578 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1580 if (r->init () == 0 && r->set_state (node, version) == 0) {
1581 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1582 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1592 Session::load_regions (const XMLNode& node)
1595 XMLNodeConstIterator niter;
1596 boost::shared_ptr<Region> region;
1598 nlist = node.children();
1602 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1603 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1604 error << _("Session: cannot create Region from XML description.");
1605 const XMLProperty *name = (**niter).property("name");
1608 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1619 Session::load_compounds (const XMLNode& node)
1621 XMLNodeList calist = node.children();
1622 XMLNodeConstIterator caiter;
1623 XMLProperty *caprop;
1625 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1626 XMLNode* ca = *caiter;
1630 if ((caprop = ca->property (X_("original"))) == 0) {
1633 orig_id = caprop->value();
1635 if ((caprop = ca->property (X_("copy"))) == 0) {
1638 copy_id = caprop->value();
1640 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1641 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1643 if (!orig || !copy) {
1644 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1650 RegionFactory::add_compound_association (orig, copy);
1657 Session::load_nested_sources (const XMLNode& node)
1660 XMLNodeConstIterator niter;
1662 nlist = node.children();
1664 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1665 if ((*niter)->name() == "Source") {
1667 /* it may already exist, so don't recreate it unnecessarily
1670 XMLProperty* prop = (*niter)->property (X_("id"));
1672 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1676 ID source_id (prop->value());
1678 if (!source_by_id (source_id)) {
1681 SourceFactory::create (*this, **niter, true);
1683 catch (failed_constructor& err) {
1684 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1691 boost::shared_ptr<Region>
1692 Session::XMLRegionFactory (const XMLNode& node, bool full)
1694 const XMLProperty* type = node.property("type");
1698 const XMLNodeList& nlist = node.children();
1700 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1701 XMLNode *child = (*niter);
1702 if (child->name() == "NestedSource") {
1703 load_nested_sources (*child);
1707 if (!type || type->value() == "audio") {
1708 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1709 } else if (type->value() == "midi") {
1710 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1713 } catch (failed_constructor& err) {
1714 return boost::shared_ptr<Region> ();
1717 return boost::shared_ptr<Region> ();
1720 boost::shared_ptr<AudioRegion>
1721 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1723 const XMLProperty* prop;
1724 boost::shared_ptr<Source> source;
1725 boost::shared_ptr<AudioSource> as;
1727 SourceList master_sources;
1728 uint32_t nchans = 1;
1731 if (node.name() != X_("Region")) {
1732 return boost::shared_ptr<AudioRegion>();
1735 if ((prop = node.property (X_("channels"))) != 0) {
1736 nchans = atoi (prop->value().c_str());
1739 if ((prop = node.property ("name")) == 0) {
1740 cerr << "no name for this region\n";
1744 if ((prop = node.property (X_("source-0"))) == 0) {
1745 if ((prop = node.property ("source")) == 0) {
1746 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1747 return boost::shared_ptr<AudioRegion>();
1751 PBD::ID s_id (prop->value());
1753 if ((source = source_by_id (s_id)) == 0) {
1754 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1755 return boost::shared_ptr<AudioRegion>();
1758 as = boost::dynamic_pointer_cast<AudioSource>(source);
1760 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1761 return boost::shared_ptr<AudioRegion>();
1764 sources.push_back (as);
1766 /* pickup other channels */
1768 for (uint32_t n=1; n < nchans; ++n) {
1769 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1770 if ((prop = node.property (buf)) != 0) {
1772 PBD::ID id2 (prop->value());
1774 if ((source = source_by_id (id2)) == 0) {
1775 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1776 return boost::shared_ptr<AudioRegion>();
1779 as = boost::dynamic_pointer_cast<AudioSource>(source);
1781 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1782 return boost::shared_ptr<AudioRegion>();
1784 sources.push_back (as);
1788 for (uint32_t n = 0; n < nchans; ++n) {
1789 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1790 if ((prop = node.property (buf)) != 0) {
1792 PBD::ID id2 (prop->value());
1794 if ((source = source_by_id (id2)) == 0) {
1795 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1796 return boost::shared_ptr<AudioRegion>();
1799 as = boost::dynamic_pointer_cast<AudioSource>(source);
1801 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1802 return boost::shared_ptr<AudioRegion>();
1804 master_sources.push_back (as);
1809 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1811 /* a final detail: this is the one and only place that we know how long missing files are */
1813 if (region->whole_file()) {
1814 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1815 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1817 sfp->set_length (region->length());
1822 if (!master_sources.empty()) {
1823 if (master_sources.size() != nchans) {
1824 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1826 region->set_master_sources (master_sources);
1834 catch (failed_constructor& err) {
1835 return boost::shared_ptr<AudioRegion>();
1839 boost::shared_ptr<MidiRegion>
1840 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1842 const XMLProperty* prop;
1843 boost::shared_ptr<Source> source;
1844 boost::shared_ptr<MidiSource> ms;
1847 if (node.name() != X_("Region")) {
1848 return boost::shared_ptr<MidiRegion>();
1851 if ((prop = node.property ("name")) == 0) {
1852 cerr << "no name for this region\n";
1856 if ((prop = node.property (X_("source-0"))) == 0) {
1857 if ((prop = node.property ("source")) == 0) {
1858 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1859 return boost::shared_ptr<MidiRegion>();
1863 PBD::ID s_id (prop->value());
1865 if ((source = source_by_id (s_id)) == 0) {
1866 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1867 return boost::shared_ptr<MidiRegion>();
1870 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1872 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1873 return boost::shared_ptr<MidiRegion>();
1876 sources.push_back (ms);
1879 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1880 /* a final detail: this is the one and only place that we know how long missing files are */
1882 if (region->whole_file()) {
1883 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1884 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1886 sfp->set_length (region->length());
1894 catch (failed_constructor& err) {
1895 return boost::shared_ptr<MidiRegion>();
1900 Session::get_sources_as_xml ()
1903 XMLNode* node = new XMLNode (X_("Sources"));
1904 Glib::Mutex::Lock lm (source_lock);
1906 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1907 node->add_child_nocopy (i->second->get_state());
1914 Session::path_from_region_name (DataType type, string name, string identifier)
1916 char buf[PATH_MAX+1];
1918 SessionDirectory sdir(get_best_session_directory_for_new_source());
1919 sys::path source_dir = ((type == DataType::AUDIO)
1920 ? sdir.sound_path() : sdir.midi_path());
1922 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1924 for (n = 0; n < 999999; ++n) {
1925 if (identifier.length()) {
1926 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1927 identifier.c_str(), n, ext.c_str());
1929 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1933 sys::path source_path = source_dir / buf;
1935 if (!Glib::file_test (source_path.to_string(), Glib::FILE_TEST_EXISTS)) {
1936 return source_path.to_string();
1940 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1949 Session::load_sources (const XMLNode& node)
1952 XMLNodeConstIterator niter;
1953 boost::shared_ptr<Source> source;
1955 nlist = node.children();
1959 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1962 if ((source = XMLSourceFactory (**niter)) == 0) {
1963 error << _("Session: cannot create Source from XML description.") << endmsg;
1966 } catch (MissingSource& err) {
1970 if (!no_questions_about_missing_files) {
1971 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1976 switch (user_choice) {
1978 /* user added a new search location, so try again */
1983 /* user asked to quit the entire session load
1988 no_questions_about_missing_files = true;
1992 no_questions_about_missing_files = true;
1997 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1998 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2007 boost::shared_ptr<Source>
2008 Session::XMLSourceFactory (const XMLNode& node)
2010 if (node.name() != "Source") {
2011 return boost::shared_ptr<Source>();
2015 /* note: do peak building in another thread when loading session state */
2016 return SourceFactory::create (*this, node, true);
2019 catch (failed_constructor& err) {
2020 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2021 return boost::shared_ptr<Source>();
2026 Session::save_template (string template_name)
2030 if (_state_of_the_state & CannotSave) {
2034 sys::path user_template_dir(user_template_directory());
2036 if (g_mkdir_with_parents (user_template_dir.to_string().c_str(), 0755) != 0) {
2037 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2038 user_template_dir.to_string(), g_strerror (errno)) << endmsg;
2042 tree.set_root (&get_template());
2044 sys::path template_dir_path(user_template_dir);
2046 /* directory to put the template in */
2047 template_dir_path /= template_name;
2048 if (Glib::file_test (template_dir_path.to_string(), Glib::FILE_TEST_EXISTS)) {
2049 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2050 template_dir_path.to_string()) << endmsg;
2054 if (g_mkdir_with_parents (template_dir_path.to_string().c_str(), 0755) != 0) {
2055 error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
2056 template_dir_path.to_string(), g_strerror (errno)) << endmsg;
2061 sys::path template_file_path = template_dir_path;
2062 template_file_path /= template_name + template_suffix;
2064 if (!tree.write (template_file_path.to_string())) {
2065 error << _("template not saved") << endmsg;
2069 /* copy plugin state directory */
2071 sys::path template_plugin_state_path = template_dir_path;
2072 template_plugin_state_path /= X_("plugins");
2074 if (g_mkdir_with_parents (template_plugin_state_path.to_string().c_str(), 0755) != 0) {
2075 error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
2076 template_plugin_state_path.to_string(), g_strerror (errno)) << endmsg;
2080 copy_files (plugins_dir(), template_plugin_state_path.to_string());
2086 Session::refresh_disk_space ()
2088 #if HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H
2090 Glib::Mutex::Lock lm (space_lock);
2092 /* get freespace on every FS that is part of the session path */
2094 _total_free_4k_blocks = 0;
2095 _total_free_4k_blocks_uncertain = false;
2097 for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2099 struct statfs statfsbuf;
2100 statfs (i->path.c_str(), &statfsbuf);
2102 double const scale = statfsbuf.f_bsize / 4096.0;
2104 /* See if this filesystem is read-only */
2105 struct statvfs statvfsbuf;
2106 statvfs (i->path.c_str(), &statvfsbuf);
2108 /* f_bavail can be 0 if it is undefined for whatever
2109 filesystem we are looking at; Samba shares mounted
2110 via GVFS are an example of this.
2112 if (statfsbuf.f_bavail == 0) {
2113 /* block count unknown */
2115 i->blocks_unknown = true;
2116 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2117 /* read-only filesystem */
2119 i->blocks_unknown = false;
2121 /* read/write filesystem with known space */
2122 i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2123 i->blocks_unknown = false;
2126 _total_free_4k_blocks += i->blocks;
2127 if (i->blocks_unknown) {
2128 _total_free_4k_blocks_uncertain = true;
2135 Session::get_best_session_directory_for_new_source ()
2137 vector<space_and_path>::iterator i;
2138 string result = _session_dir->root_path();
2140 /* handle common case without system calls */
2142 if (session_dirs.size() == 1) {
2146 /* OK, here's the algorithm we're following here:
2148 We want to select which directory to use for
2149 the next file source to be created. Ideally,
2150 we'd like to use a round-robin process so as to
2151 get maximum performance benefits from splitting
2152 the files across multiple disks.
2154 However, in situations without much diskspace, an
2155 RR approach may end up filling up a filesystem
2156 with new files while others still have space.
2157 Its therefore important to pay some attention to
2158 the freespace in the filesystem holding each
2159 directory as well. However, if we did that by
2160 itself, we'd keep creating new files in the file
2161 system with the most space until it was as full
2162 as all others, thus negating any performance
2163 benefits of this RAID-1 like approach.
2165 So, we use a user-configurable space threshold. If
2166 there are at least 2 filesystems with more than this
2167 much space available, we use RR selection between them.
2168 If not, then we pick the filesystem with the most space.
2170 This gets a good balance between the two
2174 refresh_disk_space ();
2176 int free_enough = 0;
2178 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2179 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2184 if (free_enough >= 2) {
2185 /* use RR selection process, ensuring that the one
2189 i = last_rr_session_dir;
2192 if (++i == session_dirs.end()) {
2193 i = session_dirs.begin();
2196 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2197 if (create_session_directory ((*i).path)) {
2199 last_rr_session_dir = i;
2204 } while (i != last_rr_session_dir);
2208 /* pick FS with the most freespace (and that
2209 seems to actually work ...)
2212 vector<space_and_path> sorted;
2213 space_and_path_ascending_cmp cmp;
2215 sorted = session_dirs;
2216 sort (sorted.begin(), sorted.end(), cmp);
2218 for (i = sorted.begin(); i != sorted.end(); ++i) {
2219 if (create_session_directory ((*i).path)) {
2221 last_rr_session_dir = i;
2231 Session::load_named_selections (const XMLNode& node)
2234 XMLNodeConstIterator niter;
2237 nlist = node.children();
2241 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2243 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2244 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2252 Session::XMLNamedSelectionFactory (const XMLNode& node)
2255 return new NamedSelection (*this, node);
2258 catch (failed_constructor& err) {
2264 Session::automation_dir () const
2266 return Glib::build_filename (_path, "automation");
2270 Session::analysis_dir () const
2272 return Glib::build_filename (_path, "analysis");
2276 Session::plugins_dir () const
2278 return Glib::build_filename (_path, "plugins");
2282 Session::externals_dir () const
2284 return Glib::build_filename (_path, "externals");
2288 Session::load_bundles (XMLNode const & node)
2290 XMLNodeList nlist = node.children();
2291 XMLNodeConstIterator niter;
2295 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2296 if ((*niter)->name() == "InputBundle") {
2297 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2298 } else if ((*niter)->name() == "OutputBundle") {
2299 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2301 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2310 Session::load_route_groups (const XMLNode& node, int version)
2312 XMLNodeList nlist = node.children();
2313 XMLNodeConstIterator niter;
2317 if (version >= 3000) {
2319 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2320 if ((*niter)->name() == "RouteGroup") {
2321 RouteGroup* rg = new RouteGroup (*this, "");
2322 add_route_group (rg);
2323 rg->set_state (**niter, version);
2327 } else if (version < 3000) {
2329 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2330 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2331 RouteGroup* rg = new RouteGroup (*this, "");
2332 add_route_group (rg);
2333 rg->set_state (**niter, version);
2342 Session::auto_save()
2344 save_state (_current_snapshot_name);
2348 state_file_filter (const string &str, void */*arg*/)
2350 return (str.length() > strlen(statefile_suffix) &&
2351 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2355 bool operator()(const string* a, const string* b) {
2361 remove_end(string* state)
2363 string statename(*state);
2365 string::size_type start,end;
2366 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2367 statename = statename.substr (start+1);
2370 if ((end = statename.rfind(".ardour")) == string::npos) {
2371 end = statename.length();
2374 return new string(statename.substr (0, end));
2378 Session::possible_states (string path)
2380 PathScanner scanner;
2381 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2383 transform(states->begin(), states->end(), states->begin(), remove_end);
2386 sort (states->begin(), states->end(), cmp);
2392 Session::possible_states () const
2394 return possible_states(_path);
2398 Session::add_route_group (RouteGroup* g)
2400 _route_groups.push_back (g);
2401 route_group_added (g); /* EMIT SIGNAL */
2403 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2404 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2405 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2411 Session::remove_route_group (RouteGroup& rg)
2413 list<RouteGroup*>::iterator i;
2415 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2416 _route_groups.erase (i);
2419 route_group_removed (); /* EMIT SIGNAL */
2423 /** Set a new order for our route groups, without adding or removing any.
2424 * @param groups Route group list in the new order.
2427 Session::reorder_route_groups (list<RouteGroup*> groups)
2429 _route_groups = groups;
2431 route_groups_reordered (); /* EMIT SIGNAL */
2437 Session::route_group_by_name (string name)
2439 list<RouteGroup *>::iterator i;
2441 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2442 if ((*i)->name() == name) {
2450 Session::all_route_group() const
2452 return *_all_route_group;
2456 Session::add_commands (vector<Command*> const & cmds)
2458 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2464 Session::begin_reversible_command (const string& name)
2466 begin_reversible_command (g_quark_from_string (name.c_str ()));
2469 /** Begin a reversible command using a GQuark to identify it.
2470 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2471 * but there must be as many begin...()s as there are commit...()s.
2474 Session::begin_reversible_command (GQuark q)
2476 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2477 to hold all the commands that are committed. This keeps the order of
2478 commands correct in the history.
2481 if (_current_trans == 0) {
2482 /* start a new transaction */
2483 assert (_current_trans_quarks.empty ());
2484 _current_trans = new UndoTransaction();
2485 _current_trans->set_name (g_quark_to_string (q));
2488 _current_trans_quarks.push_front (q);
2492 Session::commit_reversible_command (Command *cmd)
2494 assert (_current_trans);
2495 assert (!_current_trans_quarks.empty ());
2500 _current_trans->add_command (cmd);
2503 _current_trans_quarks.pop_front ();
2505 if (!_current_trans_quarks.empty ()) {
2506 /* the transaction we're committing is not the top-level one */
2510 if (_current_trans->empty()) {
2511 /* no commands were added to the transaction, so just get rid of it */
2512 delete _current_trans;
2517 gettimeofday (&now, 0);
2518 _current_trans->set_timestamp (now);
2520 _history.add (_current_trans);
2525 accept_all_audio_files (const string& path, void */*arg*/)
2527 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2531 if (!AudioFileSource::safe_audio_file_extension (path)) {
2539 accept_all_midi_files (const string& path, void */*arg*/)
2541 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2545 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2546 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2547 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2551 accept_all_state_files (const string& path, void */*arg*/)
2553 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2557 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2561 Session::find_all_sources (string path, set<string>& result)
2566 if (!tree.read (path)) {
2570 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2575 XMLNodeConstIterator niter;
2577 nlist = node->children();
2581 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2585 if ((prop = (*niter)->property (X_("type"))) == 0) {
2589 DataType type (prop->value());
2591 if ((prop = (*niter)->property (X_("name"))) == 0) {
2595 if (Glib::path_is_absolute (prop->value())) {
2596 /* external file, ignore */
2604 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2605 result.insert (found_path);
2613 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2615 PathScanner scanner;
2616 vector<string*>* state_files;
2618 string this_snapshot_path;
2624 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2625 ripped = ripped.substr (0, ripped.length() - 1);
2628 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2630 if (state_files == 0) {
2635 this_snapshot_path = _path;
2636 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2637 this_snapshot_path += statefile_suffix;
2639 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2641 if (exclude_this_snapshot && **i == this_snapshot_path) {
2645 if (find_all_sources (**i, result) < 0) {
2653 struct RegionCounter {
2654 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2655 AudioSourceList::iterator iter;
2656 boost::shared_ptr<Region> region;
2659 RegionCounter() : count (0) {}
2663 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2665 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2666 return r.get_value_or (1);
2670 Session::cleanup_regions ()
2672 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2674 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2676 uint32_t used = playlists->region_use_count (i->second);
2678 if (used == 0 && !i->second->automatic ()) {
2679 RegionFactory::map_remove (i->second);
2683 /* dump the history list */
2690 Session::cleanup_sources (CleanupReport& rep)
2692 // FIXME: needs adaptation to midi
2694 vector<boost::shared_ptr<Source> > dead_sources;
2695 PathScanner scanner;
2698 vector<space_and_path>::iterator i;
2699 vector<space_and_path>::iterator nexti;
2700 vector<string*>* candidates;
2701 vector<string*>* candidates2;
2702 vector<string> unused;
2703 set<string> all_sources;
2708 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2710 /* consider deleting all unused playlists */
2712 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2717 /* sync the "all regions" property of each playlist with its current state
2720 playlists->sync_all_regions_with_regions ();
2722 /* find all un-used sources */
2727 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2729 SourceMap::iterator tmp;
2734 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2738 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2739 dead_sources.push_back (i->second);
2740 i->second->drop_references ();
2746 /* build a list of all the possible audio directories for the session */
2748 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2753 SessionDirectory sdir ((*i).path);
2754 audio_path += sdir.sound_path();
2756 if (nexti != session_dirs.end()) {
2764 /* build a list of all the possible midi directories for the session */
2766 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2771 SessionDirectory sdir ((*i).path);
2772 midi_path += sdir.midi_path();
2774 if (nexti != session_dirs.end()) {
2781 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2782 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2788 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2789 candidates->push_back (*i);
2794 candidates = candidates2; // might still be null
2797 /* find all sources, but don't use this snapshot because the
2798 state file on disk still references sources we may have already
2802 find_all_sources_across_snapshots (all_sources, true);
2804 /* add our current source list
2807 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2808 boost::shared_ptr<FileSource> fs;
2809 SourceMap::iterator tmp = i;
2812 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2813 if (playlists->source_use_count (fs) != 0) {
2814 all_sources.insert (fs->path());
2817 /* we might not remove this source from disk, because it may be used
2818 by other snapshots, but its not being used in this version
2819 so lets get rid of it now, along with any representative regions
2823 RegionFactory::remove_regions_using_source (i->second);
2831 char tmppath1[PATH_MAX+1];
2832 char tmppath2[PATH_MAX+1];
2835 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2840 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2842 if (realpath(spath.c_str(), tmppath1) == 0) {
2843 error << string_compose (_("Cannot expand path %1 (%2)"),
2844 spath, strerror (errno)) << endmsg;
2848 if (realpath((*i).c_str(), tmppath2) == 0) {
2849 error << string_compose (_("Cannot expand path %1 (%2)"),
2850 (*i), strerror (errno)) << endmsg;
2854 if (strcmp(tmppath1, tmppath2) == 0) {
2861 unused.push_back (spath);
2870 /* now try to move all unused files into the "dead" directory(ies) */
2872 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2873 struct stat statbuf;
2877 /* don't move the file across filesystems, just
2878 stick it in the `dead_dir_name' directory
2879 on whichever filesystem it was already on.
2882 if ((*x).find ("/sounds/") != string::npos) {
2884 /* old school, go up 1 level */
2886 newpath = Glib::path_get_dirname (*x); // "sounds"
2887 newpath = Glib::path_get_dirname (newpath); // "session-name"
2891 /* new school, go up 4 levels */
2893 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2894 newpath = Glib::path_get_dirname (newpath); // "session-name"
2895 newpath = Glib::path_get_dirname (newpath); // "interchange"
2896 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2899 newpath = Glib::build_filename (newpath, dead_dir_name);
2901 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2902 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2906 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2908 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2910 /* the new path already exists, try versioning */
2912 char buf[PATH_MAX+1];
2916 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2919 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2920 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2924 if (version == 999) {
2925 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2929 newpath = newpath_v;
2934 /* it doesn't exist, or we can't read it or something */
2938 stat ((*x).c_str(), &statbuf);
2940 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2941 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2942 (*x), newpath, strerror (errno))
2947 /* see if there an easy to find peakfile for this file, and remove it.
2950 string base = basename_nosuffix (*x);
2951 base += "%A"; /* this is what we add for the channel suffix of all native files,
2952 or for the first channel of embedded files. it will miss
2953 some peakfiles for other channels
2955 string peakpath = peak_path (base);
2957 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2958 if (::unlink (peakpath.c_str()) != 0) {
2959 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2960 peakpath, _path, strerror (errno))
2962 /* try to back out */
2963 ::rename (newpath.c_str(), _path.c_str());
2968 rep.paths.push_back (*x);
2969 rep.space += statbuf.st_size;
2972 /* dump the history list */
2976 /* save state so we don't end up a session file
2977 referring to non-existent sources.
2984 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2990 Session::cleanup_trash_sources (CleanupReport& rep)
2992 // FIXME: needs adaptation for MIDI
2994 vector<space_and_path>::iterator i;
3000 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3002 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
3004 clear_directory (dead_dir, &rep.space, &rep.paths);
3011 Session::set_dirty ()
3013 bool was_dirty = dirty();
3015 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3019 DirtyChanged(); /* EMIT SIGNAL */
3025 Session::set_clean ()
3027 bool was_dirty = dirty();
3029 _state_of_the_state = Clean;
3033 DirtyChanged(); /* EMIT SIGNAL */
3038 Session::set_deletion_in_progress ()
3040 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3044 Session::clear_deletion_in_progress ()
3046 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3050 Session::add_controllable (boost::shared_ptr<Controllable> c)
3052 /* this adds a controllable to the list managed by the Session.
3053 this is a subset of those managed by the Controllable class
3054 itself, and represents the only ones whose state will be saved
3055 as part of the session.
3058 Glib::Mutex::Lock lm (controllables_lock);
3059 controllables.insert (c);
3062 struct null_deleter { void operator()(void const *) const {} };
3065 Session::remove_controllable (Controllable* c)
3067 if (_state_of_the_state & Deletion) {
3071 Glib::Mutex::Lock lm (controllables_lock);
3073 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3075 if (x != controllables.end()) {
3076 controllables.erase (x);
3080 boost::shared_ptr<Controllable>
3081 Session::controllable_by_id (const PBD::ID& id)
3083 Glib::Mutex::Lock lm (controllables_lock);
3085 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3086 if ((*i)->id() == id) {
3091 return boost::shared_ptr<Controllable>();
3094 boost::shared_ptr<Controllable>
3095 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3097 boost::shared_ptr<Controllable> c;
3098 boost::shared_ptr<Route> r;
3100 switch (desc.top_level_type()) {
3101 case ControllableDescriptor::NamedRoute:
3103 std::string str = desc.top_level_name();
3104 if (str == "master") {
3106 } else if (str == "control" || str == "listen") {
3109 r = route_by_name (desc.top_level_name());
3114 case ControllableDescriptor::RemoteControlID:
3115 r = route_by_remote_id (desc.rid());
3123 switch (desc.subtype()) {
3124 case ControllableDescriptor::Gain:
3125 c = r->gain_control ();
3128 case ControllableDescriptor::Solo:
3129 c = r->solo_control();
3132 case ControllableDescriptor::Mute:
3133 c = r->mute_control();
3136 case ControllableDescriptor::Recenable:
3138 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3141 c = t->rec_enable_control ();
3146 case ControllableDescriptor::PanDirection:
3148 c = r->pannable()->pan_azimuth_control;
3152 case ControllableDescriptor::PanWidth:
3154 c = r->pannable()->pan_width_control;
3158 case ControllableDescriptor::PanElevation:
3160 c = r->pannable()->pan_elevation_control;
3164 case ControllableDescriptor::Balance:
3165 /* XXX simple pan control */
3168 case ControllableDescriptor::PluginParameter:
3170 uint32_t plugin = desc.target (0);
3171 uint32_t parameter_index = desc.target (1);
3173 /* revert to zero based counting */
3179 if (parameter_index > 0) {
3183 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3186 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3187 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3192 case ControllableDescriptor::SendGain:
3194 uint32_t send = desc.target (0);
3196 /* revert to zero-based counting */
3202 boost::shared_ptr<Processor> p = r->nth_send (send);
3205 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3206 boost::shared_ptr<Amp> a = s->amp();
3209 c = s->amp()->gain_control();
3216 /* relax and return a null pointer */
3224 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3227 Stateful::add_instant_xml (node, _path);
3230 if (write_to_config) {
3231 Config->add_instant_xml (node);
3236 Session::instant_xml (const string& node_name)
3238 return Stateful::instant_xml (node_name, _path);
3242 Session::save_history (string snapshot_name)
3250 if (snapshot_name.empty()) {
3251 snapshot_name = _current_snapshot_name;
3254 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3255 const string backup_filename = history_filename + backup_suffix;
3256 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3257 const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3259 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3260 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3261 error << _("could not backup old history file, current history not saved") << endmsg;
3266 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3270 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3272 if (!tree.write (xml_path))
3274 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3276 if (g_remove (xml_path.c_str()) != 0) {
3277 error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3278 xml_path, g_strerror (errno)) << endmsg;
3280 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3281 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3282 backup_path, g_strerror (errno)) << endmsg;
3292 Session::restore_history (string snapshot_name)
3296 if (snapshot_name.empty()) {
3297 snapshot_name = _current_snapshot_name;
3300 const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3301 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3303 info << "Loading history from " << xml_path << endmsg;
3305 if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3306 info << string_compose (_("%1: no history file \"%2\" for this session."),
3307 _name, xml_path) << endmsg;
3311 if (!tree.read (xml_path)) {
3312 error << string_compose (_("Could not understand session history file \"%1\""),
3313 xml_path) << endmsg;
3320 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3323 UndoTransaction* ut = new UndoTransaction ();
3326 ut->set_name(t->property("name")->value());
3327 stringstream ss(t->property("tv-sec")->value());
3329 ss.str(t->property("tv-usec")->value());
3331 ut->set_timestamp(tv);
3333 for (XMLNodeConstIterator child_it = t->children().begin();
3334 child_it != t->children().end(); child_it++)
3336 XMLNode *n = *child_it;
3339 if (n->name() == "MementoCommand" ||
3340 n->name() == "MementoUndoCommand" ||
3341 n->name() == "MementoRedoCommand") {
3343 if ((c = memento_command_factory(n))) {
3347 } else if (n->name() == "NoteDiffCommand") {
3348 PBD::ID id (n->property("midi-source")->value());
3349 boost::shared_ptr<MidiSource> midi_source =
3350 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3352 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3354 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3357 } else if (n->name() == "SysExDiffCommand") {
3359 PBD::ID id (n->property("midi-source")->value());
3360 boost::shared_ptr<MidiSource> midi_source =
3361 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3363 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3365 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3368 } else if (n->name() == "PatchChangeDiffCommand") {
3370 PBD::ID id (n->property("midi-source")->value());
3371 boost::shared_ptr<MidiSource> midi_source =
3372 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3374 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3376 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3379 } else if (n->name() == "StatefulDiffCommand") {
3380 if ((c = stateful_diff_command_factory (n))) {
3381 ut->add_command (c);
3384 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3395 Session::config_changed (std::string p, bool ours)
3401 if (p == "seamless-loop") {
3403 } else if (p == "rf-speed") {
3405 } else if (p == "auto-loop") {
3407 } else if (p == "auto-input") {
3409 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3410 /* auto-input only makes a difference if we're rolling */
3411 set_track_monitor_input_status (!config.get_auto_input());
3414 } else if (p == "punch-in") {
3418 if ((location = _locations->auto_punch_location()) != 0) {
3420 if (config.get_punch_in ()) {
3421 replace_event (SessionEvent::PunchIn, location->start());
3423 remove_event (location->start(), SessionEvent::PunchIn);
3427 } else if (p == "punch-out") {
3431 if ((location = _locations->auto_punch_location()) != 0) {
3433 if (config.get_punch_out()) {
3434 replace_event (SessionEvent::PunchOut, location->end());
3436 clear_events (SessionEvent::PunchOut);
3440 } else if (p == "edit-mode") {
3442 Glib::Mutex::Lock lm (playlists->lock);
3444 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3445 (*i)->set_edit_mode (Config->get_edit_mode ());
3448 } else if (p == "use-video-sync") {
3450 waiting_for_sync_offset = config.get_use_video_sync();
3452 } else if (p == "mmc-control") {
3454 //poke_midi_thread ();
3456 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3458 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3460 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3462 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3464 } else if (p == "midi-control") {
3466 //poke_midi_thread ();
3468 } else if (p == "raid-path") {
3470 setup_raid_path (config.get_raid_path());
3472 } else if (p == "timecode-format") {
3476 } else if (p == "video-pullup") {
3480 } else if (p == "seamless-loop") {
3482 if (play_loop && transport_rolling()) {
3483 // to reset diskstreams etc
3484 request_play_loop (true);
3487 } else if (p == "rf-speed") {
3489 cumulative_rf_motion = 0;
3492 } else if (p == "click-sound") {
3494 setup_click_sounds (1);
3496 } else if (p == "click-emphasis-sound") {
3498 setup_click_sounds (-1);
3500 } else if (p == "clicking") {
3502 if (Config->get_clicking()) {
3503 if (_click_io && click_data) { // don't require emphasis data
3510 } else if (p == "click-gain") {
3513 _click_gain->set_gain (Config->get_click_gain(), this);
3516 } else if (p == "send-mtc") {
3518 if (Config->get_send_mtc ()) {
3519 /* mark us ready to send */
3520 next_quarter_frame_to_send = 0;
3523 } else if (p == "send-mmc") {
3525 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3527 } else if (p == "midi-feedback") {
3529 session_midi_feedback = Config->get_midi_feedback();
3531 } else if (p == "jack-time-master") {
3533 engine().reset_timebase ();
3535 } else if (p == "native-file-header-format") {
3537 if (!first_file_header_format_reset) {
3538 reset_native_file_format ();
3541 first_file_header_format_reset = false;
3543 } else if (p == "native-file-data-format") {
3545 if (!first_file_data_format_reset) {
3546 reset_native_file_format ();
3549 first_file_data_format_reset = false;
3551 } else if (p == "external-sync") {
3552 if (!config.get_external_sync()) {
3553 drop_sync_source ();
3555 switch_to_sync_source (config.get_sync_source());
3557 } else if (p == "remote-model") {
3558 set_remote_control_ids ();
3559 } else if (p == "denormal-model") {
3561 } else if (p == "history-depth") {
3562 set_history_depth (Config->get_history_depth());
3563 } else if (p == "sync-all-route-ordering") {
3564 sync_order_keys ("session");
3565 } else if (p == "initial-program-change") {
3567 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3570 buf[0] = MIDI::program; // channel zero by default
3571 buf[1] = (Config->get_initial_program_change() & 0x7f);
3573 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3575 } else if (p == "solo-mute-override") {
3576 // catch_up_on_solo_mute_override ();
3577 } else if (p == "listen-position" || p == "pfl-position") {
3578 listen_position_changed ();
3579 } else if (p == "solo-control-is-listen-control") {
3580 solo_control_mode_changed ();
3581 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3582 last_timecode_valid = false;
3583 } else if (p == "playback-buffer-seconds") {
3584 AudioSource::allocate_working_buffers (frame_rate());
3585 } else if (p == "automation-thinning-factor") {
3586 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3593 Session::set_history_depth (uint32_t d)
3595 _history.set_depth (d);
3599 Session::load_diskstreams_2X (XMLNode const & node, int)
3602 XMLNodeConstIterator citer;
3604 clist = node.children();
3606 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3609 /* diskstreams added automatically by DiskstreamCreated handler */
3610 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3611 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3612 _diskstreams_2X.push_back (dsp);
3614 error << _("Session: unknown diskstream type in XML") << endmsg;
3618 catch (failed_constructor& err) {
3619 error << _("Session: could not load diskstream via XML state") << endmsg;
3627 /** Connect things to the MMC object */
3629 Session::setup_midi_machine_control ()
3631 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3633 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3634 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3635 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3636 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3637 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3638 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3639 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3640 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3641 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3642 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3643 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3644 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3645 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3647 /* also handle MIDI SPP because its so common */
3649 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3650 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3651 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3654 boost::shared_ptr<Controllable>
3655 Session::solo_cut_control() const
3657 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3658 controls in Ardour that currently get presented to the user in the GUI that require
3659 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3661 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3662 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3666 return _solo_cut_control;
3670 Session::rename (const std::string& new_name)
3672 string legal_name = legalize_for_path (new_name);
3678 string const old_sources_root = _session_dir->sources_root();
3680 #define RENAME ::rename
3685 * interchange subdirectory
3689 * Backup files are left unchanged and not renamed.
3692 /* pass one: not 100% safe check that the new directory names don't
3696 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3701 /* this is a stupid hack because Glib::path_get_dirname() is
3702 * lexical-only, and so passing it /a/b/c/ gives a different
3703 * result than passing it /a/b/c ...
3706 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3707 oldstr = oldstr.substr (0, oldstr.length() - 1);
3710 string base = Glib::path_get_dirname (oldstr);
3711 string p = Glib::path_get_basename (oldstr);
3713 newstr = Glib::build_filename (base, legal_name);
3715 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3722 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3727 /* this is a stupid hack because Glib::path_get_dirname() is
3728 * lexical-only, and so passing it /a/b/c/ gives a different
3729 * result than passing it /a/b/c ...
3732 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3733 oldstr = oldstr.substr (0, oldstr.length() - 1);
3736 string base = Glib::path_get_dirname (oldstr);
3737 string p = Glib::path_get_basename (oldstr);
3739 newstr = Glib::build_filename (base, legal_name);
3741 cerr << "Rename " << oldstr << " => " << newstr << endl;
3743 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3748 (*_session_dir) = newstr;
3753 /* directory below interchange */
3755 v.push_back (newstr);
3756 v.push_back (interchange_dir_name);
3759 oldstr = Glib::build_filename (v);
3762 v.push_back (newstr);
3763 v.push_back (interchange_dir_name);
3764 v.push_back (legal_name);
3766 newstr = Glib::build_filename (v);
3768 cerr << "Rename " << oldstr << " => " << newstr << endl;
3770 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3777 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3778 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3780 cerr << "Rename " << oldstr << " => " << newstr << endl;
3782 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3789 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3791 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3792 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3794 cerr << "Rename " << oldstr << " => " << newstr << endl;
3796 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3801 /* update file source paths */
3803 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3804 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3806 string p = fs->path ();
3807 boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3812 /* remove old name from recent sessions */
3814 remove_recent_sessions (_path);
3817 _current_snapshot_name = new_name;
3822 /* save state again to get everything just right */
3824 save_state (_current_snapshot_name);
3827 /* add to recent sessions */
3829 store_recent_sessions (new_name, _path);