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 AudioDiskstream::allocate_working_buffers();
230 /* default short fade = 15ms */
232 Crossfade::set_short_xfade_length ((framecnt_t) floor (config.get_short_xfade_seconds() * frame_rate()));
233 SndFileSource::setup_standard_crossfades (*this, frame_rate());
235 last_mmc_step.tv_sec = 0;
236 last_mmc_step.tv_usec = 0;
239 /* click sounds are unset by default, which causes us to internal
240 waveforms for clicks.
244 click_emphasis_length = 0;
247 process_function = &Session::process_with_events;
249 if (config.get_use_video_sync()) {
250 waiting_for_sync_offset = true;
252 waiting_for_sync_offset = false;
255 last_timecode_when = 0;
256 last_timecode_valid = false;
260 last_rr_session_dir = session_dirs.begin();
261 refresh_disk_space ();
263 /* default: assume simple stereo speaker configuration */
265 _speakers->setup_default_speakers (2);
269 average_slave_delta = 1800; // !!! why 1800 ????
270 have_first_delta_accumulator = false;
271 delta_accumulator_cnt = 0;
272 _slave_state = Stopped;
274 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
275 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
276 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
277 add_controllable (_solo_cut_control);
279 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
281 /* These are all static "per-class" signals */
283 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
284 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
285 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
286 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
287 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
289 /* stop IO objects from doing stuff until we're ready for them */
291 Delivery::disable_panners ();
292 IO::disable_connecting ();
296 Session::second_stage_init ()
298 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
301 if (load_state (_current_snapshot_name)) {
306 if (_butler->start_thread()) {
310 if (start_midi_thread ()) {
314 setup_midi_machine_control ();
316 // set_state() will call setup_raid_path(), but if it's a new session we need
317 // to call setup_raid_path() here.
320 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
324 setup_raid_path(_path);
327 /* we can't save till after ::when_engine_running() is called,
328 because otherwise we save state with no connections made.
329 therefore, we reset _state_of_the_state because ::set_state()
330 will have cleared it.
332 we also have to include Loading so that any events that get
333 generated between here and the end of ::when_engine_running()
334 will be processed directly rather than queued.
337 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
339 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
340 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
341 setup_click_sounds (0);
342 setup_midi_control ();
344 /* Pay attention ... */
346 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
347 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
350 when_engine_running ();
353 /* handle this one in a different way than all others, so that its clear what happened */
355 catch (AudioEngine::PortRegistrationFailure& err) {
356 error << err.what() << endmsg;
364 BootMessage (_("Reset Remote Controls"));
366 send_full_time_code (0);
367 _engine.transport_locate (0);
369 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
370 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
372 MidiClockTicker::instance().set_session (this);
373 MIDI::Name::MidiPatchManager::instance().set_session (this);
375 /* initial program change will be delivered later; see ::config_changed() */
377 _state_of_the_state = Clean;
379 Port::set_connecting_blocked (false);
381 DirtyChanged (); /* EMIT SIGNAL */
383 if (state_was_pending) {
384 save_state (_current_snapshot_name);
385 remove_pending_capture_state ();
386 state_was_pending = false;
389 BootMessage (_("Session loading complete"));
395 Session::raid_path () const
397 SearchPath raid_search_path;
399 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
400 raid_search_path += sys::path((*i).path);
403 return raid_search_path.to_string ();
407 Session::setup_raid_path (string path)
416 session_dirs.clear ();
418 SearchPath search_path(path);
419 SearchPath sound_search_path;
420 SearchPath midi_search_path;
422 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
423 sp.path = (*i).to_string ();
424 sp.blocks = 0; // not needed
425 session_dirs.push_back (sp);
427 SessionDirectory sdir(sp.path);
429 sound_search_path += sdir.sound_path ();
430 midi_search_path += sdir.midi_path ();
433 // reset the round-robin soundfile path thingie
434 last_rr_session_dir = session_dirs.begin();
438 Session::path_is_within_session (const std::string& path)
440 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
441 if (path.find ((*i).path) == 0) {
449 Session::ensure_subdirs ()
453 dir = session_directory().peak_path().to_string();
455 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
456 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
460 dir = session_directory().sound_path().to_string();
462 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
463 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
467 dir = session_directory().midi_path().to_string();
469 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
470 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
474 dir = session_directory().dead_path().to_string();
476 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
477 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
481 dir = session_directory().export_path().to_string();
483 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
484 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
488 dir = analysis_dir ();
490 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
491 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
495 dir = plugins_dir ();
497 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
498 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
505 /** @param session_template directory containing session template, or empty.
506 * Caller must not hold process lock.
509 Session::create (const string& session_template, BusProfile* bus_profile)
511 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
512 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
516 if (ensure_subdirs ()) {
520 _writable = exists_and_writable (sys::path (_path));
522 if (!session_template.empty()) {
523 std::string in_path = session_template_dir_to_file (session_template);
525 ifstream in(in_path.c_str());
528 string out_path = _path;
530 out_path += statefile_suffix;
532 ofstream out(out_path.c_str());
538 /* Copy plugin state files from template to new session */
539 sys::path template_plugins = session_template;
540 template_plugins /= X_("plugins");
541 sys::copy_files (template_plugins, plugins_dir ());
546 error << string_compose (_("Could not open %1 for writing session template"), out_path)
552 error << string_compose (_("Could not open session template %1 for reading"), in_path)
559 /* Instantiate metadata */
561 _metadata = new SessionMetadata ();
563 /* set initial start + end point */
565 _state_of_the_state = Clean;
567 /* set up Master Out and Control Out if necessary */
573 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
575 if (bus_profile->master_out_channels) {
576 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
580 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
581 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
584 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
585 r->input()->ensure_io (count, false, this);
586 r->output()->ensure_io (count, false, this);
588 r->set_remote_control_id (control_id++);
592 if (Config->get_use_monitor_bus()) {
593 boost::shared_ptr<Route> r (new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO));
597 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
598 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
601 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
602 r->input()->ensure_io (count, false, this);
603 r->output()->ensure_io (count, false, this);
605 r->set_remote_control_id (control_id);
611 /* prohibit auto-connect to master, because there isn't one */
612 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
616 add_routes (rl, false, false);
619 /* this allows the user to override settings with an environment variable.
622 if (no_auto_connect()) {
623 bus_profile->input_ac = AutoConnectOption (0);
624 bus_profile->output_ac = AutoConnectOption (0);
627 Config->set_input_auto_connect (bus_profile->input_ac);
628 Config->set_output_auto_connect (bus_profile->output_ac);
637 Session::maybe_write_autosave()
639 if (dirty() && record_status() != Recording) {
640 save_state("", true);
645 Session::remove_pending_capture_state ()
647 sys::path pending_state_file_path(_session_dir->root_path());
649 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
653 sys::remove (pending_state_file_path);
655 catch(sys::filesystem_error& ex)
657 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
658 pending_state_file_path.to_string(), ex.what()) << endmsg;
662 /** Rename a state file.
663 * @param old_name Old snapshot name.
664 * @param new_name New snapshot name.
667 Session::rename_state (string old_name, string new_name)
669 if (old_name == _current_snapshot_name || old_name == _name) {
670 /* refuse to rename the current snapshot or the "main" one */
674 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
675 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
677 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
678 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
682 sys::rename (old_xml_path, new_xml_path);
684 catch (const sys::filesystem_error& err)
686 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
687 old_name, new_name, err.what()) << endmsg;
691 /** Remove a state file.
692 * @param snapshot_name Snapshot name.
695 Session::remove_state (string snapshot_name)
697 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
698 // refuse to remove the current snapshot or the "main" one
702 sys::path xml_path(_session_dir->root_path());
704 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
706 if (!create_backup_file (xml_path)) {
707 // don't remove it if a backup can't be made
708 // create_backup_file will log the error.
713 sys::remove (xml_path);
716 #ifdef HAVE_JACK_SESSION
718 Session::jack_session_event (jack_session_event_t * event)
722 struct tm local_time;
725 localtime_r (&n, &local_time);
726 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
728 if (event->type == JackSessionSaveTemplate)
730 if (save_template( timebuf )) {
731 event->flags = JackSessionSaveError;
733 string cmd ("ardour3 -P -U ");
734 cmd += event->client_uuid;
738 event->command_line = strdup (cmd.c_str());
743 if (save_state (timebuf)) {
744 event->flags = JackSessionSaveError;
746 sys::path xml_path (_session_dir->root_path());
747 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
749 string cmd ("ardour3 -P -U ");
750 cmd += event->client_uuid;
752 cmd += xml_path.to_string();
755 event->command_line = strdup (cmd.c_str());
759 jack_session_reply (_engine.jack(), event);
761 if (event->type == JackSessionSaveAndQuit) {
762 Quit (); /* EMIT SIGNAL */
765 jack_session_event_free( event );
769 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
771 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
774 sys::path xml_path(_session_dir->root_path());
776 if (!_writable || (_state_of_the_state & CannotSave)) {
780 if (!_engine.connected ()) {
781 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
787 /* tell sources we're saving first, in case they write out to a new file
788 * which should be saved with the state rather than the old one */
789 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
790 i->second->session_saved();
793 tree.set_root (&get_state());
795 if (snapshot_name.empty()) {
796 snapshot_name = _current_snapshot_name;
797 } else if (switch_to_snapshot) {
798 _current_snapshot_name = snapshot_name;
803 /* proper save: use statefile_suffix (.ardour in English) */
805 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
807 /* make a backup copy of the old file */
809 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
810 // create_backup_file will log the error
816 /* pending save: use pending_suffix (.pending in English) */
817 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
820 sys::path tmp_path(_session_dir->root_path());
822 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
824 // cerr << "actually writing state to " << xml_path.to_string() << endl;
826 if (!tree.write (tmp_path.to_string())) {
827 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
828 sys::remove (tmp_path);
833 if (::rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
834 error << string_compose (_("could not rename temporary session file %1 to %2"),
835 tmp_path.to_string(), xml_path.to_string()) << endmsg;
836 sys::remove (tmp_path);
843 save_history (snapshot_name);
845 bool was_dirty = dirty();
847 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
850 DirtyChanged (); /* EMIT SIGNAL */
853 StateSaved (snapshot_name); /* EMIT SIGNAL */
860 Session::restore_state (string snapshot_name)
862 if (load_state (snapshot_name) == 0) {
863 set_state (*state_tree->root(), Stateful::loading_state_version);
870 Session::load_state (string snapshot_name)
875 state_was_pending = false;
877 /* check for leftover pending state from a crashed capture attempt */
879 sys::path xmlpath(_session_dir->root_path());
880 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
882 if (sys::exists (xmlpath)) {
884 /* there is pending state from a crashed capture attempt */
886 boost::optional<int> r = AskAboutPendingState();
887 if (r.get_value_or (1)) {
888 state_was_pending = true;
892 if (!state_was_pending) {
893 xmlpath = _session_dir->root_path();
894 xmlpath /= snapshot_name;
897 if (!sys::exists (xmlpath)) {
898 xmlpath = _session_dir->root_path();
899 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
900 if (!sys::exists (xmlpath)) {
901 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
906 state_tree = new XMLTree;
910 _writable = exists_and_writable (xmlpath);
912 if (!state_tree->read (xmlpath.to_string())) {
913 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
919 XMLNode& root (*state_tree->root());
921 if (root.name() != X_("Session")) {
922 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
928 const XMLProperty* prop;
930 if ((prop = root.property ("version")) == 0) {
931 /* no version implies very old version of Ardour */
932 Stateful::loading_state_version = 1000;
938 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
939 Stateful::loading_state_version = (major * 1000) + minor;
942 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
944 sys::path backup_path(_session_dir->root_path());
946 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
948 // only create a backup once
949 if (sys::exists (backup_path)) {
953 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
954 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
959 sys::copy_file (xmlpath, backup_path);
961 catch(sys::filesystem_error& ex)
963 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
964 xmlpath.to_string(), ex.what())
974 Session::load_options (const XMLNode& node)
976 LocaleGuard lg (X_("POSIX"));
977 config.set_variables (node);
988 Session::get_template()
990 /* if we don't disable rec-enable, diskstreams
991 will believe they need to store their capture
992 sources in their state node.
995 disable_record (false);
1001 Session::state(bool full_state)
1003 XMLNode* node = new XMLNode("Session");
1006 // store libardour version, just in case
1008 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
1009 node->add_property("version", string(buf));
1011 /* store configuration settings */
1015 node->add_property ("name", _name);
1016 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1017 node->add_property ("sample-rate", buf);
1019 if (session_dirs.size() > 1) {
1023 vector<space_and_path>::iterator i = session_dirs.begin();
1024 vector<space_and_path>::iterator next;
1026 ++i; /* skip the first one */
1030 while (i != session_dirs.end()) {
1034 if (next != session_dirs.end()) {
1044 child = node->add_child ("Path");
1045 child->add_content (p);
1049 /* save the ID counter */
1051 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1052 node->add_property ("id-counter", buf);
1054 /* save the event ID counter */
1056 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1057 node->add_property ("event-counter", buf);
1059 /* various options */
1061 node->add_child_nocopy (config.get_variables ());
1063 node->add_child_nocopy (_metadata->get_state());
1065 child = node->add_child ("Sources");
1068 Glib::Mutex::Lock sl (source_lock);
1070 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1072 /* Don't save information about non-file Sources, or
1073 * about non-destructive file sources that are empty
1074 * and unused by any regions.
1077 boost::shared_ptr<FileSource> fs;
1079 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1081 if (!fs->destructive()) {
1082 if (fs->empty() && !fs->used()) {
1087 child->add_child_nocopy (siter->second->get_state());
1092 child = node->add_child ("Regions");
1095 Glib::Mutex::Lock rl (region_lock);
1096 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1097 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1098 boost::shared_ptr<Region> r = i->second;
1099 /* only store regions not attached to playlists */
1100 if (r->playlist() == 0) {
1101 child->add_child_nocopy (r->state ());
1105 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1107 if (!cassocs.empty()) {
1108 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1110 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1112 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1113 i->first->id().print (buf, sizeof (buf));
1114 can->add_property (X_("copy"), buf);
1115 i->second->id().print (buf, sizeof (buf));
1116 can->add_property (X_("original"), buf);
1117 ca->add_child_nocopy (*can);
1123 node->add_child_nocopy (_locations->get_state());
1125 // for a template, just create a new Locations, populate it
1126 // with the default start and end, and get the state for that.
1127 Locations loc (*this);
1128 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1129 range->set (max_framepos, 0);
1131 node->add_child_nocopy (loc.get_state());
1134 child = node->add_child ("Bundles");
1136 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1137 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1138 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1140 child->add_child_nocopy (b->get_state());
1145 child = node->add_child ("Routes");
1147 boost::shared_ptr<RouteList> r = routes.reader ();
1149 RoutePublicOrderSorter cmp;
1150 RouteList public_order (*r);
1151 public_order.sort (cmp);
1153 /* the sort should have put control outs first */
1156 assert (_monitor_out == public_order.front());
1159 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1160 if (!(*i)->is_hidden()) {
1162 child->add_child_nocopy ((*i)->get_state());
1164 child->add_child_nocopy ((*i)->get_template());
1170 playlists->add_state (node, full_state);
1172 child = node->add_child ("RouteGroups");
1173 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1174 child->add_child_nocopy ((*i)->get_state());
1178 child = node->add_child ("Click");
1179 child->add_child_nocopy (_click_io->state (full_state));
1183 child = node->add_child ("NamedSelections");
1184 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1186 child->add_child_nocopy ((*i)->get_state());
1191 node->add_child_nocopy (_speakers->get_state());
1192 node->add_child_nocopy (_tempo_map->get_state());
1193 node->add_child_nocopy (get_control_protocol_state());
1196 node->add_child_copy (*_extra_xml);
1203 Session::get_control_protocol_state ()
1205 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1206 return cpm.get_state();
1210 Session::set_state (const XMLNode& node, int version)
1214 const XMLProperty* prop;
1217 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1219 if (node.name() != X_("Session")) {
1220 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1224 if ((prop = node.property ("version")) != 0) {
1225 version = atoi (prop->value ()) * 1000;
1228 if ((prop = node.property ("name")) != 0) {
1229 _name = prop->value ();
1232 if ((prop = node.property (X_("sample-rate"))) != 0) {
1234 _nominal_frame_rate = atoi (prop->value());
1236 if (_nominal_frame_rate != _current_frame_rate) {
1237 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1238 if (r.get_value_or (0)) {
1244 setup_raid_path(_session_dir->root_path().to_string());
1246 if ((prop = node.property (X_("id-counter"))) != 0) {
1248 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1249 ID::init_counter (x);
1251 /* old sessions used a timebased counter, so fake
1252 the startup ID counter based on a standard
1257 ID::init_counter (now);
1260 if ((prop = node.property (X_("event-counter"))) != 0) {
1261 Evoral::init_event_id_counter (atoi (prop->value()));
1264 IO::disable_connecting ();
1266 Stateful::save_extra_xml (node);
1268 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1269 load_options (*child);
1270 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1271 load_options (*child);
1273 error << _("Session: XML state has no options section") << endmsg;
1276 if (version >= 3000) {
1277 if ((child = find_named_node (node, "Metadata")) == 0) {
1278 warning << _("Session: XML state has no metadata section") << endmsg;
1279 } else if (_metadata->set_state (*child, version)) {
1284 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1285 _speakers->set_state (*child, version);
1288 if ((child = find_named_node (node, "Sources")) == 0) {
1289 error << _("Session: XML state has no sources section") << endmsg;
1291 } else if (load_sources (*child)) {
1295 if ((child = find_named_node (node, "TempoMap")) == 0) {
1296 error << _("Session: XML state has no Tempo Map section") << endmsg;
1298 } else if (_tempo_map->set_state (*child, version)) {
1302 if ((child = find_named_node (node, "Locations")) == 0) {
1303 error << _("Session: XML state has no locations section") << endmsg;
1305 } else if (_locations->set_state (*child, version)) {
1311 if ((location = _locations->auto_loop_location()) != 0) {
1312 set_auto_loop_location (location);
1315 if ((location = _locations->auto_punch_location()) != 0) {
1316 set_auto_punch_location (location);
1319 if ((location = _locations->session_range_location()) != 0) {
1320 delete _session_range_location;
1321 _session_range_location = location;
1324 if (_session_range_location) {
1325 AudioFileSource::set_header_position_offset (_session_range_location->start());
1328 if ((child = find_named_node (node, "Regions")) == 0) {
1329 error << _("Session: XML state has no Regions section") << endmsg;
1331 } else if (load_regions (*child)) {
1335 if ((child = find_named_node (node, "Playlists")) == 0) {
1336 error << _("Session: XML state has no playlists section") << endmsg;
1338 } else if (playlists->load (*this, *child)) {
1342 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1344 } else if (playlists->load_unused (*this, *child)) {
1348 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1349 if (load_compounds (*child)) {
1354 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1355 if (load_named_selections (*child)) {
1360 if (version >= 3000) {
1361 if ((child = find_named_node (node, "Bundles")) == 0) {
1362 warning << _("Session: XML state has no bundles section") << endmsg;
1365 /* We can't load Bundles yet as they need to be able
1366 to convert from port names to Port objects, which can't happen until
1368 _bundle_xml_node = new XMLNode (*child);
1372 if (version < 3000) {
1373 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1374 error << _("Session: XML state has no diskstreams section") << endmsg;
1376 } else if (load_diskstreams_2X (*child, version)) {
1381 if ((child = find_named_node (node, "Routes")) == 0) {
1382 error << _("Session: XML state has no routes section") << endmsg;
1384 } else if (load_routes (*child, version)) {
1388 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1389 _diskstreams_2X.clear ();
1391 if (version >= 3000) {
1393 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1394 error << _("Session: XML state has no route groups section") << endmsg;
1396 } else if (load_route_groups (*child, version)) {
1400 } else if (version < 3000) {
1402 if ((child = find_named_node (node, "EditGroups")) == 0) {
1403 error << _("Session: XML state has no edit groups section") << endmsg;
1405 } else if (load_route_groups (*child, version)) {
1409 if ((child = find_named_node (node, "MixGroups")) == 0) {
1410 error << _("Session: XML state has no mix groups section") << endmsg;
1412 } else if (load_route_groups (*child, version)) {
1417 if ((child = find_named_node (node, "Click")) == 0) {
1418 warning << _("Session: XML state has no click section") << endmsg;
1419 } else if (_click_io) {
1420 _click_io->set_state (*child, version);
1423 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1424 ControlProtocolManager::instance().set_protocol_states (*child);
1427 /* here beginneth the second phase ... */
1429 StateReady (); /* EMIT SIGNAL */
1438 Session::load_routes (const XMLNode& node, int version)
1441 XMLNodeConstIterator niter;
1442 RouteList new_routes;
1444 nlist = node.children();
1448 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1450 boost::shared_ptr<Route> route;
1451 if (version < 3000) {
1452 route = XMLRouteFactory_2X (**niter, version);
1454 route = XMLRouteFactory (**niter, version);
1458 error << _("Session: cannot create Route from XML description.") << endmsg;
1462 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1464 new_routes.push_back (route);
1467 add_routes (new_routes, false, false);
1472 boost::shared_ptr<Route>
1473 Session::XMLRouteFactory (const XMLNode& node, int version)
1475 boost::shared_ptr<Route> ret;
1477 if (node.name() != "Route") {
1481 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1483 DataType type = DataType::AUDIO;
1484 const XMLProperty* prop = node.property("default-type");
1487 type = DataType (prop->value());
1490 assert (type != DataType::NIL);
1494 boost::shared_ptr<Track> track;
1496 if (type == DataType::AUDIO) {
1497 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1499 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1502 if (track->init()) {
1506 if (track->set_state (node, version)) {
1510 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1511 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1516 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1518 if (r->init () == 0 && r->set_state (node, version) == 0) {
1519 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1520 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1529 boost::shared_ptr<Route>
1530 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1532 boost::shared_ptr<Route> ret;
1534 if (node.name() != "Route") {
1538 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1540 ds_prop = node.property (X_("diskstream"));
1543 DataType type = DataType::AUDIO;
1544 const XMLProperty* prop = node.property("default-type");
1547 type = DataType (prop->value());
1550 assert (type != DataType::NIL);
1554 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1555 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1559 if (i == _diskstreams_2X.end()) {
1560 error << _("Could not find diskstream for route") << endmsg;
1561 return boost::shared_ptr<Route> ();
1564 boost::shared_ptr<Track> track;
1566 if (type == DataType::AUDIO) {
1567 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1569 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1572 if (track->init()) {
1576 if (track->set_state (node, version)) {
1580 track->set_diskstream (*i);
1582 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1583 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1588 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1590 if (r->init () == 0 && r->set_state (node, version) == 0) {
1591 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1592 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1602 Session::load_regions (const XMLNode& node)
1605 XMLNodeConstIterator niter;
1606 boost::shared_ptr<Region> region;
1608 nlist = node.children();
1612 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1613 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1614 error << _("Session: cannot create Region from XML description.");
1615 const XMLProperty *name = (**niter).property("name");
1618 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1629 Session::load_compounds (const XMLNode& node)
1631 XMLNodeList calist = node.children();
1632 XMLNodeConstIterator caiter;
1633 XMLProperty *caprop;
1635 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1636 XMLNode* ca = *caiter;
1640 if ((caprop = ca->property (X_("original"))) == 0) {
1643 orig_id = caprop->value();
1645 if ((caprop = ca->property (X_("copy"))) == 0) {
1648 copy_id = caprop->value();
1650 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1651 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1653 if (!orig || !copy) {
1654 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1660 RegionFactory::add_compound_association (orig, copy);
1667 Session::load_nested_sources (const XMLNode& node)
1670 XMLNodeConstIterator niter;
1672 nlist = node.children();
1674 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1675 if ((*niter)->name() == "Source") {
1677 /* it may already exist, so don't recreate it unnecessarily
1680 XMLProperty* prop = (*niter)->property (X_("id"));
1682 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1686 ID source_id (prop->value());
1688 if (!source_by_id (source_id)) {
1691 SourceFactory::create (*this, **niter, true);
1693 catch (failed_constructor& err) {
1694 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1701 boost::shared_ptr<Region>
1702 Session::XMLRegionFactory (const XMLNode& node, bool full)
1704 const XMLProperty* type = node.property("type");
1708 const XMLNodeList& nlist = node.children();
1710 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1711 XMLNode *child = (*niter);
1712 if (child->name() == "NestedSource") {
1713 load_nested_sources (*child);
1717 if (!type || type->value() == "audio") {
1718 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1719 } else if (type->value() == "midi") {
1720 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1723 } catch (failed_constructor& err) {
1724 return boost::shared_ptr<Region> ();
1727 return boost::shared_ptr<Region> ();
1730 boost::shared_ptr<AudioRegion>
1731 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1733 const XMLProperty* prop;
1734 boost::shared_ptr<Source> source;
1735 boost::shared_ptr<AudioSource> as;
1737 SourceList master_sources;
1738 uint32_t nchans = 1;
1741 if (node.name() != X_("Region")) {
1742 return boost::shared_ptr<AudioRegion>();
1745 if ((prop = node.property (X_("channels"))) != 0) {
1746 nchans = atoi (prop->value().c_str());
1749 if ((prop = node.property ("name")) == 0) {
1750 cerr << "no name for this region\n";
1754 if ((prop = node.property (X_("source-0"))) == 0) {
1755 if ((prop = node.property ("source")) == 0) {
1756 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1757 return boost::shared_ptr<AudioRegion>();
1761 PBD::ID s_id (prop->value());
1763 if ((source = source_by_id (s_id)) == 0) {
1764 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1765 return boost::shared_ptr<AudioRegion>();
1768 as = boost::dynamic_pointer_cast<AudioSource>(source);
1770 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1771 return boost::shared_ptr<AudioRegion>();
1774 sources.push_back (as);
1776 /* pickup other channels */
1778 for (uint32_t n=1; n < nchans; ++n) {
1779 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1780 if ((prop = node.property (buf)) != 0) {
1782 PBD::ID id2 (prop->value());
1784 if ((source = source_by_id (id2)) == 0) {
1785 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1786 return boost::shared_ptr<AudioRegion>();
1789 as = boost::dynamic_pointer_cast<AudioSource>(source);
1791 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1792 return boost::shared_ptr<AudioRegion>();
1794 sources.push_back (as);
1798 for (uint32_t n = 0; n < nchans; ++n) {
1799 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1800 if ((prop = node.property (buf)) != 0) {
1802 PBD::ID id2 (prop->value());
1804 if ((source = source_by_id (id2)) == 0) {
1805 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1806 return boost::shared_ptr<AudioRegion>();
1809 as = boost::dynamic_pointer_cast<AudioSource>(source);
1811 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1812 return boost::shared_ptr<AudioRegion>();
1814 master_sources.push_back (as);
1819 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1821 /* a final detail: this is the one and only place that we know how long missing files are */
1823 if (region->whole_file()) {
1824 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1825 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1827 sfp->set_length (region->length());
1832 if (!master_sources.empty()) {
1833 if (master_sources.size() != nchans) {
1834 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1836 region->set_master_sources (master_sources);
1844 catch (failed_constructor& err) {
1845 return boost::shared_ptr<AudioRegion>();
1849 boost::shared_ptr<MidiRegion>
1850 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1852 const XMLProperty* prop;
1853 boost::shared_ptr<Source> source;
1854 boost::shared_ptr<MidiSource> ms;
1857 if (node.name() != X_("Region")) {
1858 return boost::shared_ptr<MidiRegion>();
1861 if ((prop = node.property ("name")) == 0) {
1862 cerr << "no name for this region\n";
1866 if ((prop = node.property (X_("source-0"))) == 0) {
1867 if ((prop = node.property ("source")) == 0) {
1868 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1869 return boost::shared_ptr<MidiRegion>();
1873 PBD::ID s_id (prop->value());
1875 if ((source = source_by_id (s_id)) == 0) {
1876 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1877 return boost::shared_ptr<MidiRegion>();
1880 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1882 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1883 return boost::shared_ptr<MidiRegion>();
1886 sources.push_back (ms);
1889 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1890 /* a final detail: this is the one and only place that we know how long missing files are */
1892 if (region->whole_file()) {
1893 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1894 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1896 sfp->set_length (region->length());
1904 catch (failed_constructor& err) {
1905 return boost::shared_ptr<MidiRegion>();
1910 Session::get_sources_as_xml ()
1913 XMLNode* node = new XMLNode (X_("Sources"));
1914 Glib::Mutex::Lock lm (source_lock);
1916 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1917 node->add_child_nocopy (i->second->get_state());
1924 Session::path_from_region_name (DataType type, string name, string identifier)
1926 char buf[PATH_MAX+1];
1928 SessionDirectory sdir(get_best_session_directory_for_new_source());
1929 sys::path source_dir = ((type == DataType::AUDIO)
1930 ? sdir.sound_path() : sdir.midi_path());
1932 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1934 for (n = 0; n < 999999; ++n) {
1935 if (identifier.length()) {
1936 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1937 identifier.c_str(), n, ext.c_str());
1939 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1943 sys::path source_path = source_dir / buf;
1945 if (!sys::exists (source_path)) {
1946 return source_path.to_string();
1950 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1959 Session::load_sources (const XMLNode& node)
1962 XMLNodeConstIterator niter;
1963 boost::shared_ptr<Source> source;
1965 nlist = node.children();
1969 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1972 if ((source = XMLSourceFactory (**niter)) == 0) {
1973 error << _("Session: cannot create Source from XML description.") << endmsg;
1976 } catch (MissingSource& err) {
1980 if (!no_questions_about_missing_files) {
1981 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1986 switch (user_choice) {
1988 /* user added a new search location, so try again */
1993 /* user asked to quit the entire session load
1998 no_questions_about_missing_files = true;
2002 no_questions_about_missing_files = true;
2007 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
2008 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2017 boost::shared_ptr<Source>
2018 Session::XMLSourceFactory (const XMLNode& node)
2020 if (node.name() != "Source") {
2021 return boost::shared_ptr<Source>();
2025 /* note: do peak building in another thread when loading session state */
2026 return SourceFactory::create (*this, node, true);
2029 catch (failed_constructor& err) {
2030 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2031 return boost::shared_ptr<Source>();
2036 Session::save_template (string template_name)
2040 if (_state_of_the_state & CannotSave) {
2044 sys::path user_template_dir(user_template_directory());
2048 sys::create_directories (user_template_dir);
2050 catch(sys::filesystem_error& ex)
2052 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2053 user_template_dir.to_string(), ex.what()) << endmsg;
2057 tree.set_root (&get_template());
2059 sys::path template_dir_path(user_template_dir);
2061 /* directory to put the template in */
2062 template_dir_path /= template_name;
2063 if (sys::exists (template_dir_path))
2065 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2066 template_dir_path.to_string()) << endmsg;
2070 sys::create_directories (template_dir_path);
2073 sys::path template_file_path = template_dir_path;
2074 template_file_path /= template_name + template_suffix;
2076 if (!tree.write (template_file_path.to_string())) {
2077 error << _("template not saved") << endmsg;
2081 /* copy plugin state directory */
2083 sys::path template_plugin_state_path = template_dir_path;
2084 template_plugin_state_path /= X_("plugins");
2085 sys::create_directories (template_plugin_state_path);
2086 sys::copy_files (plugins_dir(), template_plugin_state_path);
2092 Session::refresh_disk_space ()
2095 struct statfs statfsbuf;
2096 vector<space_and_path>::iterator i;
2097 Glib::Mutex::Lock lm (space_lock);
2100 /* get freespace on every FS that is part of the session path */
2102 _total_free_4k_blocks = 0;
2104 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2105 statfs ((*i).path.c_str(), &statfsbuf);
2107 scale = statfsbuf.f_bsize/4096.0;
2109 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2110 _total_free_4k_blocks += (*i).blocks;
2116 Session::get_best_session_directory_for_new_source ()
2118 vector<space_and_path>::iterator i;
2119 string result = _session_dir->root_path().to_string();
2121 /* handle common case without system calls */
2123 if (session_dirs.size() == 1) {
2127 /* OK, here's the algorithm we're following here:
2129 We want to select which directory to use for
2130 the next file source to be created. Ideally,
2131 we'd like to use a round-robin process so as to
2132 get maximum performance benefits from splitting
2133 the files across multiple disks.
2135 However, in situations without much diskspace, an
2136 RR approach may end up filling up a filesystem
2137 with new files while others still have space.
2138 Its therefore important to pay some attention to
2139 the freespace in the filesystem holding each
2140 directory as well. However, if we did that by
2141 itself, we'd keep creating new files in the file
2142 system with the most space until it was as full
2143 as all others, thus negating any performance
2144 benefits of this RAID-1 like approach.
2146 So, we use a user-configurable space threshold. If
2147 there are at least 2 filesystems with more than this
2148 much space available, we use RR selection between them.
2149 If not, then we pick the filesystem with the most space.
2151 This gets a good balance between the two
2155 refresh_disk_space ();
2157 int free_enough = 0;
2159 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2160 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2165 if (free_enough >= 2) {
2166 /* use RR selection process, ensuring that the one
2170 i = last_rr_session_dir;
2173 if (++i == session_dirs.end()) {
2174 i = session_dirs.begin();
2177 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2178 if (create_session_directory ((*i).path)) {
2180 last_rr_session_dir = i;
2185 } while (i != last_rr_session_dir);
2189 /* pick FS with the most freespace (and that
2190 seems to actually work ...)
2193 vector<space_and_path> sorted;
2194 space_and_path_ascending_cmp cmp;
2196 sorted = session_dirs;
2197 sort (sorted.begin(), sorted.end(), cmp);
2199 for (i = sorted.begin(); i != sorted.end(); ++i) {
2200 if (create_session_directory ((*i).path)) {
2202 last_rr_session_dir = i;
2212 Session::load_named_selections (const XMLNode& node)
2215 XMLNodeConstIterator niter;
2218 nlist = node.children();
2222 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2224 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2225 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2233 Session::XMLNamedSelectionFactory (const XMLNode& node)
2236 return new NamedSelection (*this, node);
2239 catch (failed_constructor& err) {
2245 Session::automation_dir () const
2247 return Glib::build_filename (_path, "automation");
2251 Session::analysis_dir () const
2253 return Glib::build_filename (_path, "analysis");
2257 Session::plugins_dir () const
2259 return Glib::build_filename (_path, "plugins");
2263 Session::load_bundles (XMLNode const & node)
2265 XMLNodeList nlist = node.children();
2266 XMLNodeConstIterator niter;
2270 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2271 if ((*niter)->name() == "InputBundle") {
2272 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2273 } else if ((*niter)->name() == "OutputBundle") {
2274 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2276 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2285 Session::load_route_groups (const XMLNode& node, int version)
2287 XMLNodeList nlist = node.children();
2288 XMLNodeConstIterator niter;
2292 if (version >= 3000) {
2294 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2295 if ((*niter)->name() == "RouteGroup") {
2296 RouteGroup* rg = new RouteGroup (*this, "");
2297 add_route_group (rg);
2298 rg->set_state (**niter, version);
2302 } else if (version < 3000) {
2304 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2305 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2306 RouteGroup* rg = new RouteGroup (*this, "");
2307 add_route_group (rg);
2308 rg->set_state (**niter, version);
2317 Session::auto_save()
2319 save_state (_current_snapshot_name);
2323 state_file_filter (const string &str, void */*arg*/)
2325 return (str.length() > strlen(statefile_suffix) &&
2326 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2330 bool operator()(const string* a, const string* b) {
2336 remove_end(string* state)
2338 string statename(*state);
2340 string::size_type start,end;
2341 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2342 statename = statename.substr (start+1);
2345 if ((end = statename.rfind(".ardour")) == string::npos) {
2346 end = statename.length();
2349 return new string(statename.substr (0, end));
2353 Session::possible_states (string path)
2355 PathScanner scanner;
2356 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2358 transform(states->begin(), states->end(), states->begin(), remove_end);
2361 sort (states->begin(), states->end(), cmp);
2367 Session::possible_states () const
2369 return possible_states(_path);
2373 Session::add_route_group (RouteGroup* g)
2375 _route_groups.push_back (g);
2376 route_group_added (g); /* EMIT SIGNAL */
2378 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2379 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2380 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2386 Session::remove_route_group (RouteGroup& rg)
2388 list<RouteGroup*>::iterator i;
2390 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2391 _route_groups.erase (i);
2394 route_group_removed (); /* EMIT SIGNAL */
2398 /** Set a new order for our route groups, without adding or removing any.
2399 * @param groups Route group list in the new order.
2402 Session::reorder_route_groups (list<RouteGroup*> groups)
2404 _route_groups = groups;
2406 route_groups_reordered (); /* EMIT SIGNAL */
2412 Session::route_group_by_name (string name)
2414 list<RouteGroup *>::iterator i;
2416 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2417 if ((*i)->name() == name) {
2425 Session::all_route_group() const
2427 return *_all_route_group;
2431 Session::add_commands (vector<Command*> const & cmds)
2433 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2439 Session::begin_reversible_command (const string& name)
2441 begin_reversible_command (g_quark_from_string (name.c_str ()));
2444 /** Begin a reversible command using a GQuark to identify it.
2445 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2446 * but there must be as many begin...()s as there are commit...()s.
2449 Session::begin_reversible_command (GQuark q)
2451 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2452 to hold all the commands that are committed. This keeps the order of
2453 commands correct in the history.
2456 if (_current_trans == 0) {
2457 /* start a new transaction */
2458 assert (_current_trans_quarks.empty ());
2459 _current_trans = new UndoTransaction();
2460 _current_trans->set_name (g_quark_to_string (q));
2463 _current_trans_quarks.push_front (q);
2467 Session::commit_reversible_command (Command *cmd)
2469 assert (_current_trans);
2470 assert (!_current_trans_quarks.empty ());
2475 _current_trans->add_command (cmd);
2478 _current_trans_quarks.pop_front ();
2480 if (!_current_trans_quarks.empty ()) {
2481 /* the transaction we're committing is not the top-level one */
2485 if (_current_trans->empty()) {
2486 /* no commands were added to the transaction, so just get rid of it */
2487 delete _current_trans;
2492 gettimeofday (&now, 0);
2493 _current_trans->set_timestamp (now);
2495 _history.add (_current_trans);
2500 accept_all_audio_files (const string& path, void */*arg*/)
2502 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2506 if (!AudioFileSource::safe_audio_file_extension (path)) {
2514 accept_all_midi_files (const string& path, void */*arg*/)
2516 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2520 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2521 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2522 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2526 accept_all_state_files (const string& path, void */*arg*/)
2528 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2532 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2536 Session::find_all_sources (string path, set<string>& result)
2541 if (!tree.read (path)) {
2545 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2550 XMLNodeConstIterator niter;
2552 nlist = node->children();
2556 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2560 if ((prop = (*niter)->property (X_("type"))) == 0) {
2564 DataType type (prop->value());
2566 if ((prop = (*niter)->property (X_("name"))) == 0) {
2570 if (Glib::path_is_absolute (prop->value())) {
2571 /* external file, ignore */
2579 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2580 result.insert (found_path);
2588 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2590 PathScanner scanner;
2591 vector<string*>* state_files;
2593 string this_snapshot_path;
2599 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2600 ripped = ripped.substr (0, ripped.length() - 1);
2603 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2605 if (state_files == 0) {
2610 this_snapshot_path = _path;
2611 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2612 this_snapshot_path += statefile_suffix;
2614 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2616 if (exclude_this_snapshot && **i == this_snapshot_path) {
2620 if (find_all_sources (**i, result) < 0) {
2628 struct RegionCounter {
2629 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2630 AudioSourceList::iterator iter;
2631 boost::shared_ptr<Region> region;
2634 RegionCounter() : count (0) {}
2638 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2640 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2641 return r.get_value_or (1);
2645 Session::cleanup_regions ()
2647 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2649 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2651 uint32_t used = playlists->region_use_count (i->second);
2653 if (used == 0 && !i->second->automatic ()) {
2654 RegionFactory::map_remove (i->second);
2658 /* dump the history list */
2665 Session::cleanup_sources (CleanupReport& rep)
2667 // FIXME: needs adaptation to midi
2669 vector<boost::shared_ptr<Source> > dead_sources;
2670 PathScanner scanner;
2673 vector<space_and_path>::iterator i;
2674 vector<space_and_path>::iterator nexti;
2675 vector<string*>* candidates;
2676 vector<string*>* candidates2;
2677 vector<string> unused;
2678 set<string> all_sources;
2683 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2685 /* consider deleting all unused playlists */
2687 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2692 /* sync the "all regions" property of each playlist with its current state
2695 playlists->sync_all_regions_with_regions ();
2697 /* find all un-used sources */
2702 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2704 SourceMap::iterator tmp;
2709 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2713 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2714 dead_sources.push_back (i->second);
2715 i->second->drop_references ();
2721 /* build a list of all the possible audio directories for the session */
2723 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2728 SessionDirectory sdir ((*i).path);
2729 audio_path += sdir.sound_path().to_string();
2731 if (nexti != session_dirs.end()) {
2739 /* build a list of all the possible midi directories for the session */
2741 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2746 SessionDirectory sdir ((*i).path);
2747 midi_path += sdir.midi_path().to_string();
2749 if (nexti != session_dirs.end()) {
2756 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2757 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2763 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2764 candidates->push_back (*i);
2769 candidates = candidates2; // might still be null
2772 /* find all sources, but don't use this snapshot because the
2773 state file on disk still references sources we may have already
2777 find_all_sources_across_snapshots (all_sources, true);
2779 /* add our current source list
2782 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2783 boost::shared_ptr<FileSource> fs;
2784 SourceMap::iterator tmp = i;
2787 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2788 if (playlists->source_use_count (fs) != 0) {
2789 all_sources.insert (fs->path());
2792 /* we might not remove this source from disk, because it may be used
2793 by other snapshots, but its not being used in this version
2794 so lets get rid of it now, along with any representative regions
2798 RegionFactory::remove_regions_using_source (i->second);
2806 char tmppath1[PATH_MAX+1];
2807 char tmppath2[PATH_MAX+1];
2810 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2815 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2817 if (realpath(spath.c_str(), tmppath1) == 0) {
2818 error << string_compose (_("Cannot expand path %1 (%2)"),
2819 spath, strerror (errno)) << endmsg;
2823 if (realpath((*i).c_str(), tmppath2) == 0) {
2824 error << string_compose (_("Cannot expand path %1 (%2)"),
2825 (*i), strerror (errno)) << endmsg;
2829 if (strcmp(tmppath1, tmppath2) == 0) {
2836 unused.push_back (spath);
2845 /* now try to move all unused files into the "dead" directory(ies) */
2847 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2848 struct stat statbuf;
2852 /* don't move the file across filesystems, just
2853 stick it in the `dead_dir_name' directory
2854 on whichever filesystem it was already on.
2857 if ((*x).find ("/sounds/") != string::npos) {
2859 /* old school, go up 1 level */
2861 newpath = Glib::path_get_dirname (*x); // "sounds"
2862 newpath = Glib::path_get_dirname (newpath); // "session-name"
2866 /* new school, go up 4 levels */
2868 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2869 newpath = Glib::path_get_dirname (newpath); // "session-name"
2870 newpath = Glib::path_get_dirname (newpath); // "interchange"
2871 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2874 newpath = Glib::build_filename (newpath, dead_dir_name);
2876 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2877 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2881 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2883 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2885 /* the new path already exists, try versioning */
2887 char buf[PATH_MAX+1];
2891 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2894 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2895 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2899 if (version == 999) {
2900 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2904 newpath = newpath_v;
2909 /* it doesn't exist, or we can't read it or something */
2913 stat ((*x).c_str(), &statbuf);
2915 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2916 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2917 (*x), newpath, strerror (errno))
2922 /* see if there an easy to find peakfile for this file, and remove it.
2925 string base = basename_nosuffix (*x);
2926 base += "%A"; /* this is what we add for the channel suffix of all native files,
2927 or for the first channel of embedded files. it will miss
2928 some peakfiles for other channels
2930 string peakpath = peak_path (base);
2932 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2933 if (::unlink (peakpath.c_str()) != 0) {
2934 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2935 peakpath, _path, strerror (errno))
2937 /* try to back out */
2938 ::rename (newpath.c_str(), _path.c_str());
2943 rep.paths.push_back (*x);
2944 rep.space += statbuf.st_size;
2947 /* dump the history list */
2951 /* save state so we don't end up a session file
2952 referring to non-existent sources.
2959 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2965 Session::cleanup_trash_sources (CleanupReport& rep)
2967 // FIXME: needs adaptation for MIDI
2969 vector<space_and_path>::iterator i;
2975 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2977 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2979 clear_directory (dead_dir, &rep.space, &rep.paths);
2986 Session::set_dirty ()
2988 bool was_dirty = dirty();
2990 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2994 DirtyChanged(); /* EMIT SIGNAL */
3000 Session::set_clean ()
3002 bool was_dirty = dirty();
3004 _state_of_the_state = Clean;
3008 DirtyChanged(); /* EMIT SIGNAL */
3013 Session::set_deletion_in_progress ()
3015 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3019 Session::clear_deletion_in_progress ()
3021 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3025 Session::add_controllable (boost::shared_ptr<Controllable> c)
3027 /* this adds a controllable to the list managed by the Session.
3028 this is a subset of those managed by the Controllable class
3029 itself, and represents the only ones whose state will be saved
3030 as part of the session.
3033 Glib::Mutex::Lock lm (controllables_lock);
3034 controllables.insert (c);
3037 struct null_deleter { void operator()(void const *) const {} };
3040 Session::remove_controllable (Controllable* c)
3042 if (_state_of_the_state | Deletion) {
3046 Glib::Mutex::Lock lm (controllables_lock);
3048 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3050 if (x != controllables.end()) {
3051 controllables.erase (x);
3055 boost::shared_ptr<Controllable>
3056 Session::controllable_by_id (const PBD::ID& id)
3058 Glib::Mutex::Lock lm (controllables_lock);
3060 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3061 if ((*i)->id() == id) {
3066 return boost::shared_ptr<Controllable>();
3069 boost::shared_ptr<Controllable>
3070 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3072 boost::shared_ptr<Controllable> c;
3073 boost::shared_ptr<Route> r;
3075 switch (desc.top_level_type()) {
3076 case ControllableDescriptor::NamedRoute:
3078 std::string str = desc.top_level_name();
3079 if (str == "master") {
3081 } else if (str == "control" || str == "listen") {
3084 r = route_by_name (desc.top_level_name());
3089 case ControllableDescriptor::RemoteControlID:
3090 r = route_by_remote_id (desc.rid());
3098 switch (desc.subtype()) {
3099 case ControllableDescriptor::Gain:
3100 c = r->gain_control ();
3103 case ControllableDescriptor::Solo:
3104 c = r->solo_control();
3107 case ControllableDescriptor::Mute:
3108 c = r->mute_control();
3111 case ControllableDescriptor::Recenable:
3113 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3116 c = t->rec_enable_control ();
3121 case ControllableDescriptor::PanDirection:
3123 c = r->pannable()->pan_azimuth_control;
3127 case ControllableDescriptor::PanWidth:
3129 c = r->pannable()->pan_width_control;
3133 case ControllableDescriptor::PanElevation:
3135 c = r->pannable()->pan_elevation_control;
3139 case ControllableDescriptor::Balance:
3140 /* XXX simple pan control */
3143 case ControllableDescriptor::PluginParameter:
3145 uint32_t plugin = desc.target (0);
3146 uint32_t parameter_index = desc.target (1);
3148 /* revert to zero based counting */
3154 if (parameter_index > 0) {
3158 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3161 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3162 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3167 case ControllableDescriptor::SendGain:
3169 uint32_t send = desc.target (0);
3171 /* revert to zero-based counting */
3177 boost::shared_ptr<Processor> p = r->nth_send (send);
3180 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3181 boost::shared_ptr<Amp> a = s->amp();
3184 c = s->amp()->gain_control();
3191 /* relax and return a null pointer */
3199 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3202 Stateful::add_instant_xml (node, _path);
3205 if (write_to_config) {
3206 Config->add_instant_xml (node);
3211 Session::instant_xml (const string& node_name)
3213 return Stateful::instant_xml (node_name, _path);
3217 Session::save_history (string snapshot_name)
3225 if (snapshot_name.empty()) {
3226 snapshot_name = _current_snapshot_name;
3229 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3230 const string backup_filename = history_filename + backup_suffix;
3231 const sys::path xml_path = _session_dir->root_path() / history_filename;
3232 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3234 if (sys::exists (xml_path)) {
3237 sys::rename (xml_path, backup_path);
3239 catch (const sys::filesystem_error& err)
3241 error << _("could not backup old history file, current history not saved") << endmsg;
3246 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3250 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3252 if (!tree.write (xml_path.to_string()))
3254 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3258 sys::remove (xml_path);
3259 sys::rename (backup_path, xml_path);
3261 catch (const sys::filesystem_error& err)
3263 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3264 backup_path.to_string(), err.what()) << endmsg;
3274 Session::restore_history (string snapshot_name)
3278 if (snapshot_name.empty()) {
3279 snapshot_name = _current_snapshot_name;
3282 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3283 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3285 info << "Loading history from " << xml_path.to_string() << endmsg;
3287 if (!sys::exists (xml_path)) {
3288 info << string_compose (_("%1: no history file \"%2\" for this session."),
3289 _name, xml_path.to_string()) << endmsg;
3293 if (!tree.read (xml_path.to_string())) {
3294 error << string_compose (_("Could not understand session history file \"%1\""),
3295 xml_path.to_string()) << endmsg;
3302 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3305 UndoTransaction* ut = new UndoTransaction ();
3308 ut->set_name(t->property("name")->value());
3309 stringstream ss(t->property("tv-sec")->value());
3311 ss.str(t->property("tv-usec")->value());
3313 ut->set_timestamp(tv);
3315 for (XMLNodeConstIterator child_it = t->children().begin();
3316 child_it != t->children().end(); child_it++)
3318 XMLNode *n = *child_it;
3321 if (n->name() == "MementoCommand" ||
3322 n->name() == "MementoUndoCommand" ||
3323 n->name() == "MementoRedoCommand") {
3325 if ((c = memento_command_factory(n))) {
3329 } else if (n->name() == "NoteDiffCommand") {
3330 PBD::ID id (n->property("midi-source")->value());
3331 boost::shared_ptr<MidiSource> midi_source =
3332 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3334 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3336 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3339 } else if (n->name() == "SysExDiffCommand") {
3341 PBD::ID id (n->property("midi-source")->value());
3342 boost::shared_ptr<MidiSource> midi_source =
3343 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3345 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3347 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3350 } else if (n->name() == "PatchChangeDiffCommand") {
3352 PBD::ID id (n->property("midi-source")->value());
3353 boost::shared_ptr<MidiSource> midi_source =
3354 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3356 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3358 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3361 } else if (n->name() == "StatefulDiffCommand") {
3362 if ((c = stateful_diff_command_factory (n))) {
3363 ut->add_command (c);
3366 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3377 Session::config_changed (std::string p, bool ours)
3383 if (p == "seamless-loop") {
3385 } else if (p == "rf-speed") {
3387 } else if (p == "auto-loop") {
3389 } else if (p == "auto-input") {
3391 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3392 /* auto-input only makes a difference if we're rolling */
3393 set_track_monitor_input_status (!config.get_auto_input());
3396 } else if (p == "punch-in") {
3400 if ((location = _locations->auto_punch_location()) != 0) {
3402 if (config.get_punch_in ()) {
3403 replace_event (SessionEvent::PunchIn, location->start());
3405 remove_event (location->start(), SessionEvent::PunchIn);
3409 } else if (p == "punch-out") {
3413 if ((location = _locations->auto_punch_location()) != 0) {
3415 if (config.get_punch_out()) {
3416 replace_event (SessionEvent::PunchOut, location->end());
3418 clear_events (SessionEvent::PunchOut);
3422 } else if (p == "edit-mode") {
3424 Glib::Mutex::Lock lm (playlists->lock);
3426 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3427 (*i)->set_edit_mode (Config->get_edit_mode ());
3430 } else if (p == "use-video-sync") {
3432 waiting_for_sync_offset = config.get_use_video_sync();
3434 } else if (p == "mmc-control") {
3436 //poke_midi_thread ();
3438 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3440 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3442 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3444 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3446 } else if (p == "midi-control") {
3448 //poke_midi_thread ();
3450 } else if (p == "raid-path") {
3452 setup_raid_path (config.get_raid_path());
3454 } else if (p == "timecode-format") {
3458 } else if (p == "video-pullup") {
3462 } else if (p == "seamless-loop") {
3464 if (play_loop && transport_rolling()) {
3465 // to reset diskstreams etc
3466 request_play_loop (true);
3469 } else if (p == "rf-speed") {
3471 cumulative_rf_motion = 0;
3474 } else if (p == "click-sound") {
3476 setup_click_sounds (1);
3478 } else if (p == "click-emphasis-sound") {
3480 setup_click_sounds (-1);
3482 } else if (p == "clicking") {
3484 if (Config->get_clicking()) {
3485 if (_click_io && click_data) { // don't require emphasis data
3492 } else if (p == "send-mtc") {
3494 if (Config->get_send_mtc ()) {
3495 /* mark us ready to send */
3496 next_quarter_frame_to_send = 0;
3499 } else if (p == "send-mmc") {
3501 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3503 } else if (p == "midi-feedback") {
3505 session_midi_feedback = Config->get_midi_feedback();
3507 } else if (p == "jack-time-master") {
3509 engine().reset_timebase ();
3511 } else if (p == "native-file-header-format") {
3513 if (!first_file_header_format_reset) {
3514 reset_native_file_format ();
3517 first_file_header_format_reset = false;
3519 } else if (p == "native-file-data-format") {
3521 if (!first_file_data_format_reset) {
3522 reset_native_file_format ();
3525 first_file_data_format_reset = false;
3527 } else if (p == "external-sync") {
3528 if (!config.get_external_sync()) {
3529 drop_sync_source ();
3531 switch_to_sync_source (config.get_sync_source());
3533 } else if (p == "remote-model") {
3534 set_remote_control_ids ();
3535 } else if (p == "denormal-model") {
3537 } else if (p == "history-depth") {
3538 set_history_depth (Config->get_history_depth());
3539 } else if (p == "sync-all-route-ordering") {
3540 sync_order_keys ("session");
3541 } else if (p == "initial-program-change") {
3543 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3546 buf[0] = MIDI::program; // channel zero by default
3547 buf[1] = (Config->get_initial_program_change() & 0x7f);
3549 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3551 } else if (p == "solo-mute-override") {
3552 // catch_up_on_solo_mute_override ();
3553 } else if (p == "listen-position" || p == "pfl-position") {
3554 listen_position_changed ();
3555 } else if (p == "solo-control-is-listen-control") {
3556 solo_control_mode_changed ();
3557 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3558 last_timecode_valid = false;
3559 } else if (p == "playback-buffer-seconds") {
3560 AudioSource::allocate_working_buffers (frame_rate());
3567 Session::set_history_depth (uint32_t d)
3569 _history.set_depth (d);
3573 Session::load_diskstreams_2X (XMLNode const & node, int)
3576 XMLNodeConstIterator citer;
3578 clist = node.children();
3580 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3583 /* diskstreams added automatically by DiskstreamCreated handler */
3584 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3585 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3586 _diskstreams_2X.push_back (dsp);
3588 error << _("Session: unknown diskstream type in XML") << endmsg;
3592 catch (failed_constructor& err) {
3593 error << _("Session: could not load diskstream via XML state") << endmsg;
3601 /** Connect things to the MMC object */
3603 Session::setup_midi_machine_control ()
3605 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3607 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3608 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3609 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3610 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3611 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3612 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3613 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3614 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3615 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3616 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3617 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3618 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3619 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3621 /* also handle MIDI SPP because its so common */
3623 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3624 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3625 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));
3628 boost::shared_ptr<Controllable>
3629 Session::solo_cut_control() const
3631 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3632 controls in Ardour that currently get presented to the user in the GUI that require
3633 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3635 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3636 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3640 return _solo_cut_control;
3644 Session::rename (const std::string& new_name)
3646 string legal_name = legalize_for_path (new_name);
3652 string const old_sources_root = _session_dir->sources_root().to_string ();
3654 #define RENAME ::rename
3659 * interchange subdirectory
3663 * Backup files are left unchanged and not renamed.
3666 /* pass one: not 100% safe check that the new directory names don't
3670 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3675 /* this is a stupid hack because Glib::path_get_dirname() is
3676 * lexical-only, and so passing it /a/b/c/ gives a different
3677 * result than passing it /a/b/c ...
3680 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3681 oldstr = oldstr.substr (0, oldstr.length() - 1);
3684 string base = Glib::path_get_dirname (oldstr);
3685 string p = Glib::path_get_basename (oldstr);
3687 newstr = Glib::build_filename (base, legal_name);
3689 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
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 cerr << "Rename " << oldstr << " => " << newstr << endl;
3717 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3722 (*_session_dir) = newstr;
3727 /* directory below interchange */
3729 v.push_back (newstr);
3730 v.push_back (interchange_dir_name);
3733 oldstr = Glib::build_filename (v);
3736 v.push_back (newstr);
3737 v.push_back (interchange_dir_name);
3738 v.push_back (legal_name);
3740 newstr = Glib::build_filename (v);
3742 cerr << "Rename " << oldstr << " => " << newstr << endl;
3744 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3751 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3752 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3754 cerr << "Rename " << oldstr << " => " << newstr << endl;
3756 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3763 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3765 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3766 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3768 cerr << "Rename " << oldstr << " => " << newstr << endl;
3770 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3775 /* update file source paths */
3777 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3778 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3780 string p = fs->path ();
3781 boost::replace_all (p, old_sources_root, _session_dir->sources_root().to_string ());
3786 /* remove old name from recent sessions */
3788 remove_recent_sessions (_path);
3791 _current_snapshot_name = new_name;
3796 /* save state again to get everything just right */
3798 save_state (_current_snapshot_name);
3801 /* add to recent sessions */
3803 store_recent_sessions (new_name, _path);