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 (bool with_midi_ui)
298 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
301 if (load_state (_current_snapshot_name)) {
306 if (_butler->start_thread()) {
311 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));
352 when_engine_running ();
355 /* handle this one in a different way than all others, so that its clear what happened */
357 catch (AudioEngine::PortRegistrationFailure& err) {
358 error << err.what() << endmsg;
366 BootMessage (_("Reset Remote Controls"));
368 send_full_time_code (0);
369 _engine.transport_locate (0);
371 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
372 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
374 MidiClockTicker::instance().set_session (this);
375 MIDI::Name::MidiPatchManager::instance().set_session (this);
377 /* initial program change will be delivered later; see ::config_changed() */
379 _state_of_the_state = Clean;
381 Port::set_connecting_blocked (false);
383 DirtyChanged (); /* EMIT SIGNAL */
385 if (state_was_pending) {
386 save_state (_current_snapshot_name);
387 remove_pending_capture_state ();
388 state_was_pending = false;
391 BootMessage (_("Session loading complete"));
397 Session::raid_path () const
399 SearchPath raid_search_path;
401 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
402 raid_search_path += sys::path((*i).path);
405 return raid_search_path.to_string ();
409 Session::setup_raid_path (string path)
418 session_dirs.clear ();
420 SearchPath search_path(path);
421 SearchPath sound_search_path;
422 SearchPath midi_search_path;
424 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
425 sp.path = (*i).to_string ();
426 sp.blocks = 0; // not needed
427 session_dirs.push_back (sp);
429 SessionDirectory sdir(sp.path);
431 sound_search_path += sdir.sound_path ();
432 midi_search_path += sdir.midi_path ();
435 // reset the round-robin soundfile path thingie
436 last_rr_session_dir = session_dirs.begin();
440 Session::path_is_within_session (const std::string& path)
442 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
443 if (path.find ((*i).path) == 0) {
451 Session::ensure_subdirs ()
455 dir = session_directory().peak_path().to_string();
457 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
458 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
462 dir = session_directory().sound_path().to_string();
464 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
465 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
469 dir = session_directory().midi_path().to_string();
471 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
472 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
476 dir = session_directory().dead_path().to_string();
478 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
479 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
483 dir = session_directory().export_path().to_string();
485 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
486 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
490 dir = analysis_dir ();
492 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
493 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
497 dir = plugins_dir ();
499 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
500 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
507 /** @param session_template directory containing session template, or empty.
508 * Caller must not hold process lock.
511 Session::create (const string& session_template, BusProfile* bus_profile)
513 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
514 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
518 if (ensure_subdirs ()) {
522 _writable = exists_and_writable (sys::path (_path));
524 if (!session_template.empty()) {
525 std::string in_path = session_template_dir_to_file (session_template);
527 ifstream in(in_path.c_str());
530 string out_path = _path;
532 out_path += statefile_suffix;
534 ofstream out(out_path.c_str());
540 /* Copy plugin state files from template to new session */
541 sys::path template_plugins = session_template;
542 template_plugins /= X_("plugins");
543 sys::copy_files (template_plugins, plugins_dir ());
548 error << string_compose (_("Could not open %1 for writing session template"), out_path)
554 error << string_compose (_("Could not open session template %1 for reading"), in_path)
561 /* Instantiate metadata */
563 _metadata = new SessionMetadata ();
565 /* set initial start + end point */
567 _state_of_the_state = Clean;
569 /* set up Master Out and Control Out if necessary */
575 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
577 if (bus_profile->master_out_channels) {
578 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
582 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
583 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
586 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
587 r->input()->ensure_io (count, false, this);
588 r->output()->ensure_io (count, false, this);
590 r->set_remote_control_id (control_id++);
594 if (Config->get_use_monitor_bus()) {
595 boost::shared_ptr<Route> r (new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO));
599 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
600 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
603 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
604 r->input()->ensure_io (count, false, this);
605 r->output()->ensure_io (count, false, this);
607 r->set_remote_control_id (control_id);
613 /* prohibit auto-connect to master, because there isn't one */
614 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
618 add_routes (rl, false, false);
621 /* this allows the user to override settings with an environment variable.
624 if (no_auto_connect()) {
625 bus_profile->input_ac = AutoConnectOption (0);
626 bus_profile->output_ac = AutoConnectOption (0);
629 Config->set_input_auto_connect (bus_profile->input_ac);
630 Config->set_output_auto_connect (bus_profile->output_ac);
639 Session::maybe_write_autosave()
641 if (dirty() && record_status() != Recording) {
642 save_state("", true);
647 Session::remove_pending_capture_state ()
649 sys::path pending_state_file_path(_session_dir->root_path());
651 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
655 sys::remove (pending_state_file_path);
657 catch(sys::filesystem_error& ex)
659 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
660 pending_state_file_path.to_string(), ex.what()) << endmsg;
664 /** Rename a state file.
665 * @param old_name Old snapshot name.
666 * @param new_name New snapshot name.
669 Session::rename_state (string old_name, string new_name)
671 if (old_name == _current_snapshot_name || old_name == _name) {
672 /* refuse to rename the current snapshot or the "main" one */
676 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
677 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
679 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
680 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
684 sys::rename (old_xml_path, new_xml_path);
686 catch (const sys::filesystem_error& err)
688 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
689 old_name, new_name, err.what()) << endmsg;
693 /** Remove a state file.
694 * @param snapshot_name Snapshot name.
697 Session::remove_state (string snapshot_name)
699 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
700 // refuse to remove the current snapshot or the "main" one
704 sys::path xml_path(_session_dir->root_path());
706 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
708 if (!create_backup_file (xml_path)) {
709 // don't remove it if a backup can't be made
710 // create_backup_file will log the error.
715 sys::remove (xml_path);
718 #ifdef HAVE_JACK_SESSION
720 Session::jack_session_event (jack_session_event_t * event)
724 struct tm local_time;
727 localtime_r (&n, &local_time);
728 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
730 if (event->type == JackSessionSaveTemplate)
732 if (save_template( timebuf )) {
733 event->flags = JackSessionSaveError;
735 string cmd ("ardour3 -P -U ");
736 cmd += event->client_uuid;
740 event->command_line = strdup (cmd.c_str());
745 if (save_state (timebuf)) {
746 event->flags = JackSessionSaveError;
748 sys::path xml_path (_session_dir->root_path());
749 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
751 string cmd ("ardour3 -P -U ");
752 cmd += event->client_uuid;
754 cmd += xml_path.to_string();
757 event->command_line = strdup (cmd.c_str());
761 jack_session_reply (_engine.jack(), event);
763 if (event->type == JackSessionSaveAndQuit) {
764 Quit (); /* EMIT SIGNAL */
767 jack_session_event_free( event );
771 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
773 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
776 sys::path xml_path(_session_dir->root_path());
778 if (!_writable || (_state_of_the_state & CannotSave)) {
782 if (!_engine.connected ()) {
783 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
789 /* tell sources we're saving first, in case they write out to a new file
790 * which should be saved with the state rather than the old one */
791 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
792 i->second->session_saved();
795 tree.set_root (&get_state());
797 if (snapshot_name.empty()) {
798 snapshot_name = _current_snapshot_name;
799 } else if (switch_to_snapshot) {
800 _current_snapshot_name = snapshot_name;
805 /* proper save: use statefile_suffix (.ardour in English) */
807 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
809 /* make a backup copy of the old file */
811 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
812 // create_backup_file will log the error
818 /* pending save: use pending_suffix (.pending in English) */
819 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
822 sys::path tmp_path(_session_dir->root_path());
824 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
826 // cerr << "actually writing state to " << xml_path.to_string() << endl;
828 if (!tree.write (tmp_path.to_string())) {
829 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
830 sys::remove (tmp_path);
835 if (::rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
836 error << string_compose (_("could not rename temporary session file %1 to %2"),
837 tmp_path.to_string(), xml_path.to_string()) << endmsg;
838 sys::remove (tmp_path);
845 save_history (snapshot_name);
847 bool was_dirty = dirty();
849 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
852 DirtyChanged (); /* EMIT SIGNAL */
855 StateSaved (snapshot_name); /* EMIT SIGNAL */
862 Session::restore_state (string snapshot_name)
864 if (load_state (snapshot_name) == 0) {
865 set_state (*state_tree->root(), Stateful::loading_state_version);
872 Session::load_state (string snapshot_name)
877 state_was_pending = false;
879 /* check for leftover pending state from a crashed capture attempt */
881 sys::path xmlpath(_session_dir->root_path());
882 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
884 if (sys::exists (xmlpath)) {
886 /* there is pending state from a crashed capture attempt */
888 boost::optional<int> r = AskAboutPendingState();
889 if (r.get_value_or (1)) {
890 state_was_pending = true;
894 if (!state_was_pending) {
895 xmlpath = _session_dir->root_path();
896 xmlpath /= snapshot_name;
899 if (!sys::exists (xmlpath)) {
900 xmlpath = _session_dir->root_path();
901 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
902 if (!sys::exists (xmlpath)) {
903 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
908 state_tree = new XMLTree;
912 _writable = exists_and_writable (xmlpath);
914 if (!state_tree->read (xmlpath.to_string())) {
915 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
921 XMLNode& root (*state_tree->root());
923 if (root.name() != X_("Session")) {
924 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
930 const XMLProperty* prop;
932 if ((prop = root.property ("version")) == 0) {
933 /* no version implies very old version of Ardour */
934 Stateful::loading_state_version = 1000;
940 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
941 Stateful::loading_state_version = (major * 1000) + minor;
944 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
946 sys::path backup_path(_session_dir->root_path());
948 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
950 // only create a backup once
951 if (sys::exists (backup_path)) {
955 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
956 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
961 sys::copy_file (xmlpath, backup_path);
963 catch(sys::filesystem_error& ex)
965 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
966 xmlpath.to_string(), ex.what())
976 Session::load_options (const XMLNode& node)
978 LocaleGuard lg (X_("POSIX"));
979 config.set_variables (node);
990 Session::get_template()
992 /* if we don't disable rec-enable, diskstreams
993 will believe they need to store their capture
994 sources in their state node.
997 disable_record (false);
1003 Session::state(bool full_state)
1005 XMLNode* node = new XMLNode("Session");
1008 // store libardour version, just in case
1010 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
1011 node->add_property("version", string(buf));
1013 /* store configuration settings */
1017 node->add_property ("name", _name);
1018 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1019 node->add_property ("sample-rate", buf);
1021 if (session_dirs.size() > 1) {
1025 vector<space_and_path>::iterator i = session_dirs.begin();
1026 vector<space_and_path>::iterator next;
1028 ++i; /* skip the first one */
1032 while (i != session_dirs.end()) {
1036 if (next != session_dirs.end()) {
1046 child = node->add_child ("Path");
1047 child->add_content (p);
1051 /* save the ID counter */
1053 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1054 node->add_property ("id-counter", buf);
1056 /* save the event ID counter */
1058 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1059 node->add_property ("event-counter", buf);
1061 /* various options */
1063 node->add_child_nocopy (config.get_variables ());
1065 node->add_child_nocopy (_metadata->get_state());
1067 child = node->add_child ("Sources");
1070 Glib::Mutex::Lock sl (source_lock);
1072 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1074 /* Don't save information about non-file Sources, or
1075 * about non-destructive file sources that are empty
1076 * and unused by any regions.
1079 boost::shared_ptr<FileSource> fs;
1081 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1083 if (!fs->destructive()) {
1084 if (fs->empty() && !fs->used()) {
1089 child->add_child_nocopy (siter->second->get_state());
1094 child = node->add_child ("Regions");
1097 Glib::Mutex::Lock rl (region_lock);
1098 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1099 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1100 boost::shared_ptr<Region> r = i->second;
1101 /* only store regions not attached to playlists */
1102 if (r->playlist() == 0) {
1103 child->add_child_nocopy (r->state ());
1107 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1109 if (!cassocs.empty()) {
1110 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1112 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1114 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1115 i->first->id().print (buf, sizeof (buf));
1116 can->add_property (X_("copy"), buf);
1117 i->second->id().print (buf, sizeof (buf));
1118 can->add_property (X_("original"), buf);
1119 ca->add_child_nocopy (*can);
1125 node->add_child_nocopy (_locations->get_state());
1127 // for a template, just create a new Locations, populate it
1128 // with the default start and end, and get the state for that.
1129 Locations loc (*this);
1130 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1131 range->set (max_framepos, 0);
1133 node->add_child_nocopy (loc.get_state());
1136 child = node->add_child ("Bundles");
1138 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1139 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1140 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1142 child->add_child_nocopy (b->get_state());
1147 child = node->add_child ("Routes");
1149 boost::shared_ptr<RouteList> r = routes.reader ();
1151 RoutePublicOrderSorter cmp;
1152 RouteList public_order (*r);
1153 public_order.sort (cmp);
1155 /* the sort should have put control outs first */
1158 assert (_monitor_out == public_order.front());
1161 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1162 if (!(*i)->is_hidden()) {
1164 child->add_child_nocopy ((*i)->get_state());
1166 child->add_child_nocopy ((*i)->get_template());
1172 playlists->add_state (node, full_state);
1174 child = node->add_child ("RouteGroups");
1175 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1176 child->add_child_nocopy ((*i)->get_state());
1180 child = node->add_child ("Click");
1181 child->add_child_nocopy (_click_io->state (full_state));
1185 child = node->add_child ("NamedSelections");
1186 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1188 child->add_child_nocopy ((*i)->get_state());
1193 node->add_child_nocopy (_speakers->get_state());
1194 node->add_child_nocopy (_tempo_map->get_state());
1195 node->add_child_nocopy (get_control_protocol_state());
1198 node->add_child_copy (*_extra_xml);
1205 Session::get_control_protocol_state ()
1207 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1208 return cpm.get_state();
1212 Session::set_state (const XMLNode& node, int version)
1216 const XMLProperty* prop;
1219 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1221 if (node.name() != X_("Session")) {
1222 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1226 if ((prop = node.property ("version")) != 0) {
1227 version = atoi (prop->value ()) * 1000;
1230 if ((prop = node.property ("name")) != 0) {
1231 _name = prop->value ();
1234 if ((prop = node.property (X_("sample-rate"))) != 0) {
1236 _nominal_frame_rate = atoi (prop->value());
1238 if (_nominal_frame_rate != _current_frame_rate) {
1239 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1240 if (r.get_value_or (0)) {
1246 setup_raid_path(_session_dir->root_path().to_string());
1248 if ((prop = node.property (X_("id-counter"))) != 0) {
1250 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1251 ID::init_counter (x);
1253 /* old sessions used a timebased counter, so fake
1254 the startup ID counter based on a standard
1259 ID::init_counter (now);
1262 if ((prop = node.property (X_("event-counter"))) != 0) {
1263 Evoral::init_event_id_counter (atoi (prop->value()));
1266 IO::disable_connecting ();
1268 Stateful::save_extra_xml (node);
1270 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1271 load_options (*child);
1272 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1273 load_options (*child);
1275 error << _("Session: XML state has no options section") << endmsg;
1278 if (version >= 3000) {
1279 if ((child = find_named_node (node, "Metadata")) == 0) {
1280 warning << _("Session: XML state has no metadata section") << endmsg;
1281 } else if (_metadata->set_state (*child, version)) {
1286 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1287 _speakers->set_state (*child, version);
1290 if ((child = find_named_node (node, "Sources")) == 0) {
1291 error << _("Session: XML state has no sources section") << endmsg;
1293 } else if (load_sources (*child)) {
1297 if ((child = find_named_node (node, "TempoMap")) == 0) {
1298 error << _("Session: XML state has no Tempo Map section") << endmsg;
1300 } else if (_tempo_map->set_state (*child, version)) {
1304 if ((child = find_named_node (node, "Locations")) == 0) {
1305 error << _("Session: XML state has no locations section") << endmsg;
1307 } else if (_locations->set_state (*child, version)) {
1313 if ((location = _locations->auto_loop_location()) != 0) {
1314 set_auto_loop_location (location);
1317 if ((location = _locations->auto_punch_location()) != 0) {
1318 set_auto_punch_location (location);
1321 if ((location = _locations->session_range_location()) != 0) {
1322 delete _session_range_location;
1323 _session_range_location = location;
1326 if (_session_range_location) {
1327 AudioFileSource::set_header_position_offset (_session_range_location->start());
1330 if ((child = find_named_node (node, "Regions")) == 0) {
1331 error << _("Session: XML state has no Regions section") << endmsg;
1333 } else if (load_regions (*child)) {
1337 if ((child = find_named_node (node, "Playlists")) == 0) {
1338 error << _("Session: XML state has no playlists section") << endmsg;
1340 } else if (playlists->load (*this, *child)) {
1344 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1346 } else if (playlists->load_unused (*this, *child)) {
1350 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1351 if (load_compounds (*child)) {
1356 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1357 if (load_named_selections (*child)) {
1362 if (version >= 3000) {
1363 if ((child = find_named_node (node, "Bundles")) == 0) {
1364 warning << _("Session: XML state has no bundles section") << endmsg;
1367 /* We can't load Bundles yet as they need to be able
1368 to convert from port names to Port objects, which can't happen until
1370 _bundle_xml_node = new XMLNode (*child);
1374 if (version < 3000) {
1375 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1376 error << _("Session: XML state has no diskstreams section") << endmsg;
1378 } else if (load_diskstreams_2X (*child, version)) {
1383 if ((child = find_named_node (node, "Routes")) == 0) {
1384 error << _("Session: XML state has no routes section") << endmsg;
1386 } else if (load_routes (*child, version)) {
1390 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1391 _diskstreams_2X.clear ();
1393 if (version >= 3000) {
1395 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1396 error << _("Session: XML state has no route groups section") << endmsg;
1398 } else if (load_route_groups (*child, version)) {
1402 } else if (version < 3000) {
1404 if ((child = find_named_node (node, "EditGroups")) == 0) {
1405 error << _("Session: XML state has no edit groups section") << endmsg;
1407 } else if (load_route_groups (*child, version)) {
1411 if ((child = find_named_node (node, "MixGroups")) == 0) {
1412 error << _("Session: XML state has no mix groups section") << endmsg;
1414 } else if (load_route_groups (*child, version)) {
1419 if ((child = find_named_node (node, "Click")) == 0) {
1420 warning << _("Session: XML state has no click section") << endmsg;
1421 } else if (_click_io) {
1422 _click_io->set_state (*child, version);
1425 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1426 ControlProtocolManager::instance().set_protocol_states (*child);
1429 /* here beginneth the second phase ... */
1431 StateReady (); /* EMIT SIGNAL */
1440 Session::load_routes (const XMLNode& node, int version)
1443 XMLNodeConstIterator niter;
1444 RouteList new_routes;
1446 nlist = node.children();
1450 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1452 boost::shared_ptr<Route> route;
1453 if (version < 3000) {
1454 route = XMLRouteFactory_2X (**niter, version);
1456 route = XMLRouteFactory (**niter, version);
1460 error << _("Session: cannot create Route from XML description.") << endmsg;
1464 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1466 new_routes.push_back (route);
1469 add_routes (new_routes, false, false);
1474 boost::shared_ptr<Route>
1475 Session::XMLRouteFactory (const XMLNode& node, int version)
1477 boost::shared_ptr<Route> ret;
1479 if (node.name() != "Route") {
1483 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1485 DataType type = DataType::AUDIO;
1486 const XMLProperty* prop = node.property("default-type");
1489 type = DataType (prop->value());
1492 assert (type != DataType::NIL);
1496 boost::shared_ptr<Track> track;
1498 if (type == DataType::AUDIO) {
1499 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1501 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1504 if (track->init()) {
1508 if (track->set_state (node, version)) {
1512 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1513 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1518 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1520 if (r->init () == 0 && r->set_state (node, version) == 0) {
1521 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1522 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1531 boost::shared_ptr<Route>
1532 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1534 boost::shared_ptr<Route> ret;
1536 if (node.name() != "Route") {
1540 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1542 ds_prop = node.property (X_("diskstream"));
1545 DataType type = DataType::AUDIO;
1546 const XMLProperty* prop = node.property("default-type");
1549 type = DataType (prop->value());
1552 assert (type != DataType::NIL);
1556 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1557 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1561 if (i == _diskstreams_2X.end()) {
1562 error << _("Could not find diskstream for route") << endmsg;
1563 return boost::shared_ptr<Route> ();
1566 boost::shared_ptr<Track> track;
1568 if (type == DataType::AUDIO) {
1569 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1571 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1574 if (track->init()) {
1578 if (track->set_state (node, version)) {
1582 track->set_diskstream (*i);
1584 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1585 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1590 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1592 if (r->init () == 0 && r->set_state (node, version) == 0) {
1593 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1594 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1604 Session::load_regions (const XMLNode& node)
1607 XMLNodeConstIterator niter;
1608 boost::shared_ptr<Region> region;
1610 nlist = node.children();
1614 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1615 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1616 error << _("Session: cannot create Region from XML description.");
1617 const XMLProperty *name = (**niter).property("name");
1620 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1631 Session::load_compounds (const XMLNode& node)
1633 XMLNodeList calist = node.children();
1634 XMLNodeConstIterator caiter;
1635 XMLProperty *caprop;
1637 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1638 XMLNode* ca = *caiter;
1642 if ((caprop = ca->property (X_("original"))) == 0) {
1645 orig_id = caprop->value();
1647 if ((caprop = ca->property (X_("copy"))) == 0) {
1650 copy_id = caprop->value();
1652 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1653 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1655 if (!orig || !copy) {
1656 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1662 RegionFactory::add_compound_association (orig, copy);
1669 Session::load_nested_sources (const XMLNode& node)
1672 XMLNodeConstIterator niter;
1674 nlist = node.children();
1676 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1677 if ((*niter)->name() == "Source") {
1679 /* it may already exist, so don't recreate it unnecessarily
1682 XMLProperty* prop = (*niter)->property (X_("id"));
1684 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1688 ID source_id (prop->value());
1690 if (!source_by_id (source_id)) {
1693 SourceFactory::create (*this, **niter, true);
1695 catch (failed_constructor& err) {
1696 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1703 boost::shared_ptr<Region>
1704 Session::XMLRegionFactory (const XMLNode& node, bool full)
1706 const XMLProperty* type = node.property("type");
1710 const XMLNodeList& nlist = node.children();
1712 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1713 XMLNode *child = (*niter);
1714 if (child->name() == "NestedSource") {
1715 load_nested_sources (*child);
1719 if (!type || type->value() == "audio") {
1720 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1721 } else if (type->value() == "midi") {
1722 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1725 } catch (failed_constructor& err) {
1726 return boost::shared_ptr<Region> ();
1729 return boost::shared_ptr<Region> ();
1732 boost::shared_ptr<AudioRegion>
1733 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1735 const XMLProperty* prop;
1736 boost::shared_ptr<Source> source;
1737 boost::shared_ptr<AudioSource> as;
1739 SourceList master_sources;
1740 uint32_t nchans = 1;
1743 if (node.name() != X_("Region")) {
1744 return boost::shared_ptr<AudioRegion>();
1747 if ((prop = node.property (X_("channels"))) != 0) {
1748 nchans = atoi (prop->value().c_str());
1751 if ((prop = node.property ("name")) == 0) {
1752 cerr << "no name for this region\n";
1756 if ((prop = node.property (X_("source-0"))) == 0) {
1757 if ((prop = node.property ("source")) == 0) {
1758 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1759 return boost::shared_ptr<AudioRegion>();
1763 PBD::ID s_id (prop->value());
1765 if ((source = source_by_id (s_id)) == 0) {
1766 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1767 return boost::shared_ptr<AudioRegion>();
1770 as = boost::dynamic_pointer_cast<AudioSource>(source);
1772 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1773 return boost::shared_ptr<AudioRegion>();
1776 sources.push_back (as);
1778 /* pickup other channels */
1780 for (uint32_t n=1; n < nchans; ++n) {
1781 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1782 if ((prop = node.property (buf)) != 0) {
1784 PBD::ID id2 (prop->value());
1786 if ((source = source_by_id (id2)) == 0) {
1787 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1788 return boost::shared_ptr<AudioRegion>();
1791 as = boost::dynamic_pointer_cast<AudioSource>(source);
1793 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1794 return boost::shared_ptr<AudioRegion>();
1796 sources.push_back (as);
1800 for (uint32_t n = 0; n < nchans; ++n) {
1801 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1802 if ((prop = node.property (buf)) != 0) {
1804 PBD::ID id2 (prop->value());
1806 if ((source = source_by_id (id2)) == 0) {
1807 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1808 return boost::shared_ptr<AudioRegion>();
1811 as = boost::dynamic_pointer_cast<AudioSource>(source);
1813 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1814 return boost::shared_ptr<AudioRegion>();
1816 master_sources.push_back (as);
1821 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1823 /* a final detail: this is the one and only place that we know how long missing files are */
1825 if (region->whole_file()) {
1826 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1827 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1829 sfp->set_length (region->length());
1834 if (!master_sources.empty()) {
1835 if (master_sources.size() != nchans) {
1836 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1838 region->set_master_sources (master_sources);
1846 catch (failed_constructor& err) {
1847 return boost::shared_ptr<AudioRegion>();
1851 boost::shared_ptr<MidiRegion>
1852 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1854 const XMLProperty* prop;
1855 boost::shared_ptr<Source> source;
1856 boost::shared_ptr<MidiSource> ms;
1859 if (node.name() != X_("Region")) {
1860 return boost::shared_ptr<MidiRegion>();
1863 if ((prop = node.property ("name")) == 0) {
1864 cerr << "no name for this region\n";
1868 if ((prop = node.property (X_("source-0"))) == 0) {
1869 if ((prop = node.property ("source")) == 0) {
1870 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1871 return boost::shared_ptr<MidiRegion>();
1875 PBD::ID s_id (prop->value());
1877 if ((source = source_by_id (s_id)) == 0) {
1878 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1879 return boost::shared_ptr<MidiRegion>();
1882 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1884 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1885 return boost::shared_ptr<MidiRegion>();
1888 sources.push_back (ms);
1891 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1892 /* a final detail: this is the one and only place that we know how long missing files are */
1894 if (region->whole_file()) {
1895 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1896 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1898 sfp->set_length (region->length());
1906 catch (failed_constructor& err) {
1907 return boost::shared_ptr<MidiRegion>();
1912 Session::get_sources_as_xml ()
1915 XMLNode* node = new XMLNode (X_("Sources"));
1916 Glib::Mutex::Lock lm (source_lock);
1918 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1919 node->add_child_nocopy (i->second->get_state());
1926 Session::path_from_region_name (DataType type, string name, string identifier)
1928 char buf[PATH_MAX+1];
1930 SessionDirectory sdir(get_best_session_directory_for_new_source());
1931 sys::path source_dir = ((type == DataType::AUDIO)
1932 ? sdir.sound_path() : sdir.midi_path());
1934 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1936 for (n = 0; n < 999999; ++n) {
1937 if (identifier.length()) {
1938 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1939 identifier.c_str(), n, ext.c_str());
1941 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1945 sys::path source_path = source_dir / buf;
1947 if (!sys::exists (source_path)) {
1948 return source_path.to_string();
1952 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1961 Session::load_sources (const XMLNode& node)
1964 XMLNodeConstIterator niter;
1965 boost::shared_ptr<Source> source;
1967 nlist = node.children();
1971 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1974 if ((source = XMLSourceFactory (**niter)) == 0) {
1975 error << _("Session: cannot create Source from XML description.") << endmsg;
1978 } catch (MissingSource& err) {
1982 if (!no_questions_about_missing_files) {
1983 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1988 switch (user_choice) {
1990 /* user added a new search location, so try again */
1995 /* user asked to quit the entire session load
2000 no_questions_about_missing_files = true;
2004 no_questions_about_missing_files = true;
2009 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
2010 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2019 boost::shared_ptr<Source>
2020 Session::XMLSourceFactory (const XMLNode& node)
2022 if (node.name() != "Source") {
2023 return boost::shared_ptr<Source>();
2027 /* note: do peak building in another thread when loading session state */
2028 return SourceFactory::create (*this, node, true);
2031 catch (failed_constructor& err) {
2032 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2033 return boost::shared_ptr<Source>();
2038 Session::save_template (string template_name)
2042 if (_state_of_the_state & CannotSave) {
2046 sys::path user_template_dir(user_template_directory());
2050 sys::create_directories (user_template_dir);
2052 catch(sys::filesystem_error& ex)
2054 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2055 user_template_dir.to_string(), ex.what()) << endmsg;
2059 tree.set_root (&get_template());
2061 sys::path template_dir_path(user_template_dir);
2063 /* directory to put the template in */
2064 template_dir_path /= template_name;
2065 if (sys::exists (template_dir_path))
2067 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2068 template_dir_path.to_string()) << endmsg;
2072 sys::create_directories (template_dir_path);
2075 sys::path template_file_path = template_dir_path;
2076 template_file_path /= template_name + template_suffix;
2078 if (!tree.write (template_file_path.to_string())) {
2079 error << _("template not saved") << endmsg;
2083 /* copy plugin state directory */
2085 sys::path template_plugin_state_path = template_dir_path;
2086 template_plugin_state_path /= X_("plugins");
2087 sys::create_directories (template_plugin_state_path);
2088 sys::copy_files (plugins_dir(), template_plugin_state_path);
2094 Session::refresh_disk_space ()
2097 struct statfs statfsbuf;
2098 vector<space_and_path>::iterator i;
2099 Glib::Mutex::Lock lm (space_lock);
2102 /* get freespace on every FS that is part of the session path */
2104 _total_free_4k_blocks = 0;
2106 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2107 statfs ((*i).path.c_str(), &statfsbuf);
2109 scale = statfsbuf.f_bsize/4096.0;
2111 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2112 _total_free_4k_blocks += (*i).blocks;
2118 Session::get_best_session_directory_for_new_source ()
2120 vector<space_and_path>::iterator i;
2121 string result = _session_dir->root_path().to_string();
2123 /* handle common case without system calls */
2125 if (session_dirs.size() == 1) {
2129 /* OK, here's the algorithm we're following here:
2131 We want to select which directory to use for
2132 the next file source to be created. Ideally,
2133 we'd like to use a round-robin process so as to
2134 get maximum performance benefits from splitting
2135 the files across multiple disks.
2137 However, in situations without much diskspace, an
2138 RR approach may end up filling up a filesystem
2139 with new files while others still have space.
2140 Its therefore important to pay some attention to
2141 the freespace in the filesystem holding each
2142 directory as well. However, if we did that by
2143 itself, we'd keep creating new files in the file
2144 system with the most space until it was as full
2145 as all others, thus negating any performance
2146 benefits of this RAID-1 like approach.
2148 So, we use a user-configurable space threshold. If
2149 there are at least 2 filesystems with more than this
2150 much space available, we use RR selection between them.
2151 If not, then we pick the filesystem with the most space.
2153 This gets a good balance between the two
2157 refresh_disk_space ();
2159 int free_enough = 0;
2161 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2162 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2167 if (free_enough >= 2) {
2168 /* use RR selection process, ensuring that the one
2172 i = last_rr_session_dir;
2175 if (++i == session_dirs.end()) {
2176 i = session_dirs.begin();
2179 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2180 if (create_session_directory ((*i).path)) {
2182 last_rr_session_dir = i;
2187 } while (i != last_rr_session_dir);
2191 /* pick FS with the most freespace (and that
2192 seems to actually work ...)
2195 vector<space_and_path> sorted;
2196 space_and_path_ascending_cmp cmp;
2198 sorted = session_dirs;
2199 sort (sorted.begin(), sorted.end(), cmp);
2201 for (i = sorted.begin(); i != sorted.end(); ++i) {
2202 if (create_session_directory ((*i).path)) {
2204 last_rr_session_dir = i;
2214 Session::load_named_selections (const XMLNode& node)
2217 XMLNodeConstIterator niter;
2220 nlist = node.children();
2224 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2226 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2227 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2235 Session::XMLNamedSelectionFactory (const XMLNode& node)
2238 return new NamedSelection (*this, node);
2241 catch (failed_constructor& err) {
2247 Session::automation_dir () const
2249 return Glib::build_filename (_path, "automation");
2253 Session::analysis_dir () const
2255 return Glib::build_filename (_path, "analysis");
2259 Session::plugins_dir () const
2261 return Glib::build_filename (_path, "plugins");
2265 Session::load_bundles (XMLNode const & node)
2267 XMLNodeList nlist = node.children();
2268 XMLNodeConstIterator niter;
2272 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2273 if ((*niter)->name() == "InputBundle") {
2274 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2275 } else if ((*niter)->name() == "OutputBundle") {
2276 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2278 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2287 Session::load_route_groups (const XMLNode& node, int version)
2289 XMLNodeList nlist = node.children();
2290 XMLNodeConstIterator niter;
2294 if (version >= 3000) {
2296 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2297 if ((*niter)->name() == "RouteGroup") {
2298 RouteGroup* rg = new RouteGroup (*this, "");
2299 add_route_group (rg);
2300 rg->set_state (**niter, version);
2304 } else if (version < 3000) {
2306 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2307 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2308 RouteGroup* rg = new RouteGroup (*this, "");
2309 add_route_group (rg);
2310 rg->set_state (**niter, version);
2319 Session::auto_save()
2321 save_state (_current_snapshot_name);
2325 state_file_filter (const string &str, void */*arg*/)
2327 return (str.length() > strlen(statefile_suffix) &&
2328 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2332 bool operator()(const string* a, const string* b) {
2338 remove_end(string* state)
2340 string statename(*state);
2342 string::size_type start,end;
2343 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2344 statename = statename.substr (start+1);
2347 if ((end = statename.rfind(".ardour")) == string::npos) {
2348 end = statename.length();
2351 return new string(statename.substr (0, end));
2355 Session::possible_states (string path)
2357 PathScanner scanner;
2358 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2360 transform(states->begin(), states->end(), states->begin(), remove_end);
2363 sort (states->begin(), states->end(), cmp);
2369 Session::possible_states () const
2371 return possible_states(_path);
2375 Session::add_route_group (RouteGroup* g)
2377 _route_groups.push_back (g);
2378 route_group_added (g); /* EMIT SIGNAL */
2380 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2381 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2382 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2388 Session::remove_route_group (RouteGroup& rg)
2390 list<RouteGroup*>::iterator i;
2392 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2393 _route_groups.erase (i);
2396 route_group_removed (); /* EMIT SIGNAL */
2400 /** Set a new order for our route groups, without adding or removing any.
2401 * @param groups Route group list in the new order.
2404 Session::reorder_route_groups (list<RouteGroup*> groups)
2406 _route_groups = groups;
2408 route_groups_reordered (); /* EMIT SIGNAL */
2414 Session::route_group_by_name (string name)
2416 list<RouteGroup *>::iterator i;
2418 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2419 if ((*i)->name() == name) {
2427 Session::all_route_group() const
2429 return *_all_route_group;
2433 Session::add_commands (vector<Command*> const & cmds)
2435 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2441 Session::begin_reversible_command (const string& name)
2443 begin_reversible_command (g_quark_from_string (name.c_str ()));
2446 /** Begin a reversible command using a GQuark to identify it.
2447 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2448 * but there must be as many begin...()s as there are commit...()s.
2451 Session::begin_reversible_command (GQuark q)
2453 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2454 to hold all the commands that are committed. This keeps the order of
2455 commands correct in the history.
2458 if (_current_trans == 0) {
2459 /* start a new transaction */
2460 assert (_current_trans_quarks.empty ());
2461 _current_trans = new UndoTransaction();
2462 _current_trans->set_name (g_quark_to_string (q));
2465 _current_trans_quarks.push_front (q);
2469 Session::commit_reversible_command (Command *cmd)
2471 assert (_current_trans);
2472 assert (!_current_trans_quarks.empty ());
2477 _current_trans->add_command (cmd);
2480 _current_trans_quarks.pop_front ();
2482 if (!_current_trans_quarks.empty ()) {
2483 /* the transaction we're committing is not the top-level one */
2487 if (_current_trans->empty()) {
2488 /* no commands were added to the transaction, so just get rid of it */
2489 delete _current_trans;
2494 gettimeofday (&now, 0);
2495 _current_trans->set_timestamp (now);
2497 _history.add (_current_trans);
2502 accept_all_audio_files (const string& path, void */*arg*/)
2504 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2508 if (!AudioFileSource::safe_audio_file_extension (path)) {
2516 accept_all_midi_files (const string& path, void */*arg*/)
2518 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2522 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2523 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2524 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2528 accept_all_state_files (const string& path, void */*arg*/)
2530 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2534 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2538 Session::find_all_sources (string path, set<string>& result)
2543 if (!tree.read (path)) {
2547 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2552 XMLNodeConstIterator niter;
2554 nlist = node->children();
2558 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2562 if ((prop = (*niter)->property (X_("type"))) == 0) {
2566 DataType type (prop->value());
2568 if ((prop = (*niter)->property (X_("name"))) == 0) {
2572 if (Glib::path_is_absolute (prop->value())) {
2573 /* external file, ignore */
2581 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2582 result.insert (found_path);
2590 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2592 PathScanner scanner;
2593 vector<string*>* state_files;
2595 string this_snapshot_path;
2601 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2602 ripped = ripped.substr (0, ripped.length() - 1);
2605 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2607 if (state_files == 0) {
2612 this_snapshot_path = _path;
2613 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2614 this_snapshot_path += statefile_suffix;
2616 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2618 if (exclude_this_snapshot && **i == this_snapshot_path) {
2622 if (find_all_sources (**i, result) < 0) {
2630 struct RegionCounter {
2631 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2632 AudioSourceList::iterator iter;
2633 boost::shared_ptr<Region> region;
2636 RegionCounter() : count (0) {}
2640 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2642 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2643 return r.get_value_or (1);
2647 Session::cleanup_regions ()
2649 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2651 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2653 uint32_t used = playlists->region_use_count (i->second);
2655 if (used == 0 && !i->second->automatic ()) {
2656 RegionFactory::map_remove (i->second);
2660 /* dump the history list */
2667 Session::cleanup_sources (CleanupReport& rep)
2669 // FIXME: needs adaptation to midi
2671 vector<boost::shared_ptr<Source> > dead_sources;
2672 PathScanner scanner;
2675 vector<space_and_path>::iterator i;
2676 vector<space_and_path>::iterator nexti;
2677 vector<string*>* candidates;
2678 vector<string*>* candidates2;
2679 vector<string> unused;
2680 set<string> all_sources;
2685 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2687 /* consider deleting all unused playlists */
2689 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2694 /* sync the "all regions" property of each playlist with its current state
2697 playlists->sync_all_regions_with_regions ();
2699 /* find all un-used sources */
2704 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2706 SourceMap::iterator tmp;
2711 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2715 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2716 dead_sources.push_back (i->second);
2717 i->second->drop_references ();
2723 /* build a list of all the possible audio directories for the session */
2725 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2730 SessionDirectory sdir ((*i).path);
2731 audio_path += sdir.sound_path().to_string();
2733 if (nexti != session_dirs.end()) {
2741 /* build a list of all the possible midi directories for the session */
2743 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2748 SessionDirectory sdir ((*i).path);
2749 midi_path += sdir.midi_path().to_string();
2751 if (nexti != session_dirs.end()) {
2758 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2759 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2765 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2766 candidates->push_back (*i);
2771 candidates = candidates2; // might still be null
2774 /* find all sources, but don't use this snapshot because the
2775 state file on disk still references sources we may have already
2779 find_all_sources_across_snapshots (all_sources, true);
2781 /* add our current source list
2784 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2785 boost::shared_ptr<FileSource> fs;
2786 SourceMap::iterator tmp = i;
2789 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2790 if (playlists->source_use_count (fs) != 0) {
2791 all_sources.insert (fs->path());
2794 /* we might not remove this source from disk, because it may be used
2795 by other snapshots, but its not being used in this version
2796 so lets get rid of it now, along with any representative regions
2800 RegionFactory::remove_regions_using_source (i->second);
2808 char tmppath1[PATH_MAX+1];
2809 char tmppath2[PATH_MAX+1];
2812 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2817 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2819 if (realpath(spath.c_str(), tmppath1) == 0) {
2820 error << string_compose (_("Cannot expand path %1 (%2)"),
2821 spath, strerror (errno)) << endmsg;
2825 if (realpath((*i).c_str(), tmppath2) == 0) {
2826 error << string_compose (_("Cannot expand path %1 (%2)"),
2827 (*i), strerror (errno)) << endmsg;
2831 if (strcmp(tmppath1, tmppath2) == 0) {
2838 unused.push_back (spath);
2847 /* now try to move all unused files into the "dead" directory(ies) */
2849 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2850 struct stat statbuf;
2854 /* don't move the file across filesystems, just
2855 stick it in the `dead_dir_name' directory
2856 on whichever filesystem it was already on.
2859 if ((*x).find ("/sounds/") != string::npos) {
2861 /* old school, go up 1 level */
2863 newpath = Glib::path_get_dirname (*x); // "sounds"
2864 newpath = Glib::path_get_dirname (newpath); // "session-name"
2868 /* new school, go up 4 levels */
2870 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2871 newpath = Glib::path_get_dirname (newpath); // "session-name"
2872 newpath = Glib::path_get_dirname (newpath); // "interchange"
2873 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2876 newpath = Glib::build_filename (newpath, dead_dir_name);
2878 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2879 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2883 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2885 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2887 /* the new path already exists, try versioning */
2889 char buf[PATH_MAX+1];
2893 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2896 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2897 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2901 if (version == 999) {
2902 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2906 newpath = newpath_v;
2911 /* it doesn't exist, or we can't read it or something */
2915 stat ((*x).c_str(), &statbuf);
2917 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2918 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2919 (*x), newpath, strerror (errno))
2924 /* see if there an easy to find peakfile for this file, and remove it.
2927 string base = basename_nosuffix (*x);
2928 base += "%A"; /* this is what we add for the channel suffix of all native files,
2929 or for the first channel of embedded files. it will miss
2930 some peakfiles for other channels
2932 string peakpath = peak_path (base);
2934 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2935 if (::unlink (peakpath.c_str()) != 0) {
2936 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2937 peakpath, _path, strerror (errno))
2939 /* try to back out */
2940 ::rename (newpath.c_str(), _path.c_str());
2945 rep.paths.push_back (*x);
2946 rep.space += statbuf.st_size;
2949 /* dump the history list */
2953 /* save state so we don't end up a session file
2954 referring to non-existent sources.
2961 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2967 Session::cleanup_trash_sources (CleanupReport& rep)
2969 // FIXME: needs adaptation for MIDI
2971 vector<space_and_path>::iterator i;
2977 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2979 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2981 clear_directory (dead_dir, &rep.space, &rep.paths);
2988 Session::set_dirty ()
2990 bool was_dirty = dirty();
2992 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2996 DirtyChanged(); /* EMIT SIGNAL */
3002 Session::set_clean ()
3004 bool was_dirty = dirty();
3006 _state_of_the_state = Clean;
3010 DirtyChanged(); /* EMIT SIGNAL */
3015 Session::set_deletion_in_progress ()
3017 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3021 Session::clear_deletion_in_progress ()
3023 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3027 Session::add_controllable (boost::shared_ptr<Controllable> c)
3029 /* this adds a controllable to the list managed by the Session.
3030 this is a subset of those managed by the Controllable class
3031 itself, and represents the only ones whose state will be saved
3032 as part of the session.
3035 Glib::Mutex::Lock lm (controllables_lock);
3036 controllables.insert (c);
3039 struct null_deleter { void operator()(void const *) const {} };
3042 Session::remove_controllable (Controllable* c)
3044 if (_state_of_the_state | Deletion) {
3048 Glib::Mutex::Lock lm (controllables_lock);
3050 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3052 if (x != controllables.end()) {
3053 controllables.erase (x);
3057 boost::shared_ptr<Controllable>
3058 Session::controllable_by_id (const PBD::ID& id)
3060 Glib::Mutex::Lock lm (controllables_lock);
3062 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3063 if ((*i)->id() == id) {
3068 return boost::shared_ptr<Controllable>();
3071 boost::shared_ptr<Controllable>
3072 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3074 boost::shared_ptr<Controllable> c;
3075 boost::shared_ptr<Route> r;
3077 switch (desc.top_level_type()) {
3078 case ControllableDescriptor::NamedRoute:
3080 std::string str = desc.top_level_name();
3081 if (str == "master") {
3083 } else if (str == "control" || str == "listen") {
3086 r = route_by_name (desc.top_level_name());
3091 case ControllableDescriptor::RemoteControlID:
3092 r = route_by_remote_id (desc.rid());
3100 switch (desc.subtype()) {
3101 case ControllableDescriptor::Gain:
3102 c = r->gain_control ();
3105 case ControllableDescriptor::Solo:
3106 c = r->solo_control();
3109 case ControllableDescriptor::Mute:
3110 c = r->mute_control();
3113 case ControllableDescriptor::Recenable:
3115 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3118 c = t->rec_enable_control ();
3123 case ControllableDescriptor::PanDirection:
3125 c = r->pannable()->pan_azimuth_control;
3129 case ControllableDescriptor::PanWidth:
3131 c = r->pannable()->pan_width_control;
3135 case ControllableDescriptor::PanElevation:
3137 c = r->pannable()->pan_elevation_control;
3141 case ControllableDescriptor::Balance:
3142 /* XXX simple pan control */
3145 case ControllableDescriptor::PluginParameter:
3147 uint32_t plugin = desc.target (0);
3148 uint32_t parameter_index = desc.target (1);
3150 /* revert to zero based counting */
3156 if (parameter_index > 0) {
3160 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3163 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3164 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3169 case ControllableDescriptor::SendGain:
3171 uint32_t send = desc.target (0);
3173 /* revert to zero-based counting */
3179 boost::shared_ptr<Processor> p = r->nth_send (send);
3182 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3183 boost::shared_ptr<Amp> a = s->amp();
3186 c = s->amp()->gain_control();
3193 /* relax and return a null pointer */
3201 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3204 Stateful::add_instant_xml (node, _path);
3207 if (write_to_config) {
3208 Config->add_instant_xml (node);
3213 Session::instant_xml (const string& node_name)
3215 return Stateful::instant_xml (node_name, _path);
3219 Session::save_history (string snapshot_name)
3227 if (snapshot_name.empty()) {
3228 snapshot_name = _current_snapshot_name;
3231 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3232 const string backup_filename = history_filename + backup_suffix;
3233 const sys::path xml_path = _session_dir->root_path() / history_filename;
3234 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3236 if (sys::exists (xml_path)) {
3239 sys::rename (xml_path, backup_path);
3241 catch (const sys::filesystem_error& err)
3243 error << _("could not backup old history file, current history not saved") << endmsg;
3248 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3252 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3254 if (!tree.write (xml_path.to_string()))
3256 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3260 sys::remove (xml_path);
3261 sys::rename (backup_path, xml_path);
3263 catch (const sys::filesystem_error& err)
3265 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3266 backup_path.to_string(), err.what()) << endmsg;
3276 Session::restore_history (string snapshot_name)
3280 if (snapshot_name.empty()) {
3281 snapshot_name = _current_snapshot_name;
3284 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3285 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3287 info << "Loading history from " << xml_path.to_string() << endmsg;
3289 if (!sys::exists (xml_path)) {
3290 info << string_compose (_("%1: no history file \"%2\" for this session."),
3291 _name, xml_path.to_string()) << endmsg;
3295 if (!tree.read (xml_path.to_string())) {
3296 error << string_compose (_("Could not understand session history file \"%1\""),
3297 xml_path.to_string()) << endmsg;
3304 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3307 UndoTransaction* ut = new UndoTransaction ();
3310 ut->set_name(t->property("name")->value());
3311 stringstream ss(t->property("tv-sec")->value());
3313 ss.str(t->property("tv-usec")->value());
3315 ut->set_timestamp(tv);
3317 for (XMLNodeConstIterator child_it = t->children().begin();
3318 child_it != t->children().end(); child_it++)
3320 XMLNode *n = *child_it;
3323 if (n->name() == "MementoCommand" ||
3324 n->name() == "MementoUndoCommand" ||
3325 n->name() == "MementoRedoCommand") {
3327 if ((c = memento_command_factory(n))) {
3331 } else if (n->name() == "NoteDiffCommand") {
3332 PBD::ID id (n->property("midi-source")->value());
3333 boost::shared_ptr<MidiSource> midi_source =
3334 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3336 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3338 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3341 } else if (n->name() == "SysExDiffCommand") {
3343 PBD::ID id (n->property("midi-source")->value());
3344 boost::shared_ptr<MidiSource> midi_source =
3345 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3347 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3349 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3352 } else if (n->name() == "PatchChangeDiffCommand") {
3354 PBD::ID id (n->property("midi-source")->value());
3355 boost::shared_ptr<MidiSource> midi_source =
3356 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3358 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3360 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3363 } else if (n->name() == "StatefulDiffCommand") {
3364 if ((c = stateful_diff_command_factory (n))) {
3365 ut->add_command (c);
3368 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3379 Session::config_changed (std::string p, bool ours)
3385 if (p == "seamless-loop") {
3387 } else if (p == "rf-speed") {
3389 } else if (p == "auto-loop") {
3391 } else if (p == "auto-input") {
3393 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3394 /* auto-input only makes a difference if we're rolling */
3395 set_track_monitor_input_status (!config.get_auto_input());
3398 } else if (p == "punch-in") {
3402 if ((location = _locations->auto_punch_location()) != 0) {
3404 if (config.get_punch_in ()) {
3405 replace_event (SessionEvent::PunchIn, location->start());
3407 remove_event (location->start(), SessionEvent::PunchIn);
3411 } else if (p == "punch-out") {
3415 if ((location = _locations->auto_punch_location()) != 0) {
3417 if (config.get_punch_out()) {
3418 replace_event (SessionEvent::PunchOut, location->end());
3420 clear_events (SessionEvent::PunchOut);
3424 } else if (p == "edit-mode") {
3426 Glib::Mutex::Lock lm (playlists->lock);
3428 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3429 (*i)->set_edit_mode (Config->get_edit_mode ());
3432 } else if (p == "use-video-sync") {
3434 waiting_for_sync_offset = config.get_use_video_sync();
3436 } else if (p == "mmc-control") {
3438 //poke_midi_thread ();
3440 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3442 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3444 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3446 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3448 } else if (p == "midi-control") {
3450 //poke_midi_thread ();
3452 } else if (p == "raid-path") {
3454 setup_raid_path (config.get_raid_path());
3456 } else if (p == "timecode-format") {
3460 } else if (p == "video-pullup") {
3464 } else if (p == "seamless-loop") {
3466 if (play_loop && transport_rolling()) {
3467 // to reset diskstreams etc
3468 request_play_loop (true);
3471 } else if (p == "rf-speed") {
3473 cumulative_rf_motion = 0;
3476 } else if (p == "click-sound") {
3478 setup_click_sounds (1);
3480 } else if (p == "click-emphasis-sound") {
3482 setup_click_sounds (-1);
3484 } else if (p == "clicking") {
3486 if (Config->get_clicking()) {
3487 if (_click_io && click_data) { // don't require emphasis data
3494 } else if (p == "send-mtc") {
3496 if (Config->get_send_mtc ()) {
3497 /* mark us ready to send */
3498 next_quarter_frame_to_send = 0;
3501 } else if (p == "send-mmc") {
3503 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3505 } else if (p == "midi-feedback") {
3507 session_midi_feedback = Config->get_midi_feedback();
3509 } else if (p == "jack-time-master") {
3511 engine().reset_timebase ();
3513 } else if (p == "native-file-header-format") {
3515 if (!first_file_header_format_reset) {
3516 reset_native_file_format ();
3519 first_file_header_format_reset = false;
3521 } else if (p == "native-file-data-format") {
3523 if (!first_file_data_format_reset) {
3524 reset_native_file_format ();
3527 first_file_data_format_reset = false;
3529 } else if (p == "external-sync") {
3530 if (!config.get_external_sync()) {
3531 drop_sync_source ();
3533 switch_to_sync_source (config.get_sync_source());
3535 } else if (p == "remote-model") {
3536 set_remote_control_ids ();
3537 } else if (p == "denormal-model") {
3539 } else if (p == "history-depth") {
3540 set_history_depth (Config->get_history_depth());
3541 } else if (p == "sync-all-route-ordering") {
3542 sync_order_keys ("session");
3543 } else if (p == "initial-program-change") {
3545 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3548 buf[0] = MIDI::program; // channel zero by default
3549 buf[1] = (Config->get_initial_program_change() & 0x7f);
3551 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3553 } else if (p == "solo-mute-override") {
3554 // catch_up_on_solo_mute_override ();
3555 } else if (p == "listen-position" || p == "pfl-position") {
3556 listen_position_changed ();
3557 } else if (p == "solo-control-is-listen-control") {
3558 solo_control_mode_changed ();
3559 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3560 last_timecode_valid = false;
3561 } else if (p == "playback-buffer-seconds") {
3562 AudioSource::allocate_working_buffers (frame_rate());
3569 Session::set_history_depth (uint32_t d)
3571 _history.set_depth (d);
3575 Session::load_diskstreams_2X (XMLNode const & node, int)
3578 XMLNodeConstIterator citer;
3580 clist = node.children();
3582 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3585 /* diskstreams added automatically by DiskstreamCreated handler */
3586 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3587 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3588 _diskstreams_2X.push_back (dsp);
3590 error << _("Session: unknown diskstream type in XML") << endmsg;
3594 catch (failed_constructor& err) {
3595 error << _("Session: could not load diskstream via XML state") << endmsg;
3603 /** Connect things to the MMC object */
3605 Session::setup_midi_machine_control ()
3607 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3609 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3610 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3611 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3612 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3613 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3614 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3615 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3616 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3617 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3618 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3619 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3620 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3621 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3623 /* also handle MIDI SPP because its so common */
3625 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3626 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3627 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));
3630 boost::shared_ptr<Controllable>
3631 Session::solo_cut_control() const
3633 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3634 controls in Ardour that currently get presented to the user in the GUI that require
3635 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3637 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3638 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3642 return _solo_cut_control;
3646 Session::rename (const std::string& new_name)
3648 string legal_name = legalize_for_path (new_name);
3654 string const old_sources_root = _session_dir->sources_root().to_string ();
3656 #define RENAME ::rename
3661 * interchange subdirectory
3665 * Backup files are left unchanged and not renamed.
3668 /* pass one: not 100% safe check that the new directory names don't
3672 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3677 /* this is a stupid hack because Glib::path_get_dirname() is
3678 * lexical-only, and so passing it /a/b/c/ gives a different
3679 * result than passing it /a/b/c ...
3682 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3683 oldstr = oldstr.substr (0, oldstr.length() - 1);
3686 string base = Glib::path_get_dirname (oldstr);
3687 string p = Glib::path_get_basename (oldstr);
3689 newstr = Glib::build_filename (base, legal_name);
3691 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3698 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3703 /* this is a stupid hack because Glib::path_get_dirname() is
3704 * lexical-only, and so passing it /a/b/c/ gives a different
3705 * result than passing it /a/b/c ...
3708 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3709 oldstr = oldstr.substr (0, oldstr.length() - 1);
3712 string base = Glib::path_get_dirname (oldstr);
3713 string p = Glib::path_get_basename (oldstr);
3715 newstr = Glib::build_filename (base, legal_name);
3717 cerr << "Rename " << oldstr << " => " << newstr << endl;
3719 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3724 (*_session_dir) = newstr;
3729 /* directory below interchange */
3731 v.push_back (newstr);
3732 v.push_back (interchange_dir_name);
3735 oldstr = Glib::build_filename (v);
3738 v.push_back (newstr);
3739 v.push_back (interchange_dir_name);
3740 v.push_back (legal_name);
3742 newstr = Glib::build_filename (v);
3744 cerr << "Rename " << oldstr << " => " << newstr << endl;
3746 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3753 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3754 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3756 cerr << "Rename " << oldstr << " => " << newstr << endl;
3758 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3765 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3767 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3768 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3770 cerr << "Rename " << oldstr << " => " << newstr << endl;
3772 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3777 /* update file source paths */
3779 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3780 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3782 string p = fs->path ();
3783 boost::replace_all (p, old_sources_root, _session_dir->sources_root().to_string ());
3788 /* remove old name from recent sessions */
3790 remove_recent_sessions (_path);
3793 _current_snapshot_name = new_name;
3798 /* save state again to get everything just right */
3800 save_state (_current_snapshot_name);
3803 /* add to recent sessions */
3805 store_recent_sessions (new_name, _path);