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>
52 #include <glibmm/thread.h>
54 #include <boost/algorithm/string.hpp>
56 #include "midi++/mmc.h"
57 #include "midi++/port.h"
58 #include "midi++/manager.h"
60 #include "pbd/boost_debug.h"
61 #include "pbd/basename.h"
62 #include "pbd/controllable_descriptor.h"
63 #include "pbd/enumwriter.h"
64 #include "pbd/error.h"
65 #include "pbd/pathscanner.h"
66 #include "pbd/pthread_utils.h"
67 #include "pbd/search_path.h"
68 #include "pbd/stacktrace.h"
69 #include "pbd/convert.h"
70 #include "pbd/clear_dir.h"
72 #include "ardour/amp.h"
73 #include "ardour/audio_diskstream.h"
74 #include "ardour/audio_playlist_source.h"
75 #include "ardour/audio_track.h"
76 #include "ardour/audioengine.h"
77 #include "ardour/audiofilesource.h"
78 #include "ardour/audioplaylist.h"
79 #include "ardour/audioregion.h"
80 #include "ardour/auditioner.h"
81 #include "ardour/automation_control.h"
82 #include "ardour/buffer.h"
83 #include "ardour/butler.h"
84 #include "ardour/configuration.h"
85 #include "ardour/control_protocol_manager.h"
86 #include "ardour/crossfade.h"
87 #include "ardour/cycle_timer.h"
88 #include "ardour/directory_names.h"
89 #include "ardour/filename_extensions.h"
90 #include "ardour/io_processor.h"
91 #include "ardour/location.h"
92 #include "ardour/midi_diskstream.h"
93 #include "ardour/midi_model.h"
94 #include "ardour/midi_patch_manager.h"
95 #include "ardour/midi_playlist.h"
96 #include "ardour/midi_region.h"
97 #include "ardour/midi_source.h"
98 #include "ardour/midi_track.h"
99 #include "ardour/named_selection.h"
100 #include "ardour/pannable.h"
101 #include "ardour/processor.h"
102 #include "ardour/port.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_state_utils.h"
112 #include "ardour/session_playlists.h"
113 #include "ardour/session_utils.h"
114 #include "ardour/silentfilesource.h"
115 #include "ardour/slave.h"
116 #include "ardour/smf_source.h"
117 #include "ardour/sndfile_helpers.h"
118 #include "ardour/sndfilesource.h"
119 #include "ardour/source_factory.h"
120 #include "ardour/speakers.h"
121 #include "ardour/template_utils.h"
122 #include "ardour/tempo.h"
123 #include "ardour/ticker.h"
124 #include "ardour/user_bundle.h"
125 #include "ardour/utils.h"
126 #include "ardour/utils.h"
127 #include "ardour/version.h"
128 #include "ardour/playlist_factory.h"
130 #include "control_protocol/control_protocol.h"
136 using namespace ARDOUR;
139 /** @param snapshot_name Snapshot name, without the .ardour prefix */
141 Session::first_stage_init (string fullpath, string snapshot_name)
143 if (fullpath.length() == 0) {
145 throw failed_constructor();
148 char buf[PATH_MAX+1];
149 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
150 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
152 throw failed_constructor();
157 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
158 _path += G_DIR_SEPARATOR;
161 /* these two are just provisional settings. set_state()
162 will likely override them.
165 _name = _current_snapshot_name = snapshot_name;
167 set_history_depth (Config->get_history_depth());
169 _current_frame_rate = _engine.frame_rate ();
170 _nominal_frame_rate = _current_frame_rate;
171 _base_frame_rate = _current_frame_rate;
173 _tempo_map = new TempoMap (_current_frame_rate);
174 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
177 _non_soloed_outs_muted = false;
179 _solo_isolated_cnt = 0;
180 g_atomic_int_set (&processing_prohibited, 0);
181 _transport_speed = 0;
182 _last_transport_speed = 0;
183 _target_transport_speed = 0;
184 auto_play_legal = false;
185 transport_sub_state = 0;
186 _transport_frame = 0;
187 _requested_return_frame = -1;
188 _session_range_location = 0;
189 g_atomic_int_set (&_record_status, Disabled);
190 loop_changing = false;
193 _last_roll_location = 0;
194 _last_roll_or_reversal_location = 0;
195 _last_record_location = 0;
196 pending_locate_frame = 0;
197 pending_locate_roll = false;
198 pending_locate_flush = false;
199 state_was_pending = false;
201 outbound_mtc_timecode_frame = 0;
202 next_quarter_frame_to_send = -1;
203 current_block_size = 0;
204 solo_update_disabled = false;
205 _have_captured = false;
206 _worst_output_latency = 0;
207 _worst_input_latency = 0;
208 _worst_track_latency = 0;
209 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
210 _was_seamless = Config->get_seamless_loop ();
212 _send_qf_mtc = false;
213 _pframes_since_last_mtc = 0;
214 g_atomic_int_set (&_playback_load, 100);
215 g_atomic_int_set (&_capture_load, 100);
218 pending_abort = false;
219 destructive_index = 0;
220 first_file_data_format_reset = true;
221 first_file_header_format_reset = true;
222 post_export_sync = false;
225 no_questions_about_missing_files = false;
226 _speakers.reset (new Speakers);
228 ignore_route_processor_changes = false;
230 AudioDiskstream::allocate_working_buffers();
232 /* default short fade = 15ms */
234 Crossfade::set_short_xfade_length ((framecnt_t) floor (config.get_short_xfade_seconds() * frame_rate()));
235 SndFileSource::setup_standard_crossfades (*this, frame_rate());
237 last_mmc_step.tv_sec = 0;
238 last_mmc_step.tv_usec = 0;
241 /* click sounds are unset by default, which causes us to internal
242 waveforms for clicks.
246 click_emphasis_length = 0;
249 process_function = &Session::process_with_events;
251 if (config.get_use_video_sync()) {
252 waiting_for_sync_offset = true;
254 waiting_for_sync_offset = false;
257 last_timecode_when = 0;
258 last_timecode_valid = false;
262 last_rr_session_dir = session_dirs.begin();
263 refresh_disk_space ();
265 /* default: assume simple stereo speaker configuration */
267 _speakers->setup_default_speakers (2);
271 average_slave_delta = 1800; // !!! why 1800 ????
272 have_first_delta_accumulator = false;
273 delta_accumulator_cnt = 0;
274 _slave_state = Stopped;
276 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
277 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
278 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
279 add_controllable (_solo_cut_control);
281 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
283 /* These are all static "per-class" signals */
285 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
286 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
287 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
288 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
289 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
291 /* stop IO objects from doing stuff until we're ready for them */
293 Delivery::disable_panners ();
294 IO::disable_connecting ();
298 Session::second_stage_init ()
300 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
303 if (load_state (_current_snapshot_name)) {
308 if (_butler->start_thread()) {
312 if (start_midi_thread ()) {
316 setup_midi_machine_control ();
318 // set_state() will call setup_raid_path(), but if it's a new session we need
319 // to call setup_raid_path() here.
322 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
326 setup_raid_path(_path);
329 /* we can't save till after ::when_engine_running() is called,
330 because otherwise we save state with no connections made.
331 therefore, we reset _state_of_the_state because ::set_state()
332 will have cleared it.
334 we also have to include Loading so that any events that get
335 generated between here and the end of ::when_engine_running()
336 will be processed directly rather than queued.
339 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
341 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
342 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
343 setup_click_sounds (0);
344 setup_midi_control ();
346 /* Pay attention ... */
348 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
349 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
351 midi_clock = new MidiClockTicker ();
352 midi_clock->set_session (this);
355 when_engine_running ();
358 /* handle this one in a different way than all others, so that its clear what happened */
360 catch (AudioEngine::PortRegistrationFailure& err) {
361 error << err.what() << endmsg;
369 BootMessage (_("Reset Remote Controls"));
371 send_full_time_code (0);
372 _engine.transport_locate (0);
374 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
375 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
377 MIDI::Name::MidiPatchManager::instance().set_session (this);
379 /* initial program change will be delivered later; see ::config_changed() */
381 _state_of_the_state = Clean;
383 Port::set_connecting_blocked (false);
385 DirtyChanged (); /* EMIT SIGNAL */
387 if (state_was_pending) {
388 save_state (_current_snapshot_name);
389 remove_pending_capture_state ();
390 state_was_pending = false;
393 BootMessage (_("Session loading complete"));
399 Session::raid_path () const
401 SearchPath raid_search_path;
403 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
404 raid_search_path += sys::path((*i).path);
407 return raid_search_path.to_string ();
411 Session::setup_raid_path (string path)
420 session_dirs.clear ();
422 SearchPath search_path(path);
423 SearchPath sound_search_path;
424 SearchPath midi_search_path;
426 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
427 sp.path = (*i).to_string ();
428 sp.blocks = 0; // not needed
429 session_dirs.push_back (sp);
431 SessionDirectory sdir(sp.path);
433 sound_search_path += sdir.sound_path ();
434 midi_search_path += sdir.midi_path ();
437 // reset the round-robin soundfile path thingie
438 last_rr_session_dir = session_dirs.begin();
442 Session::path_is_within_session (const std::string& path)
444 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
445 if (path.find ((*i).path) == 0) {
453 Session::ensure_subdirs ()
457 dir = session_directory().peak_path().to_string();
459 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
460 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
464 dir = session_directory().sound_path().to_string();
466 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
467 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
471 dir = session_directory().midi_path().to_string();
473 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
474 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
478 dir = session_directory().dead_path().to_string();
480 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
481 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
485 dir = session_directory().export_path().to_string();
487 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
488 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
492 dir = analysis_dir ();
494 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
495 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
499 dir = plugins_dir ();
501 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
502 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
509 /** @param session_template directory containing session template, or empty.
510 * Caller must not hold process lock.
513 Session::create (const string& session_template, BusProfile* bus_profile)
515 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
516 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
520 if (ensure_subdirs ()) {
524 _writable = exists_and_writable (sys::path (_path));
526 if (!session_template.empty()) {
527 std::string in_path = session_template_dir_to_file (session_template);
529 ifstream in(in_path.c_str());
532 string out_path = _path;
534 out_path += statefile_suffix;
536 ofstream out(out_path.c_str());
542 /* Copy plugin state files from template to new session */
543 sys::path template_plugins = session_template;
544 template_plugins /= X_("plugins");
545 sys::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 /* Instantiate metadata */
565 _metadata = new SessionMetadata ();
567 /* set initial start + end point */
569 _state_of_the_state = Clean;
571 /* set up Master Out and Control Out if necessary */
576 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
578 if (bus_profile->master_out_channels) {
579 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
583 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
584 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
587 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
588 r->input()->ensure_io (count, false, this);
589 r->output()->ensure_io (count, false, this);
595 /* prohibit auto-connect to master, because there isn't one */
596 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
600 add_routes (rl, false, false);
603 /* this allows the user to override settings with an environment variable.
606 if (no_auto_connect()) {
607 bus_profile->input_ac = AutoConnectOption (0);
608 bus_profile->output_ac = AutoConnectOption (0);
611 Config->set_input_auto_connect (bus_profile->input_ac);
612 Config->set_output_auto_connect (bus_profile->output_ac);
615 if (Config->get_use_monitor_bus() && bus_profile) {
616 add_monitor_section ();
625 Session::maybe_write_autosave()
627 if (dirty() && record_status() != Recording) {
628 save_state("", true);
633 Session::remove_pending_capture_state ()
635 sys::path pending_state_file_path(_session_dir->root_path());
637 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
641 sys::remove (pending_state_file_path);
643 catch(sys::filesystem_error& ex)
645 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
646 pending_state_file_path.to_string(), ex.what()) << endmsg;
650 /** Rename a state file.
651 * @param old_name Old snapshot name.
652 * @param new_name New snapshot name.
655 Session::rename_state (string old_name, string new_name)
657 if (old_name == _current_snapshot_name || old_name == _name) {
658 /* refuse to rename the current snapshot or the "main" one */
662 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
663 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
665 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
666 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
670 sys::rename (old_xml_path, new_xml_path);
672 catch (const sys::filesystem_error& err)
674 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
675 old_name, new_name, err.what()) << endmsg;
679 /** Remove a state file.
680 * @param snapshot_name Snapshot name.
683 Session::remove_state (string snapshot_name)
685 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
686 // refuse to remove the current snapshot or the "main" one
690 sys::path xml_path(_session_dir->root_path());
692 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
694 if (!create_backup_file (xml_path)) {
695 // don't remove it if a backup can't be made
696 // create_backup_file will log the error.
701 sys::remove (xml_path);
704 #ifdef HAVE_JACK_SESSION
706 Session::jack_session_event (jack_session_event_t * event)
710 struct tm local_time;
713 localtime_r (&n, &local_time);
714 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
716 if (event->type == JackSessionSaveTemplate)
718 if (save_template( timebuf )) {
719 event->flags = JackSessionSaveError;
721 string cmd ("ardour3 -P -U ");
722 cmd += event->client_uuid;
726 event->command_line = strdup (cmd.c_str());
731 if (save_state (timebuf)) {
732 event->flags = JackSessionSaveError;
734 sys::path xml_path (_session_dir->root_path());
735 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
737 string cmd ("ardour3 -P -U ");
738 cmd += event->client_uuid;
740 cmd += xml_path.to_string();
743 event->command_line = strdup (cmd.c_str());
747 jack_session_reply (_engine.jack(), 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 sys::path 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 tree.set_root (&get_state());
787 if (snapshot_name.empty()) {
788 snapshot_name = _current_snapshot_name;
789 } else if (switch_to_snapshot) {
790 _current_snapshot_name = snapshot_name;
795 /* proper save: use statefile_suffix (.ardour in English) */
797 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
799 /* make a backup copy of the old file */
801 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
802 // create_backup_file will log the error
808 /* pending save: use pending_suffix (.pending in English) */
809 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
812 sys::path tmp_path(_session_dir->root_path());
814 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
816 // cerr << "actually writing state to " << xml_path.to_string() << endl;
818 if (!tree.write (tmp_path.to_string())) {
819 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
820 sys::remove (tmp_path);
825 if (::rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
826 error << string_compose (_("could not rename temporary session file %1 to %2"),
827 tmp_path.to_string(), xml_path.to_string()) << endmsg;
828 sys::remove (tmp_path);
835 save_history (snapshot_name);
837 bool was_dirty = dirty();
839 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
842 DirtyChanged (); /* EMIT SIGNAL */
845 StateSaved (snapshot_name); /* EMIT SIGNAL */
852 Session::restore_state (string snapshot_name)
854 if (load_state (snapshot_name) == 0) {
855 set_state (*state_tree->root(), Stateful::loading_state_version);
862 Session::load_state (string snapshot_name)
867 state_was_pending = false;
869 /* check for leftover pending state from a crashed capture attempt */
871 sys::path xmlpath(_session_dir->root_path());
872 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
874 if (sys::exists (xmlpath)) {
876 /* there is pending state from a crashed capture attempt */
878 boost::optional<int> r = AskAboutPendingState();
879 if (r.get_value_or (1)) {
880 state_was_pending = true;
884 if (!state_was_pending) {
885 xmlpath = _session_dir->root_path();
886 xmlpath /= snapshot_name;
889 if (!sys::exists (xmlpath)) {
890 xmlpath = _session_dir->root_path();
891 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
892 if (!sys::exists (xmlpath)) {
893 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
898 state_tree = new XMLTree;
902 _writable = exists_and_writable (xmlpath);
904 if (!state_tree->read (xmlpath.to_string())) {
905 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
911 XMLNode& root (*state_tree->root());
913 if (root.name() != X_("Session")) {
914 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
920 const XMLProperty* prop;
922 if ((prop = root.property ("version")) == 0) {
923 /* no version implies very old version of Ardour */
924 Stateful::loading_state_version = 1000;
930 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
931 Stateful::loading_state_version = (major * 1000) + minor;
934 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
936 sys::path backup_path(_session_dir->root_path());
938 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
940 // only create a backup once
941 if (sys::exists (backup_path)) {
945 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
946 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
951 sys::copy_file (xmlpath, backup_path);
953 catch(sys::filesystem_error& ex)
955 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
956 xmlpath.to_string(), ex.what())
966 Session::load_options (const XMLNode& node)
968 LocaleGuard lg (X_("POSIX"));
969 config.set_variables (node);
980 Session::get_template()
982 /* if we don't disable rec-enable, diskstreams
983 will believe they need to store their capture
984 sources in their state node.
987 disable_record (false);
993 Session::state(bool full_state)
995 XMLNode* node = new XMLNode("Session");
998 // store libardour version, just in case
1000 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
1001 node->add_property("version", string(buf));
1003 /* store configuration settings */
1007 node->add_property ("name", _name);
1008 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1009 node->add_property ("sample-rate", buf);
1011 if (session_dirs.size() > 1) {
1015 vector<space_and_path>::iterator i = session_dirs.begin();
1016 vector<space_and_path>::iterator next;
1018 ++i; /* skip the first one */
1022 while (i != session_dirs.end()) {
1026 if (next != session_dirs.end()) {
1036 child = node->add_child ("Path");
1037 child->add_content (p);
1041 /* save the ID counter */
1043 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1044 node->add_property ("id-counter", buf);
1046 /* save the event ID counter */
1048 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1049 node->add_property ("event-counter", buf);
1051 /* various options */
1053 node->add_child_nocopy (config.get_variables ());
1055 node->add_child_nocopy (_metadata->get_state());
1057 child = node->add_child ("Sources");
1060 Glib::Mutex::Lock sl (source_lock);
1062 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1064 /* Don't save information about non-file Sources, or
1065 * about non-destructive file sources that are empty
1066 * and unused by any regions.
1069 boost::shared_ptr<FileSource> fs;
1071 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1073 if (!fs->destructive()) {
1074 if (fs->empty() && !fs->used()) {
1079 child->add_child_nocopy (siter->second->get_state());
1084 child = node->add_child ("Regions");
1087 Glib::Mutex::Lock rl (region_lock);
1088 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1089 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1090 boost::shared_ptr<Region> r = i->second;
1091 /* only store regions not attached to playlists */
1092 if (r->playlist() == 0) {
1093 child->add_child_nocopy (r->state ());
1097 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1099 if (!cassocs.empty()) {
1100 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1102 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1104 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1105 i->first->id().print (buf, sizeof (buf));
1106 can->add_property (X_("copy"), buf);
1107 i->second->id().print (buf, sizeof (buf));
1108 can->add_property (X_("original"), buf);
1109 ca->add_child_nocopy (*can);
1115 node->add_child_nocopy (_locations->get_state());
1117 // for a template, just create a new Locations, populate it
1118 // with the default start and end, and get the state for that.
1119 Locations loc (*this);
1120 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1121 range->set (max_framepos, 0);
1123 node->add_child_nocopy (loc.get_state());
1126 child = node->add_child ("Bundles");
1128 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1129 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1130 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1132 child->add_child_nocopy (b->get_state());
1137 child = node->add_child ("Routes");
1139 boost::shared_ptr<RouteList> r = routes.reader ();
1141 RoutePublicOrderSorter cmp;
1142 RouteList public_order (*r);
1143 public_order.sort (cmp);
1145 /* the sort should have put control outs first */
1148 assert (_monitor_out == public_order.front());
1151 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1152 if (!(*i)->is_hidden()) {
1154 child->add_child_nocopy ((*i)->get_state());
1156 child->add_child_nocopy ((*i)->get_template());
1162 playlists->add_state (node, full_state);
1164 child = node->add_child ("RouteGroups");
1165 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1166 child->add_child_nocopy ((*i)->get_state());
1170 XMLNode* gain_child = node->add_child ("Click");
1171 gain_child->add_child_nocopy (_click_io->state (full_state));
1172 gain_child->add_child_nocopy (_click_gain->state (full_state));
1176 XMLNode* ns_child = node->add_child ("NamedSelections");
1177 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1179 ns_child->add_child_nocopy ((*i)->get_state());
1184 node->add_child_nocopy (_speakers->get_state());
1185 node->add_child_nocopy (_tempo_map->get_state());
1186 node->add_child_nocopy (get_control_protocol_state());
1189 node->add_child_copy (*_extra_xml);
1196 Session::get_control_protocol_state ()
1198 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1199 return cpm.get_state();
1203 Session::set_state (const XMLNode& node, int version)
1207 const XMLProperty* prop;
1210 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1212 if (node.name() != X_("Session")) {
1213 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1217 if ((prop = node.property ("version")) != 0) {
1218 version = atoi (prop->value ()) * 1000;
1221 if ((prop = node.property ("name")) != 0) {
1222 _name = prop->value ();
1225 if ((prop = node.property (X_("sample-rate"))) != 0) {
1227 _nominal_frame_rate = atoi (prop->value());
1229 if (_nominal_frame_rate != _current_frame_rate) {
1230 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1231 if (r.get_value_or (0)) {
1237 setup_raid_path(_session_dir->root_path().to_string());
1239 if ((prop = node.property (X_("id-counter"))) != 0) {
1241 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1242 ID::init_counter (x);
1244 /* old sessions used a timebased counter, so fake
1245 the startup ID counter based on a standard
1250 ID::init_counter (now);
1253 if ((prop = node.property (X_("event-counter"))) != 0) {
1254 Evoral::init_event_id_counter (atoi (prop->value()));
1257 IO::disable_connecting ();
1259 Stateful::save_extra_xml (node);
1261 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1262 load_options (*child);
1263 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1264 load_options (*child);
1266 error << _("Session: XML state has no options section") << endmsg;
1269 if (version >= 3000) {
1270 if ((child = find_named_node (node, "Metadata")) == 0) {
1271 warning << _("Session: XML state has no metadata section") << endmsg;
1272 } else if (_metadata->set_state (*child, version)) {
1277 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1278 _speakers->set_state (*child, version);
1281 if ((child = find_named_node (node, "Sources")) == 0) {
1282 error << _("Session: XML state has no sources section") << endmsg;
1284 } else if (load_sources (*child)) {
1288 if ((child = find_named_node (node, "TempoMap")) == 0) {
1289 error << _("Session: XML state has no Tempo Map section") << endmsg;
1291 } else if (_tempo_map->set_state (*child, version)) {
1295 if ((child = find_named_node (node, "Locations")) == 0) {
1296 error << _("Session: XML state has no locations section") << endmsg;
1298 } else if (_locations->set_state (*child, version)) {
1304 if ((location = _locations->auto_loop_location()) != 0) {
1305 set_auto_loop_location (location);
1308 if ((location = _locations->auto_punch_location()) != 0) {
1309 set_auto_punch_location (location);
1312 if ((location = _locations->session_range_location()) != 0) {
1313 delete _session_range_location;
1314 _session_range_location = location;
1317 if (_session_range_location) {
1318 AudioFileSource::set_header_position_offset (_session_range_location->start());
1321 if ((child = find_named_node (node, "Regions")) == 0) {
1322 error << _("Session: XML state has no Regions section") << endmsg;
1324 } else if (load_regions (*child)) {
1328 if ((child = find_named_node (node, "Playlists")) == 0) {
1329 error << _("Session: XML state has no playlists section") << endmsg;
1331 } else if (playlists->load (*this, *child)) {
1335 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1337 } else if (playlists->load_unused (*this, *child)) {
1341 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1342 if (load_compounds (*child)) {
1347 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1348 if (load_named_selections (*child)) {
1353 if (version >= 3000) {
1354 if ((child = find_named_node (node, "Bundles")) == 0) {
1355 warning << _("Session: XML state has no bundles section") << endmsg;
1358 /* We can't load Bundles yet as they need to be able
1359 to convert from port names to Port objects, which can't happen until
1361 _bundle_xml_node = new XMLNode (*child);
1365 if (version < 3000) {
1366 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1367 error << _("Session: XML state has no diskstreams section") << endmsg;
1369 } else if (load_diskstreams_2X (*child, version)) {
1374 if ((child = find_named_node (node, "Routes")) == 0) {
1375 error << _("Session: XML state has no routes section") << endmsg;
1377 } else if (load_routes (*child, version)) {
1381 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1382 _diskstreams_2X.clear ();
1384 if (version >= 3000) {
1386 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1387 error << _("Session: XML state has no route groups section") << endmsg;
1389 } else if (load_route_groups (*child, version)) {
1393 } else if (version < 3000) {
1395 if ((child = find_named_node (node, "EditGroups")) == 0) {
1396 error << _("Session: XML state has no edit groups section") << endmsg;
1398 } else if (load_route_groups (*child, version)) {
1402 if ((child = find_named_node (node, "MixGroups")) == 0) {
1403 error << _("Session: XML state has no mix groups section") << endmsg;
1405 } else if (load_route_groups (*child, version)) {
1410 if ((child = find_named_node (node, "Click")) == 0) {
1411 warning << _("Session: XML state has no click section") << endmsg;
1412 } else if (_click_io) {
1413 const XMLNodeList& children (child->children());
1414 XMLNodeList::const_iterator i = children.begin();
1415 _click_io->set_state (**i, version);
1417 if (i != children.end()) {
1418 _click_gain->set_state (**i, version);
1422 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1423 ControlProtocolManager::instance().set_protocol_states (*child);
1426 /* here beginneth the second phase ... */
1428 StateReady (); /* EMIT SIGNAL */
1437 Session::load_routes (const XMLNode& node, int version)
1440 XMLNodeConstIterator niter;
1441 RouteList new_routes;
1443 nlist = node.children();
1447 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1449 boost::shared_ptr<Route> route;
1450 if (version < 3000) {
1451 route = XMLRouteFactory_2X (**niter, version);
1453 route = XMLRouteFactory (**niter, version);
1457 error << _("Session: cannot create Route from XML description.") << endmsg;
1461 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1463 new_routes.push_back (route);
1466 add_routes (new_routes, false, false);
1471 boost::shared_ptr<Route>
1472 Session::XMLRouteFactory (const XMLNode& node, int version)
1474 boost::shared_ptr<Route> ret;
1476 if (node.name() != "Route") {
1480 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1482 DataType type = DataType::AUDIO;
1483 const XMLProperty* prop = node.property("default-type");
1486 type = DataType (prop->value());
1489 assert (type != DataType::NIL);
1493 boost::shared_ptr<Track> track;
1495 if (type == DataType::AUDIO) {
1496 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1498 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1501 if (track->init()) {
1505 if (track->set_state (node, version)) {
1509 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1510 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1515 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1517 if (r->init () == 0 && r->set_state (node, version) == 0) {
1518 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1519 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1528 boost::shared_ptr<Route>
1529 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1531 boost::shared_ptr<Route> ret;
1533 if (node.name() != "Route") {
1537 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1539 ds_prop = node.property (X_("diskstream"));
1542 DataType type = DataType::AUDIO;
1543 const XMLProperty* prop = node.property("default-type");
1546 type = DataType (prop->value());
1549 assert (type != DataType::NIL);
1553 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1554 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1558 if (i == _diskstreams_2X.end()) {
1559 error << _("Could not find diskstream for route") << endmsg;
1560 return boost::shared_ptr<Route> ();
1563 boost::shared_ptr<Track> track;
1565 if (type == DataType::AUDIO) {
1566 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1568 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1571 if (track->init()) {
1575 if (track->set_state (node, version)) {
1579 track->set_diskstream (*i);
1581 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1582 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1587 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1589 if (r->init () == 0 && r->set_state (node, version) == 0) {
1590 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1591 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1601 Session::load_regions (const XMLNode& node)
1604 XMLNodeConstIterator niter;
1605 boost::shared_ptr<Region> region;
1607 nlist = node.children();
1611 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1612 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1613 error << _("Session: cannot create Region from XML description.");
1614 const XMLProperty *name = (**niter).property("name");
1617 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1628 Session::load_compounds (const XMLNode& node)
1630 XMLNodeList calist = node.children();
1631 XMLNodeConstIterator caiter;
1632 XMLProperty *caprop;
1634 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1635 XMLNode* ca = *caiter;
1639 if ((caprop = ca->property (X_("original"))) == 0) {
1642 orig_id = caprop->value();
1644 if ((caprop = ca->property (X_("copy"))) == 0) {
1647 copy_id = caprop->value();
1649 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1650 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1652 if (!orig || !copy) {
1653 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1659 RegionFactory::add_compound_association (orig, copy);
1666 Session::load_nested_sources (const XMLNode& node)
1669 XMLNodeConstIterator niter;
1671 nlist = node.children();
1673 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1674 if ((*niter)->name() == "Source") {
1676 /* it may already exist, so don't recreate it unnecessarily
1679 XMLProperty* prop = (*niter)->property (X_("id"));
1681 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1685 ID source_id (prop->value());
1687 if (!source_by_id (source_id)) {
1690 SourceFactory::create (*this, **niter, true);
1692 catch (failed_constructor& err) {
1693 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1700 boost::shared_ptr<Region>
1701 Session::XMLRegionFactory (const XMLNode& node, bool full)
1703 const XMLProperty* type = node.property("type");
1707 const XMLNodeList& nlist = node.children();
1709 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1710 XMLNode *child = (*niter);
1711 if (child->name() == "NestedSource") {
1712 load_nested_sources (*child);
1716 if (!type || type->value() == "audio") {
1717 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1718 } else if (type->value() == "midi") {
1719 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1722 } catch (failed_constructor& err) {
1723 return boost::shared_ptr<Region> ();
1726 return boost::shared_ptr<Region> ();
1729 boost::shared_ptr<AudioRegion>
1730 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1732 const XMLProperty* prop;
1733 boost::shared_ptr<Source> source;
1734 boost::shared_ptr<AudioSource> as;
1736 SourceList master_sources;
1737 uint32_t nchans = 1;
1740 if (node.name() != X_("Region")) {
1741 return boost::shared_ptr<AudioRegion>();
1744 if ((prop = node.property (X_("channels"))) != 0) {
1745 nchans = atoi (prop->value().c_str());
1748 if ((prop = node.property ("name")) == 0) {
1749 cerr << "no name for this region\n";
1753 if ((prop = node.property (X_("source-0"))) == 0) {
1754 if ((prop = node.property ("source")) == 0) {
1755 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1756 return boost::shared_ptr<AudioRegion>();
1760 PBD::ID s_id (prop->value());
1762 if ((source = source_by_id (s_id)) == 0) {
1763 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1764 return boost::shared_ptr<AudioRegion>();
1767 as = boost::dynamic_pointer_cast<AudioSource>(source);
1769 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1770 return boost::shared_ptr<AudioRegion>();
1773 sources.push_back (as);
1775 /* pickup other channels */
1777 for (uint32_t n=1; n < nchans; ++n) {
1778 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1779 if ((prop = node.property (buf)) != 0) {
1781 PBD::ID id2 (prop->value());
1783 if ((source = source_by_id (id2)) == 0) {
1784 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1785 return boost::shared_ptr<AudioRegion>();
1788 as = boost::dynamic_pointer_cast<AudioSource>(source);
1790 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1791 return boost::shared_ptr<AudioRegion>();
1793 sources.push_back (as);
1797 for (uint32_t n = 0; n < nchans; ++n) {
1798 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1799 if ((prop = node.property (buf)) != 0) {
1801 PBD::ID id2 (prop->value());
1803 if ((source = source_by_id (id2)) == 0) {
1804 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1805 return boost::shared_ptr<AudioRegion>();
1808 as = boost::dynamic_pointer_cast<AudioSource>(source);
1810 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1811 return boost::shared_ptr<AudioRegion>();
1813 master_sources.push_back (as);
1818 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1820 /* a final detail: this is the one and only place that we know how long missing files are */
1822 if (region->whole_file()) {
1823 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1824 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1826 sfp->set_length (region->length());
1831 if (!master_sources.empty()) {
1832 if (master_sources.size() != nchans) {
1833 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1835 region->set_master_sources (master_sources);
1843 catch (failed_constructor& err) {
1844 return boost::shared_ptr<AudioRegion>();
1848 boost::shared_ptr<MidiRegion>
1849 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1851 const XMLProperty* prop;
1852 boost::shared_ptr<Source> source;
1853 boost::shared_ptr<MidiSource> ms;
1856 if (node.name() != X_("Region")) {
1857 return boost::shared_ptr<MidiRegion>();
1860 if ((prop = node.property ("name")) == 0) {
1861 cerr << "no name for this region\n";
1865 if ((prop = node.property (X_("source-0"))) == 0) {
1866 if ((prop = node.property ("source")) == 0) {
1867 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1868 return boost::shared_ptr<MidiRegion>();
1872 PBD::ID s_id (prop->value());
1874 if ((source = source_by_id (s_id)) == 0) {
1875 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1876 return boost::shared_ptr<MidiRegion>();
1879 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1881 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1882 return boost::shared_ptr<MidiRegion>();
1885 sources.push_back (ms);
1888 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1889 /* a final detail: this is the one and only place that we know how long missing files are */
1891 if (region->whole_file()) {
1892 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1893 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1895 sfp->set_length (region->length());
1903 catch (failed_constructor& err) {
1904 return boost::shared_ptr<MidiRegion>();
1909 Session::get_sources_as_xml ()
1912 XMLNode* node = new XMLNode (X_("Sources"));
1913 Glib::Mutex::Lock lm (source_lock);
1915 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1916 node->add_child_nocopy (i->second->get_state());
1923 Session::path_from_region_name (DataType type, string name, string identifier)
1925 char buf[PATH_MAX+1];
1927 SessionDirectory sdir(get_best_session_directory_for_new_source());
1928 sys::path source_dir = ((type == DataType::AUDIO)
1929 ? sdir.sound_path() : sdir.midi_path());
1931 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1933 for (n = 0; n < 999999; ++n) {
1934 if (identifier.length()) {
1935 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1936 identifier.c_str(), n, ext.c_str());
1938 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1942 sys::path source_path = source_dir / buf;
1944 if (!sys::exists (source_path)) {
1945 return source_path.to_string();
1949 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1958 Session::load_sources (const XMLNode& node)
1961 XMLNodeConstIterator niter;
1962 boost::shared_ptr<Source> source;
1964 nlist = node.children();
1968 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1971 if ((source = XMLSourceFactory (**niter)) == 0) {
1972 error << _("Session: cannot create Source from XML description.") << endmsg;
1975 } catch (MissingSource& err) {
1979 if (!no_questions_about_missing_files) {
1980 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1985 switch (user_choice) {
1987 /* user added a new search location, so try again */
1992 /* user asked to quit the entire session load
1997 no_questions_about_missing_files = true;
2001 no_questions_about_missing_files = true;
2006 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
2007 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2016 boost::shared_ptr<Source>
2017 Session::XMLSourceFactory (const XMLNode& node)
2019 if (node.name() != "Source") {
2020 return boost::shared_ptr<Source>();
2024 /* note: do peak building in another thread when loading session state */
2025 return SourceFactory::create (*this, node, true);
2028 catch (failed_constructor& err) {
2029 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2030 return boost::shared_ptr<Source>();
2035 Session::save_template (string template_name)
2039 if (_state_of_the_state & CannotSave) {
2043 sys::path user_template_dir(user_template_directory());
2047 sys::create_directories (user_template_dir);
2049 catch(sys::filesystem_error& ex)
2051 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2052 user_template_dir.to_string(), ex.what()) << endmsg;
2056 tree.set_root (&get_template());
2058 sys::path template_dir_path(user_template_dir);
2060 /* directory to put the template in */
2061 template_dir_path /= template_name;
2062 if (sys::exists (template_dir_path))
2064 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2065 template_dir_path.to_string()) << endmsg;
2069 sys::create_directories (template_dir_path);
2072 sys::path template_file_path = template_dir_path;
2073 template_file_path /= template_name + template_suffix;
2075 if (!tree.write (template_file_path.to_string())) {
2076 error << _("template not saved") << endmsg;
2080 /* copy plugin state directory */
2082 sys::path template_plugin_state_path = template_dir_path;
2083 template_plugin_state_path /= X_("plugins");
2084 sys::create_directories (template_plugin_state_path);
2085 sys::copy_files (plugins_dir(), template_plugin_state_path);
2091 Session::refresh_disk_space ()
2094 struct statfs statfsbuf;
2095 vector<space_and_path>::iterator i;
2096 Glib::Mutex::Lock lm (space_lock);
2099 /* get freespace on every FS that is part of the session path */
2101 _total_free_4k_blocks = 0;
2103 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2104 statfs ((*i).path.c_str(), &statfsbuf);
2106 scale = statfsbuf.f_bsize/4096.0;
2108 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2109 _total_free_4k_blocks += (*i).blocks;
2115 Session::get_best_session_directory_for_new_source ()
2117 vector<space_and_path>::iterator i;
2118 string result = _session_dir->root_path().to_string();
2120 /* handle common case without system calls */
2122 if (session_dirs.size() == 1) {
2126 /* OK, here's the algorithm we're following here:
2128 We want to select which directory to use for
2129 the next file source to be created. Ideally,
2130 we'd like to use a round-robin process so as to
2131 get maximum performance benefits from splitting
2132 the files across multiple disks.
2134 However, in situations without much diskspace, an
2135 RR approach may end up filling up a filesystem
2136 with new files while others still have space.
2137 Its therefore important to pay some attention to
2138 the freespace in the filesystem holding each
2139 directory as well. However, if we did that by
2140 itself, we'd keep creating new files in the file
2141 system with the most space until it was as full
2142 as all others, thus negating any performance
2143 benefits of this RAID-1 like approach.
2145 So, we use a user-configurable space threshold. If
2146 there are at least 2 filesystems with more than this
2147 much space available, we use RR selection between them.
2148 If not, then we pick the filesystem with the most space.
2150 This gets a good balance between the two
2154 refresh_disk_space ();
2156 int free_enough = 0;
2158 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2159 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2164 if (free_enough >= 2) {
2165 /* use RR selection process, ensuring that the one
2169 i = last_rr_session_dir;
2172 if (++i == session_dirs.end()) {
2173 i = session_dirs.begin();
2176 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2177 if (create_session_directory ((*i).path)) {
2179 last_rr_session_dir = i;
2184 } while (i != last_rr_session_dir);
2188 /* pick FS with the most freespace (and that
2189 seems to actually work ...)
2192 vector<space_and_path> sorted;
2193 space_and_path_ascending_cmp cmp;
2195 sorted = session_dirs;
2196 sort (sorted.begin(), sorted.end(), cmp);
2198 for (i = sorted.begin(); i != sorted.end(); ++i) {
2199 if (create_session_directory ((*i).path)) {
2201 last_rr_session_dir = i;
2211 Session::load_named_selections (const XMLNode& node)
2214 XMLNodeConstIterator niter;
2217 nlist = node.children();
2221 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2223 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2224 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2232 Session::XMLNamedSelectionFactory (const XMLNode& node)
2235 return new NamedSelection (*this, node);
2238 catch (failed_constructor& err) {
2244 Session::automation_dir () const
2246 return Glib::build_filename (_path, "automation");
2250 Session::analysis_dir () const
2252 return Glib::build_filename (_path, "analysis");
2256 Session::plugins_dir () const
2258 return Glib::build_filename (_path, "plugins");
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 state 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, false, 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().to_string();
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().to_string();
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::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::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::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 sys::path xml_path = _session_dir->root_path() / history_filename;
3231 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3233 if (sys::exists (xml_path)) {
3236 sys::rename (xml_path, backup_path);
3238 catch (const sys::filesystem_error& err)
3240 error << _("could not backup old history file, current history not saved") << endmsg;
3245 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3249 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3251 if (!tree.write (xml_path.to_string()))
3253 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3257 sys::remove (xml_path);
3258 sys::rename (backup_path, xml_path);
3260 catch (const sys::filesystem_error& err)
3262 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3263 backup_path.to_string(), err.what()) << endmsg;
3273 Session::restore_history (string snapshot_name)
3277 if (snapshot_name.empty()) {
3278 snapshot_name = _current_snapshot_name;
3281 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3282 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3284 info << "Loading history from " << xml_path.to_string() << endmsg;
3286 if (!sys::exists (xml_path)) {
3287 info << string_compose (_("%1: no history file \"%2\" for this session."),
3288 _name, xml_path.to_string()) << endmsg;
3292 if (!tree.read (xml_path.to_string())) {
3293 error << string_compose (_("Could not understand session history file \"%1\""),
3294 xml_path.to_string()) << endmsg;
3301 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3304 UndoTransaction* ut = new UndoTransaction ();
3307 ut->set_name(t->property("name")->value());
3308 stringstream ss(t->property("tv-sec")->value());
3310 ss.str(t->property("tv-usec")->value());
3312 ut->set_timestamp(tv);
3314 for (XMLNodeConstIterator child_it = t->children().begin();
3315 child_it != t->children().end(); child_it++)
3317 XMLNode *n = *child_it;
3320 if (n->name() == "MementoCommand" ||
3321 n->name() == "MementoUndoCommand" ||
3322 n->name() == "MementoRedoCommand") {
3324 if ((c = memento_command_factory(n))) {
3328 } else if (n->name() == "NoteDiffCommand") {
3329 PBD::ID id (n->property("midi-source")->value());
3330 boost::shared_ptr<MidiSource> midi_source =
3331 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3333 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3335 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3338 } else if (n->name() == "SysExDiffCommand") {
3340 PBD::ID id (n->property("midi-source")->value());
3341 boost::shared_ptr<MidiSource> midi_source =
3342 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3344 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3346 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3349 } else if (n->name() == "PatchChangeDiffCommand") {
3351 PBD::ID id (n->property("midi-source")->value());
3352 boost::shared_ptr<MidiSource> midi_source =
3353 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3355 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3357 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3360 } else if (n->name() == "StatefulDiffCommand") {
3361 if ((c = stateful_diff_command_factory (n))) {
3362 ut->add_command (c);
3365 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3376 Session::config_changed (std::string p, bool ours)
3382 if (p == "seamless-loop") {
3384 } else if (p == "rf-speed") {
3386 } else if (p == "auto-loop") {
3388 } else if (p == "auto-input") {
3390 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3391 /* auto-input only makes a difference if we're rolling */
3392 set_track_monitor_input_status (!config.get_auto_input());
3395 } else if (p == "punch-in") {
3399 if ((location = _locations->auto_punch_location()) != 0) {
3401 if (config.get_punch_in ()) {
3402 replace_event (SessionEvent::PunchIn, location->start());
3404 remove_event (location->start(), SessionEvent::PunchIn);
3408 } else if (p == "punch-out") {
3412 if ((location = _locations->auto_punch_location()) != 0) {
3414 if (config.get_punch_out()) {
3415 replace_event (SessionEvent::PunchOut, location->end());
3417 clear_events (SessionEvent::PunchOut);
3421 } else if (p == "edit-mode") {
3423 Glib::Mutex::Lock lm (playlists->lock);
3425 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3426 (*i)->set_edit_mode (Config->get_edit_mode ());
3429 } else if (p == "use-video-sync") {
3431 waiting_for_sync_offset = config.get_use_video_sync();
3433 } else if (p == "mmc-control") {
3435 //poke_midi_thread ();
3437 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3439 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3441 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3443 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3445 } else if (p == "midi-control") {
3447 //poke_midi_thread ();
3449 } else if (p == "raid-path") {
3451 setup_raid_path (config.get_raid_path());
3453 } else if (p == "timecode-format") {
3457 } else if (p == "video-pullup") {
3461 } else if (p == "seamless-loop") {
3463 if (play_loop && transport_rolling()) {
3464 // to reset diskstreams etc
3465 request_play_loop (true);
3468 } else if (p == "rf-speed") {
3470 cumulative_rf_motion = 0;
3473 } else if (p == "click-sound") {
3475 setup_click_sounds (1);
3477 } else if (p == "click-emphasis-sound") {
3479 setup_click_sounds (-1);
3481 } else if (p == "clicking") {
3483 if (Config->get_clicking()) {
3484 if (_click_io && click_data) { // don't require emphasis data
3491 } else if (p == "click-gain") {
3494 _click_gain->set_gain (Config->get_click_gain(), this);
3497 } else if (p == "send-mtc") {
3499 if (Config->get_send_mtc ()) {
3500 /* mark us ready to send */
3501 next_quarter_frame_to_send = 0;
3504 } else if (p == "send-mmc") {
3506 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3508 } else if (p == "midi-feedback") {
3510 session_midi_feedback = Config->get_midi_feedback();
3512 } else if (p == "jack-time-master") {
3514 engine().reset_timebase ();
3516 } else if (p == "native-file-header-format") {
3518 if (!first_file_header_format_reset) {
3519 reset_native_file_format ();
3522 first_file_header_format_reset = false;
3524 } else if (p == "native-file-data-format") {
3526 if (!first_file_data_format_reset) {
3527 reset_native_file_format ();
3530 first_file_data_format_reset = false;
3532 } else if (p == "external-sync") {
3533 if (!config.get_external_sync()) {
3534 drop_sync_source ();
3536 switch_to_sync_source (config.get_sync_source());
3538 } else if (p == "remote-model") {
3539 set_remote_control_ids ();
3540 } else if (p == "denormal-model") {
3542 } else if (p == "history-depth") {
3543 set_history_depth (Config->get_history_depth());
3544 } else if (p == "sync-all-route-ordering") {
3545 sync_order_keys ("session");
3546 } else if (p == "initial-program-change") {
3548 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3551 buf[0] = MIDI::program; // channel zero by default
3552 buf[1] = (Config->get_initial_program_change() & 0x7f);
3554 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3556 } else if (p == "solo-mute-override") {
3557 // catch_up_on_solo_mute_override ();
3558 } else if (p == "listen-position" || p == "pfl-position") {
3559 listen_position_changed ();
3560 } else if (p == "solo-control-is-listen-control") {
3561 solo_control_mode_changed ();
3562 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3563 last_timecode_valid = false;
3564 } else if (p == "playback-buffer-seconds") {
3565 AudioSource::allocate_working_buffers (frame_rate());
3572 Session::set_history_depth (uint32_t d)
3574 _history.set_depth (d);
3578 Session::load_diskstreams_2X (XMLNode const & node, int)
3581 XMLNodeConstIterator citer;
3583 clist = node.children();
3585 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3588 /* diskstreams added automatically by DiskstreamCreated handler */
3589 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3590 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3591 _diskstreams_2X.push_back (dsp);
3593 error << _("Session: unknown diskstream type in XML") << endmsg;
3597 catch (failed_constructor& err) {
3598 error << _("Session: could not load diskstream via XML state") << endmsg;
3606 /** Connect things to the MMC object */
3608 Session::setup_midi_machine_control ()
3610 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3612 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3613 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3614 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3615 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3616 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3617 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3618 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3619 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3620 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3621 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3622 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3623 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3624 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3626 /* also handle MIDI SPP because its so common */
3628 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3629 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3630 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));
3633 boost::shared_ptr<Controllable>
3634 Session::solo_cut_control() const
3636 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3637 controls in Ardour that currently get presented to the user in the GUI that require
3638 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3640 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3641 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3645 return _solo_cut_control;
3649 Session::rename (const std::string& new_name)
3651 string legal_name = legalize_for_path (new_name);
3657 string const old_sources_root = _session_dir->sources_root().to_string ();
3659 #define RENAME ::rename
3664 * interchange subdirectory
3668 * Backup files are left unchanged and not renamed.
3671 /* pass one: not 100% safe check that the new directory names don't
3675 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3680 /* this is a stupid hack because Glib::path_get_dirname() is
3681 * lexical-only, and so passing it /a/b/c/ gives a different
3682 * result than passing it /a/b/c ...
3685 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3686 oldstr = oldstr.substr (0, oldstr.length() - 1);
3689 string base = Glib::path_get_dirname (oldstr);
3690 string p = Glib::path_get_basename (oldstr);
3692 newstr = Glib::build_filename (base, legal_name);
3694 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3701 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3706 /* this is a stupid hack because Glib::path_get_dirname() is
3707 * lexical-only, and so passing it /a/b/c/ gives a different
3708 * result than passing it /a/b/c ...
3711 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3712 oldstr = oldstr.substr (0, oldstr.length() - 1);
3715 string base = Glib::path_get_dirname (oldstr);
3716 string p = Glib::path_get_basename (oldstr);
3718 newstr = Glib::build_filename (base, legal_name);
3720 cerr << "Rename " << oldstr << " => " << newstr << endl;
3722 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3727 (*_session_dir) = newstr;
3732 /* directory below interchange */
3734 v.push_back (newstr);
3735 v.push_back (interchange_dir_name);
3738 oldstr = Glib::build_filename (v);
3741 v.push_back (newstr);
3742 v.push_back (interchange_dir_name);
3743 v.push_back (legal_name);
3745 newstr = Glib::build_filename (v);
3747 cerr << "Rename " << oldstr << " => " << newstr << endl;
3749 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3756 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3757 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3759 cerr << "Rename " << oldstr << " => " << newstr << endl;
3761 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3768 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3770 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3771 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3773 cerr << "Rename " << oldstr << " => " << newstr << endl;
3775 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3780 /* update file source paths */
3782 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3783 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3785 string p = fs->path ();
3786 boost::replace_all (p, old_sources_root, _session_dir->sources_root().to_string ());
3791 /* remove old name from recent sessions */
3793 remove_recent_sessions (_path);
3796 _current_snapshot_name = new_name;
3801 /* save state again to get everything just right */
3803 save_state (_current_snapshot_name);
3806 /* add to recent sessions */
3808 store_recent_sessions (new_name, _path);