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"
33 #include <cstdio> /* snprintf(3) ... grrr */
47 #include <sys/param.h>
48 #include <sys/mount.h>
52 #include <glibmm/thread.h>
54 #include "midi++/mmc.h"
55 #include "midi++/port.h"
56 #include "midi++/manager.h"
58 #include "pbd/boost_debug.h"
59 #include "pbd/basename.h"
60 #include "pbd/controllable_descriptor.h"
61 #include "pbd/enumwriter.h"
62 #include "pbd/error.h"
63 #include "pbd/pathscanner.h"
64 #include "pbd/pthread_utils.h"
65 #include "pbd/search_path.h"
66 #include "pbd/stacktrace.h"
67 #include "pbd/convert.h"
68 #include "pbd/clear_dir.h"
70 #include "ardour/amp.h"
71 #include "ardour/audio_diskstream.h"
72 #include "ardour/audio_track.h"
73 #include "ardour/audioengine.h"
74 #include "ardour/audiofilesource.h"
75 #include "ardour/audioplaylist.h"
76 #include "ardour/audioregion.h"
77 #include "ardour/auditioner.h"
78 #include "ardour/automation_control.h"
79 #include "ardour/buffer.h"
80 #include "ardour/butler.h"
81 #include "ardour/configuration.h"
82 #include "ardour/control_protocol_manager.h"
83 #include "ardour/crossfade.h"
84 #include "ardour/cycle_timer.h"
85 #include "ardour/directory_names.h"
86 #include "ardour/filename_extensions.h"
87 #include "ardour/io_processor.h"
88 #include "ardour/location.h"
89 #include "ardour/midi_diskstream.h"
90 #include "ardour/midi_patch_manager.h"
91 #include "ardour/midi_playlist.h"
92 #include "ardour/midi_region.h"
93 #include "ardour/midi_source.h"
94 #include "ardour/midi_track.h"
95 #include "ardour/named_selection.h"
96 #include "ardour/pannable.h"
97 #include "ardour/processor.h"
98 #include "ardour/port.h"
99 #include "ardour/proxy_controllable.h"
100 #include "ardour/region_factory.h"
101 #include "ardour/route_group.h"
102 #include "ardour/send.h"
103 #include "ardour/session.h"
104 #include "ardour/session_directory.h"
105 #include "ardour/session_metadata.h"
106 #include "ardour/session_state_utils.h"
107 #include "ardour/session_playlists.h"
108 #include "ardour/session_utils.h"
109 #include "ardour/silentfilesource.h"
110 #include "ardour/slave.h"
111 #include "ardour/smf_source.h"
112 #include "ardour/sndfile_helpers.h"
113 #include "ardour/sndfilesource.h"
114 #include "ardour/source_factory.h"
115 #include "ardour/template_utils.h"
116 #include "ardour/tempo.h"
117 #include "ardour/ticker.h"
118 #include "ardour/user_bundle.h"
119 #include "ardour/utils.h"
120 #include "ardour/utils.h"
121 #include "ardour/version.h"
122 #include "ardour/playlist_factory.h"
124 #include "control_protocol/control_protocol.h"
130 using namespace ARDOUR;
134 Session::first_stage_init (string fullpath, string snapshot_name)
136 if (fullpath.length() == 0) {
138 throw failed_constructor();
141 char buf[PATH_MAX+1];
142 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
143 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
145 throw failed_constructor();
150 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
151 _path += G_DIR_SEPARATOR;
154 if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
160 /* these two are just provisional settings. set_state()
161 will likely override them.
164 _name = _current_snapshot_name = snapshot_name;
166 set_history_depth (Config->get_history_depth());
168 _current_frame_rate = _engine.frame_rate ();
169 _nominal_frame_rate = _current_frame_rate;
170 _base_frame_rate = _current_frame_rate;
172 _tempo_map = new TempoMap (_current_frame_rate);
173 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
176 _non_soloed_outs_muted = false;
178 _solo_isolated_cnt = 0;
179 g_atomic_int_set (&processing_prohibited, 0);
180 _transport_speed = 0;
181 _last_transport_speed = 0;
182 _target_transport_speed = 0;
183 auto_play_legal = false;
184 transport_sub_state = 0;
185 _transport_frame = 0;
186 _requested_return_frame = -1;
187 _session_range_location = 0;
188 g_atomic_int_set (&_record_status, Disabled);
189 loop_changing = false;
192 _last_roll_location = 0;
193 _last_roll_or_reversal_location = 0;
194 _last_record_location = 0;
195 pending_locate_frame = 0;
196 pending_locate_roll = false;
197 pending_locate_flush = false;
198 state_was_pending = false;
200 outbound_mtc_timecode_frame = 0;
201 next_quarter_frame_to_send = -1;
202 current_block_size = 0;
203 solo_update_disabled = false;
204 _have_captured = false;
205 _worst_output_latency = 0;
206 _worst_input_latency = 0;
207 _worst_track_latency = 0;
208 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
209 _was_seamless = Config->get_seamless_loop ();
211 _send_qf_mtc = false;
212 _pframes_since_last_mtc = 0;
213 g_atomic_int_set (&_playback_load, 100);
214 g_atomic_int_set (&_capture_load, 100);
217 pending_abort = false;
218 destructive_index = 0;
219 first_file_data_format_reset = true;
220 first_file_header_format_reset = true;
221 post_export_sync = false;
224 no_questions_about_missing_files = false;
225 _speakers.reset (new Speakers);
227 AudioDiskstream::allocate_working_buffers();
229 /* default short fade = 15ms */
231 Crossfade::set_short_xfade_length ((framecnt_t) floor (config.get_short_xfade_seconds() * frame_rate()));
232 SndFileSource::setup_standard_crossfades (*this, frame_rate());
234 last_mmc_step.tv_sec = 0;
235 last_mmc_step.tv_usec = 0;
238 /* click sounds are unset by default, which causes us to internal
239 waveforms for clicks.
243 click_emphasis_length = 0;
246 process_function = &Session::process_with_events;
248 if (config.get_use_video_sync()) {
249 waiting_for_sync_offset = true;
251 waiting_for_sync_offset = false;
254 last_timecode_when = 0;
255 last_timecode_valid = false;
259 last_rr_session_dir = session_dirs.begin();
260 refresh_disk_space ();
262 /* default: assume simple stereo speaker configuration */
264 _speakers->setup_default_speakers (2);
268 average_slave_delta = 1800; // !!! why 1800 ????
269 have_first_delta_accumulator = false;
270 delta_accumulator_cnt = 0;
271 _slave_state = Stopped;
273 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
274 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
275 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
276 add_controllable (_solo_cut_control);
278 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
280 /* These are all static "per-class" signals */
282 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
283 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
284 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
285 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
286 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
288 /* stop IO objects from doing stuff until we're ready for them */
290 Delivery::disable_panners ();
291 IO::disable_connecting ();
295 Session::second_stage_init ()
297 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
300 if (load_state (_current_snapshot_name)) {
305 if (_butler->start_thread()) {
309 if (start_midi_thread ()) {
313 setup_midi_machine_control ();
315 // set_state() will call setup_raid_path(), but if it's a new session we need
316 // to call setup_raid_path() here.
319 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
323 setup_raid_path(_path);
326 /* we can't save till after ::when_engine_running() is called,
327 because otherwise we save state with no connections made.
328 therefore, we reset _state_of_the_state because ::set_state()
329 will have cleared it.
331 we also have to include Loading so that any events that get
332 generated between here and the end of ::when_engine_running()
333 will be processed directly rather than queued.
336 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
338 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
339 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
340 setup_click_sounds (0);
341 setup_midi_control ();
343 /* Pay attention ... */
345 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
346 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
349 when_engine_running ();
352 /* handle this one in a different way than all others, so that its clear what happened */
354 catch (AudioEngine::PortRegistrationFailure& err) {
355 error << err.what() << endmsg;
363 BootMessage (_("Reset Remote Controls"));
365 send_full_time_code (0);
366 _engine.transport_locate (0);
368 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
369 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
371 MidiClockTicker::instance().set_session (this);
372 MIDI::Name::MidiPatchManager::instance().set_session (this);
374 /* initial program change will be delivered later; see ::config_changed() */
376 BootMessage (_("Reset Control Protocols"));
378 ControlProtocolManager::instance().set_session (this);
380 _state_of_the_state = Clean;
382 Port::set_connecting_blocked (false);
384 DirtyChanged (); /* EMIT SIGNAL */
386 if (state_was_pending) {
387 save_state (_current_snapshot_name);
388 remove_pending_capture_state ();
389 state_was_pending = false;
392 BootMessage (_("Session loading complete"));
398 Session::raid_path () const
400 SearchPath raid_search_path;
402 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
403 raid_search_path += sys::path((*i).path);
406 return raid_search_path.to_string ();
410 Session::setup_raid_path (string path)
419 session_dirs.clear ();
421 SearchPath search_path(path);
422 SearchPath sound_search_path;
423 SearchPath midi_search_path;
425 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
426 sp.path = (*i).to_string ();
427 sp.blocks = 0; // not needed
428 session_dirs.push_back (sp);
430 SessionDirectory sdir(sp.path);
432 sound_search_path += sdir.sound_path ();
433 midi_search_path += sdir.midi_path ();
436 // reset the round-robin soundfile path thingie
437 last_rr_session_dir = session_dirs.begin();
441 Session::path_is_within_session (const std::string& path)
443 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
444 if (path.find ((*i).path) == 0) {
452 Session::ensure_subdirs ()
456 dir = session_directory().peak_path().to_string();
458 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
459 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
463 dir = session_directory().sound_path().to_string();
465 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
466 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
470 dir = session_directory().midi_path().to_string();
472 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
473 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
477 dir = session_directory().dead_path().to_string();
479 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
480 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
484 dir = session_directory().export_path().to_string();
486 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
487 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
491 dir = analysis_dir ();
493 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
494 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
498 dir = plugins_dir ();
500 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
501 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
508 /** Caller must not hold process lock */
510 Session::create (const string& mix_template, BusProfile* bus_profile)
512 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
513 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
517 if (ensure_subdirs ()) {
521 if (!mix_template.empty()) {
522 std::string in_path = mix_template;
524 ifstream in(in_path.c_str());
527 string out_path = _path;
529 out_path += statefile_suffix;
531 ofstream out(out_path.c_str());
539 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
545 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
552 /* Instantiate metadata */
554 _metadata = new SessionMetadata ();
556 /* set initial start + end point */
558 _state_of_the_state = Clean;
560 /* set up Master Out and Control Out if necessary */
566 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
568 if (bus_profile->master_out_channels) {
569 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
573 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
574 boost_debug_shared_ptr_mark_interesting (rt.get(), "Route");
577 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
578 r->input()->ensure_io (count, false, this);
579 r->output()->ensure_io (count, false, this);
581 r->set_remote_control_id (control_id++);
585 if (Config->get_use_monitor_bus()) {
586 boost::shared_ptr<Route> r (new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO));
590 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
591 boost_debug_shared_ptr_mark_interesting (rt, "Route");
594 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
595 r->input()->ensure_io (count, false, this);
596 r->output()->ensure_io (count, false, this);
598 r->set_remote_control_id (control_id);
604 /* prohibit auto-connect to master, because there isn't one */
605 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
609 add_routes (rl, false);
612 /* this allows the user to override settings with an environment variable.
615 if (no_auto_connect()) {
616 bus_profile->input_ac = AutoConnectOption (0);
617 bus_profile->output_ac = AutoConnectOption (0);
620 Config->set_input_auto_connect (bus_profile->input_ac);
621 Config->set_output_auto_connect (bus_profile->output_ac);
630 Session::maybe_write_autosave()
632 if (dirty() && record_status() != Recording) {
633 save_state("", true);
638 Session::remove_pending_capture_state ()
640 sys::path pending_state_file_path(_session_dir->root_path());
642 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
646 sys::remove (pending_state_file_path);
648 catch(sys::filesystem_error& ex)
650 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
651 pending_state_file_path.to_string(), ex.what()) << endmsg;
655 /** Rename a state file.
656 * @param snapshot_name Snapshot name.
659 Session::rename_state (string old_name, string new_name)
661 if (old_name == _current_snapshot_name || old_name == _name) {
662 /* refuse to rename the current snapshot or the "main" one */
666 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
667 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
669 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
670 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
674 sys::rename (old_xml_path, new_xml_path);
676 catch (const sys::filesystem_error& err)
678 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
679 old_name, new_name, err.what()) << endmsg;
683 /** Remove a state file.
684 * @param snapshot_name Snapshot name.
687 Session::remove_state (string snapshot_name)
689 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
690 // refuse to remove the current snapshot or the "main" one
694 sys::path xml_path(_session_dir->root_path());
696 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
698 if (!create_backup_file (xml_path)) {
699 // don't remove it if a backup can't be made
700 // create_backup_file will log the error.
705 sys::remove (xml_path);
708 #ifdef HAVE_JACK_SESSION
710 Session::jack_session_event (jack_session_event_t * event)
714 struct tm local_time;
717 localtime_r (&n, &local_time);
718 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
720 if (event->type == JackSessionSaveTemplate)
722 if (save_template( timebuf )) {
723 event->flags = JackSessionSaveError;
725 string cmd ("ardour3 -P -U ");
726 cmd += event->client_uuid;
730 event->command_line = strdup (cmd.c_str());
735 if (save_state (timebuf)) {
736 event->flags = JackSessionSaveError;
738 sys::path xml_path (_session_dir->root_path());
739 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
741 string cmd ("ardour3 -P -U ");
742 cmd += event->client_uuid;
744 cmd += xml_path.to_string();
747 event->command_line = strdup (cmd.c_str());
751 jack_session_reply (_engine.jack(), event);
753 if (event->type == JackSessionSaveAndQuit) {
754 Quit (); /* EMIT SIGNAL */
757 jack_session_event_free( event );
762 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
765 sys::path xml_path(_session_dir->root_path());
767 if (!_writable || (_state_of_the_state & CannotSave)) {
771 if (!_engine.connected ()) {
772 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
778 /* tell sources we're saving first, in case they write out to a new file
779 * which should be saved with the state rather than the old one */
780 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
781 i->second->session_saved();
784 tree.set_root (&get_state());
786 if (snapshot_name.empty()) {
787 snapshot_name = _current_snapshot_name;
788 } else if (switch_to_snapshot) {
789 _current_snapshot_name = snapshot_name;
794 /* proper save: use statefile_suffix (.ardour in English) */
796 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
798 /* make a backup copy of the old file */
800 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
801 // create_backup_file will log the error
807 /* pending save: use pending_suffix (.pending in English) */
808 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
811 sys::path tmp_path(_session_dir->root_path());
813 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
815 // cerr << "actually writing state to " << xml_path.to_string() << endl;
817 if (!tree.write (tmp_path.to_string())) {
818 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
819 sys::remove (tmp_path);
824 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
825 error << string_compose (_("could not rename temporary session file %1 to %2"),
826 tmp_path.to_string(), xml_path.to_string()) << endmsg;
827 sys::remove (tmp_path);
834 save_history (snapshot_name);
836 bool was_dirty = dirty();
838 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
841 DirtyChanged (); /* EMIT SIGNAL */
844 StateSaved (snapshot_name); /* EMIT SIGNAL */
851 Session::restore_state (string snapshot_name)
853 if (load_state (snapshot_name) == 0) {
854 set_state (*state_tree->root(), Stateful::loading_state_version);
861 Session::load_state (string snapshot_name)
866 state_was_pending = false;
868 /* check for leftover pending state from a crashed capture attempt */
870 sys::path xmlpath(_session_dir->root_path());
871 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
873 if (sys::exists (xmlpath)) {
875 /* there is pending state from a crashed capture attempt */
877 boost::optional<int> r = AskAboutPendingState();
878 if (r.get_value_or (1)) {
879 state_was_pending = true;
883 if (!state_was_pending) {
884 xmlpath = _session_dir->root_path();
885 xmlpath /= snapshot_name;
888 if (!sys::exists (xmlpath)) {
889 xmlpath = _session_dir->root_path();
890 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
891 if (!sys::exists (xmlpath)) {
892 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
897 state_tree = new XMLTree;
901 /* writable() really reflects the whole folder, but if for any
902 reason the session state file can't be written to, still
906 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
910 if (!state_tree->read (xmlpath.to_string())) {
911 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
917 XMLNode& root (*state_tree->root());
919 if (root.name() != X_("Session")) {
920 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
926 const XMLProperty* prop;
928 if ((prop = root.property ("version")) == 0) {
929 /* no version implies very old version of Ardour */
930 Stateful::loading_state_version = 1000;
936 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
937 Stateful::loading_state_version = (major * 1000) + minor;
940 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
942 sys::path backup_path(_session_dir->root_path());
944 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
946 // only create a backup once
947 if (sys::exists (backup_path)) {
951 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
952 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
957 sys::copy_file (xmlpath, backup_path);
959 catch(sys::filesystem_error& ex)
961 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
962 xmlpath.to_string(), ex.what())
972 Session::load_options (const XMLNode& node)
974 LocaleGuard lg (X_("POSIX"));
975 config.set_variables (node);
986 Session::get_template()
988 /* if we don't disable rec-enable, diskstreams
989 will believe they need to store their capture
990 sources in their state node.
993 disable_record (false);
999 Session::state(bool full_state)
1001 XMLNode* node = new XMLNode("Session");
1004 // store libardour version, just in case
1006 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
1007 node->add_property("version", string(buf));
1009 /* store configuration settings */
1013 node->add_property ("name", _name);
1014 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1015 node->add_property ("sample-rate", buf);
1017 if (session_dirs.size() > 1) {
1021 vector<space_and_path>::iterator i = session_dirs.begin();
1022 vector<space_and_path>::iterator next;
1024 ++i; /* skip the first one */
1028 while (i != session_dirs.end()) {
1032 if (next != session_dirs.end()) {
1042 child = node->add_child ("Path");
1043 child->add_content (p);
1047 /* save the ID counter */
1049 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1050 node->add_property ("id-counter", buf);
1052 /* save the event ID counter */
1054 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1055 node->add_property ("event-counter", buf);
1057 /* various options */
1059 node->add_child_nocopy (config.get_variables ());
1061 node->add_child_nocopy (_metadata->get_state());
1063 child = node->add_child ("Sources");
1066 Glib::Mutex::Lock sl (source_lock);
1068 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1070 /* Don't save information about non-destructive file sources that are empty
1071 and unused by any regions.
1074 boost::shared_ptr<FileSource> fs;
1075 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1076 if (!fs->destructive()) {
1077 if (fs->empty() && !fs->used()) {
1083 child->add_child_nocopy (siter->second->get_state());
1087 child = node->add_child ("Regions");
1090 Glib::Mutex::Lock rl (region_lock);
1091 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1092 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1093 boost::shared_ptr<Region> r = i->second;
1094 /* only store regions not attached to playlists */
1095 if (r->playlist() == 0) {
1096 child->add_child_nocopy (r->state ());
1102 node->add_child_nocopy (_locations->get_state());
1104 // for a template, just create a new Locations, populate it
1105 // with the default start and end, and get the state for that.
1106 Locations loc (*this);
1107 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1108 range->set (max_framepos, 0);
1110 node->add_child_nocopy (loc.get_state());
1113 child = node->add_child ("Bundles");
1115 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1116 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1117 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1119 child->add_child_nocopy (b->get_state());
1124 child = node->add_child ("Routes");
1126 boost::shared_ptr<RouteList> r = routes.reader ();
1128 RoutePublicOrderSorter cmp;
1129 RouteList public_order (*r);
1130 public_order.sort (cmp);
1132 /* the sort should have put control outs first */
1135 assert (_monitor_out == public_order.front());
1138 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1139 if (!(*i)->is_hidden()) {
1141 child->add_child_nocopy ((*i)->get_state());
1143 child->add_child_nocopy ((*i)->get_template());
1149 playlists->add_state (node, full_state);
1151 child = node->add_child ("RouteGroups");
1152 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1153 child->add_child_nocopy ((*i)->get_state());
1157 child = node->add_child ("Click");
1158 child->add_child_nocopy (_click_io->state (full_state));
1162 child = node->add_child ("NamedSelections");
1163 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1165 child->add_child_nocopy ((*i)->get_state());
1170 node->add_child_nocopy (_speakers->get_state());
1171 node->add_child_nocopy (_tempo_map->get_state());
1172 node->add_child_nocopy (get_control_protocol_state());
1175 node->add_child_copy (*_extra_xml);
1182 Session::get_control_protocol_state ()
1184 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1185 return cpm.get_state();
1189 Session::set_state (const XMLNode& node, int version)
1193 const XMLProperty* prop;
1196 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1198 if (node.name() != X_("Session")) {
1199 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1203 if ((prop = node.property ("version")) != 0) {
1204 version = atoi (prop->value ()) * 1000;
1207 if ((prop = node.property ("name")) != 0) {
1208 _name = prop->value ();
1211 if ((prop = node.property (X_("sample-rate"))) != 0) {
1213 _nominal_frame_rate = atoi (prop->value());
1215 if (_nominal_frame_rate != _current_frame_rate) {
1216 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1217 if (r.get_value_or (0)) {
1223 setup_raid_path(_session_dir->root_path().to_string());
1225 if ((prop = node.property (X_("id-counter"))) != 0) {
1227 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1228 ID::init_counter (x);
1230 /* old sessions used a timebased counter, so fake
1231 the startup ID counter based on a standard
1236 ID::init_counter (now);
1239 if ((prop = node.property (X_("event-counter"))) != 0) {
1240 Evoral::init_event_id_counter (atoi (prop->value()));
1243 IO::disable_connecting ();
1245 if ((child = find_named_node (node, "Extra")) != 0) {
1246 _extra_xml = new XMLNode (*child);
1249 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1250 load_options (*child);
1251 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1252 load_options (*child);
1254 error << _("Session: XML state has no options section") << endmsg;
1257 if (version >= 3000) {
1258 if ((child = find_named_node (node, "Metadata")) == 0) {
1259 warning << _("Session: XML state has no metadata section") << endmsg;
1260 } else if (_metadata->set_state (*child, version)) {
1265 if ((child = find_named_node (node, "Locations")) == 0) {
1266 error << _("Session: XML state has no locations section") << endmsg;
1268 } else if (_locations->set_state (*child, version)) {
1272 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1273 _speakers->set_state (*child, version);
1278 if ((location = _locations->auto_loop_location()) != 0) {
1279 set_auto_loop_location (location);
1282 if ((location = _locations->auto_punch_location()) != 0) {
1283 set_auto_punch_location (location);
1286 if ((location = _locations->session_range_location()) != 0) {
1287 delete _session_range_location;
1288 _session_range_location = location;
1291 if (_session_range_location) {
1292 AudioFileSource::set_header_position_offset (_session_range_location->start());
1295 if ((child = find_named_node (node, "Sources")) == 0) {
1296 error << _("Session: XML state has no sources section") << endmsg;
1298 } else if (load_sources (*child)) {
1302 if ((child = find_named_node (node, "TempoMap")) == 0) {
1303 error << _("Session: XML state has no Tempo Map section") << endmsg;
1305 } else if (_tempo_map->set_state (*child, version)) {
1309 if ((child = find_named_node (node, "Regions")) == 0) {
1310 error << _("Session: XML state has no Regions section") << endmsg;
1312 } else if (load_regions (*child)) {
1316 if ((child = find_named_node (node, "Playlists")) == 0) {
1317 error << _("Session: XML state has no playlists section") << endmsg;
1319 } else if (playlists->load (*this, *child)) {
1323 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1325 } else if (playlists->load_unused (*this, *child)) {
1329 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1330 if (load_named_selections (*child)) {
1335 if (version >= 3000) {
1336 if ((child = find_named_node (node, "Bundles")) == 0) {
1337 warning << _("Session: XML state has no bundles section") << endmsg;
1340 /* We can't load Bundles yet as they need to be able
1341 to convert from port names to Port objects, which can't happen until
1343 _bundle_xml_node = new XMLNode (*child);
1347 if (version < 3000) {
1348 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1349 error << _("Session: XML state has no diskstreams section") << endmsg;
1351 } else if (load_diskstreams_2X (*child, version)) {
1356 if ((child = find_named_node (node, "Routes")) == 0) {
1357 error << _("Session: XML state has no routes section") << endmsg;
1359 } else if (load_routes (*child, version)) {
1363 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1364 _diskstreams_2X.clear ();
1366 if (version >= 3000) {
1368 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1369 error << _("Session: XML state has no route groups section") << endmsg;
1371 } else if (load_route_groups (*child, version)) {
1375 } else if (version < 3000) {
1377 if ((child = find_named_node (node, "EditGroups")) == 0) {
1378 error << _("Session: XML state has no edit groups section") << endmsg;
1380 } else if (load_route_groups (*child, version)) {
1384 if ((child = find_named_node (node, "MixGroups")) == 0) {
1385 error << _("Session: XML state has no mix groups section") << endmsg;
1387 } else if (load_route_groups (*child, version)) {
1392 if ((child = find_named_node (node, "Click")) == 0) {
1393 warning << _("Session: XML state has no click section") << endmsg;
1394 } else if (_click_io) {
1395 _click_io->set_state (*child, version);
1398 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1399 ControlProtocolManager::instance().set_protocol_states (*child);
1402 /* here beginneth the second phase ... */
1404 StateReady (); /* EMIT SIGNAL */
1413 Session::load_routes (const XMLNode& node, int version)
1416 XMLNodeConstIterator niter;
1417 RouteList new_routes;
1419 nlist = node.children();
1423 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1425 boost::shared_ptr<Route> route;
1426 if (version < 3000) {
1427 route = XMLRouteFactory_2X (**niter, version);
1429 route = XMLRouteFactory (**niter, version);
1433 error << _("Session: cannot create Route from XML description.") << endmsg;
1437 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1439 new_routes.push_back (route);
1442 add_routes (new_routes, false);
1447 boost::shared_ptr<Route>
1448 Session::XMLRouteFactory (const XMLNode& node, int version)
1450 boost::shared_ptr<Route> ret;
1452 if (node.name() != "Route") {
1456 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1458 DataType type = DataType::AUDIO;
1459 const XMLProperty* prop = node.property("default-type");
1462 type = DataType (prop->value());
1465 assert (type != DataType::NIL);
1469 boost::shared_ptr<Track> track;
1471 if (type == DataType::AUDIO) {
1472 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1474 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1477 if (track->init()) {
1481 if (track->set_state (node, version)) {
1485 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1486 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1491 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1493 if (r->init () == 0 && r->set_state (node, version) == 0) {
1494 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1495 boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1504 boost::shared_ptr<Route>
1505 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1507 boost::shared_ptr<Route> ret;
1509 if (node.name() != "Route") {
1513 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1515 ds_prop = node.property (X_("diskstream"));
1518 DataType type = DataType::AUDIO;
1519 const XMLProperty* prop = node.property("default-type");
1522 type = DataType (prop->value());
1525 assert (type != DataType::NIL);
1529 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1530 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1534 if (i == _diskstreams_2X.end()) {
1535 error << _("Could not find diskstream for route") << endmsg;
1536 return boost::shared_ptr<Route> ();
1539 boost::shared_ptr<Track> track;
1541 if (type == DataType::AUDIO) {
1542 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1544 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1547 if (track->init()) {
1551 if (track->set_state (node, version)) {
1555 track->set_diskstream (*i);
1557 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1558 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1563 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1565 if (r->init () == 0 && r->set_state (node, version) == 0) {
1566 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1567 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1577 Session::load_regions (const XMLNode& node)
1580 XMLNodeConstIterator niter;
1581 boost::shared_ptr<Region> region;
1583 nlist = node.children();
1587 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1588 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1589 error << _("Session: cannot create Region from XML description.");
1590 const XMLProperty *name = (**niter).property("name");
1593 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1603 boost::shared_ptr<Region>
1604 Session::XMLRegionFactory (const XMLNode& node, bool full)
1606 const XMLProperty* type = node.property("type");
1610 if (!type || type->value() == "audio") {
1611 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1612 } else if (type->value() == "midi") {
1613 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1616 } catch (failed_constructor& err) {
1617 return boost::shared_ptr<Region> ();
1620 return boost::shared_ptr<Region> ();
1623 boost::shared_ptr<AudioRegion>
1624 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1626 const XMLProperty* prop;
1627 boost::shared_ptr<Source> source;
1628 boost::shared_ptr<AudioSource> as;
1630 SourceList master_sources;
1631 uint32_t nchans = 1;
1634 if (node.name() != X_("Region")) {
1635 return boost::shared_ptr<AudioRegion>();
1638 if ((prop = node.property (X_("channels"))) != 0) {
1639 nchans = atoi (prop->value().c_str());
1642 if ((prop = node.property ("name")) == 0) {
1643 cerr << "no name for this region\n";
1647 if ((prop = node.property (X_("source-0"))) == 0) {
1648 if ((prop = node.property ("source")) == 0) {
1649 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1650 return boost::shared_ptr<AudioRegion>();
1654 PBD::ID s_id (prop->value());
1656 if ((source = source_by_id (s_id)) == 0) {
1657 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1658 return boost::shared_ptr<AudioRegion>();
1661 as = boost::dynamic_pointer_cast<AudioSource>(source);
1663 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1664 return boost::shared_ptr<AudioRegion>();
1667 sources.push_back (as);
1669 /* pickup other channels */
1671 for (uint32_t n=1; n < nchans; ++n) {
1672 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1673 if ((prop = node.property (buf)) != 0) {
1675 PBD::ID id2 (prop->value());
1677 if ((source = source_by_id (id2)) == 0) {
1678 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1679 return boost::shared_ptr<AudioRegion>();
1682 as = boost::dynamic_pointer_cast<AudioSource>(source);
1684 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1685 return boost::shared_ptr<AudioRegion>();
1687 sources.push_back (as);
1691 for (uint32_t n = 0; n < nchans; ++n) {
1692 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1693 if ((prop = node.property (buf)) != 0) {
1695 PBD::ID id2 (prop->value());
1697 if ((source = source_by_id (id2)) == 0) {
1698 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1699 return boost::shared_ptr<AudioRegion>();
1702 as = boost::dynamic_pointer_cast<AudioSource>(source);
1704 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1705 return boost::shared_ptr<AudioRegion>();
1707 master_sources.push_back (as);
1712 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1714 /* a final detail: this is the one and only place that we know how long missing files are */
1716 if (region->whole_file()) {
1717 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1718 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1720 sfp->set_length (region->length());
1725 if (!master_sources.empty()) {
1726 if (master_sources.size() != nchans) {
1727 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1729 region->set_master_sources (master_sources);
1737 catch (failed_constructor& err) {
1738 return boost::shared_ptr<AudioRegion>();
1742 boost::shared_ptr<MidiRegion>
1743 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1745 const XMLProperty* prop;
1746 boost::shared_ptr<Source> source;
1747 boost::shared_ptr<MidiSource> ms;
1750 if (node.name() != X_("Region")) {
1751 return boost::shared_ptr<MidiRegion>();
1754 if ((prop = node.property ("name")) == 0) {
1755 cerr << "no name for this region\n";
1759 if ((prop = node.property (X_("source-0"))) == 0) {
1760 if ((prop = node.property ("source")) == 0) {
1761 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1762 return boost::shared_ptr<MidiRegion>();
1766 PBD::ID s_id (prop->value());
1768 if ((source = source_by_id (s_id)) == 0) {
1769 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1770 return boost::shared_ptr<MidiRegion>();
1773 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1775 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1776 return boost::shared_ptr<MidiRegion>();
1779 sources.push_back (ms);
1782 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1783 /* a final detail: this is the one and only place that we know how long missing files are */
1785 if (region->whole_file()) {
1786 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1787 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1789 sfp->set_length (region->length());
1797 catch (failed_constructor& err) {
1798 return boost::shared_ptr<MidiRegion>();
1803 Session::get_sources_as_xml ()
1806 XMLNode* node = new XMLNode (X_("Sources"));
1807 Glib::Mutex::Lock lm (source_lock);
1809 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1810 node->add_child_nocopy (i->second->get_state());
1817 Session::path_from_region_name (DataType type, string name, string identifier)
1819 char buf[PATH_MAX+1];
1821 SessionDirectory sdir(get_best_session_directory_for_new_source());
1822 sys::path source_dir = ((type == DataType::AUDIO)
1823 ? sdir.sound_path() : sdir.midi_path());
1825 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1827 for (n = 0; n < 999999; ++n) {
1828 if (identifier.length()) {
1829 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1830 identifier.c_str(), n, ext.c_str());
1832 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1836 sys::path source_path = source_dir / buf;
1838 if (!sys::exists (source_path)) {
1839 return source_path.to_string();
1843 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1852 Session::load_sources (const XMLNode& node)
1855 XMLNodeConstIterator niter;
1856 boost::shared_ptr<Source> source;
1858 nlist = node.children();
1862 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1865 if ((source = XMLSourceFactory (**niter)) == 0) {
1866 error << _("Session: cannot create Source from XML description.") << endmsg;
1869 } catch (MissingSource& err) {
1873 if (!no_questions_about_missing_files) {
1874 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1879 switch (user_choice) {
1881 /* user added a new search location, so try again */
1886 /* user asked to quit the entire session load
1891 no_questions_about_missing_files = true;
1895 no_questions_about_missing_files = true;
1900 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1901 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1910 boost::shared_ptr<Source>
1911 Session::XMLSourceFactory (const XMLNode& node)
1913 if (node.name() != "Source") {
1914 return boost::shared_ptr<Source>();
1918 /* note: do peak building in another thread when loading session state */
1919 return SourceFactory::create (*this, node, true);
1922 catch (failed_constructor& err) {
1923 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1924 return boost::shared_ptr<Source>();
1929 Session::save_template (string template_name)
1933 if (_state_of_the_state & CannotSave) {
1937 sys::path user_template_dir(user_template_directory());
1941 sys::create_directories (user_template_dir);
1943 catch(sys::filesystem_error& ex)
1945 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1946 user_template_dir.to_string(), ex.what()) << endmsg;
1950 tree.set_root (&get_template());
1952 sys::path template_file_path(user_template_dir);
1953 template_file_path /= template_name + template_suffix;
1955 if (sys::exists (template_file_path))
1957 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1958 template_file_path.to_string()) << endmsg;
1962 if (!tree.write (template_file_path.to_string())) {
1963 error << _("template not saved") << endmsg;
1971 Session::rename_template (string old_name, string new_name)
1973 sys::path old_path (user_template_directory());
1974 old_path /= old_name + template_suffix;
1976 sys::path new_path(user_template_directory());
1977 new_path /= new_name + template_suffix;
1979 if (sys::exists (new_path)) {
1980 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1981 new_path.to_string()) << endmsg;
1986 sys::rename (old_path, new_path);
1994 Session::delete_template (string name)
1996 sys::path path = user_template_directory();
1997 path /= name + template_suffix;
2008 Session::refresh_disk_space ()
2011 struct statfs statfsbuf;
2012 vector<space_and_path>::iterator i;
2013 Glib::Mutex::Lock lm (space_lock);
2016 /* get freespace on every FS that is part of the session path */
2018 _total_free_4k_blocks = 0;
2020 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2021 statfs ((*i).path.c_str(), &statfsbuf);
2023 scale = statfsbuf.f_bsize/4096.0;
2025 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2026 _total_free_4k_blocks += (*i).blocks;
2032 Session::get_best_session_directory_for_new_source ()
2034 vector<space_and_path>::iterator i;
2035 string result = _session_dir->root_path().to_string();
2037 /* handle common case without system calls */
2039 if (session_dirs.size() == 1) {
2043 /* OK, here's the algorithm we're following here:
2045 We want to select which directory to use for
2046 the next file source to be created. Ideally,
2047 we'd like to use a round-robin process so as to
2048 get maximum performance benefits from splitting
2049 the files across multiple disks.
2051 However, in situations without much diskspace, an
2052 RR approach may end up filling up a filesystem
2053 with new files while others still have space.
2054 Its therefore important to pay some attention to
2055 the freespace in the filesystem holding each
2056 directory as well. However, if we did that by
2057 itself, we'd keep creating new files in the file
2058 system with the most space until it was as full
2059 as all others, thus negating any performance
2060 benefits of this RAID-1 like approach.
2062 So, we use a user-configurable space threshold. If
2063 there are at least 2 filesystems with more than this
2064 much space available, we use RR selection between them.
2065 If not, then we pick the filesystem with the most space.
2067 This gets a good balance between the two
2071 refresh_disk_space ();
2073 int free_enough = 0;
2075 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2076 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2081 if (free_enough >= 2) {
2082 /* use RR selection process, ensuring that the one
2086 i = last_rr_session_dir;
2089 if (++i == session_dirs.end()) {
2090 i = session_dirs.begin();
2093 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2094 if (create_session_directory ((*i).path)) {
2096 last_rr_session_dir = i;
2101 } while (i != last_rr_session_dir);
2105 /* pick FS with the most freespace (and that
2106 seems to actually work ...)
2109 vector<space_and_path> sorted;
2110 space_and_path_ascending_cmp cmp;
2112 sorted = session_dirs;
2113 sort (sorted.begin(), sorted.end(), cmp);
2115 for (i = sorted.begin(); i != sorted.end(); ++i) {
2116 if (create_session_directory ((*i).path)) {
2118 last_rr_session_dir = i;
2128 Session::load_named_selections (const XMLNode& node)
2131 XMLNodeConstIterator niter;
2134 nlist = node.children();
2138 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2140 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2141 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2149 Session::XMLNamedSelectionFactory (const XMLNode& node)
2152 return new NamedSelection (*this, node);
2155 catch (failed_constructor& err) {
2161 Session::automation_dir () const
2163 return Glib::build_filename (_path, "automation");
2167 Session::analysis_dir () const
2169 return Glib::build_filename (_path, "analysis");
2173 Session::plugins_dir () const
2175 return Glib::build_filename (_path, "plugins");
2179 Session::load_bundles (XMLNode const & node)
2181 XMLNodeList nlist = node.children();
2182 XMLNodeConstIterator niter;
2186 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2187 if ((*niter)->name() == "InputBundle") {
2188 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2189 } else if ((*niter)->name() == "OutputBundle") {
2190 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2192 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2201 Session::load_route_groups (const XMLNode& node, int version)
2203 XMLNodeList nlist = node.children();
2204 XMLNodeConstIterator niter;
2208 if (version >= 3000) {
2210 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2211 if ((*niter)->name() == "RouteGroup") {
2212 RouteGroup* rg = new RouteGroup (*this, "");
2213 add_route_group (rg);
2214 rg->set_state (**niter, version);
2218 } else if (version < 3000) {
2220 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2221 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2222 RouteGroup* rg = new RouteGroup (*this, "");
2223 add_route_group (rg);
2224 rg->set_state (**niter, version);
2233 Session::auto_save()
2235 save_state (_current_snapshot_name);
2239 state_file_filter (const string &str, void */*arg*/)
2241 return (str.length() > strlen(statefile_suffix) &&
2242 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2246 bool operator()(const string* a, const string* b) {
2252 remove_end(string* state)
2254 string statename(*state);
2256 string::size_type start,end;
2257 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2258 statename = statename.substr (start+1);
2261 if ((end = statename.rfind(".ardour")) == string::npos) {
2262 end = statename.length();
2265 return new string(statename.substr (0, end));
2269 Session::possible_states (string path)
2271 PathScanner scanner;
2272 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2274 transform(states->begin(), states->end(), states->begin(), remove_end);
2277 sort (states->begin(), states->end(), cmp);
2283 Session::possible_states () const
2285 return possible_states(_path);
2289 Session::add_route_group (RouteGroup* g)
2291 _route_groups.push_back (g);
2292 route_group_added (g); /* EMIT SIGNAL */
2294 g->MembershipChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2295 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2301 Session::remove_route_group (RouteGroup& rg)
2303 list<RouteGroup*>::iterator i;
2305 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2306 _route_groups.erase (i);
2309 route_group_removed (); /* EMIT SIGNAL */
2315 Session::route_group_by_name (string name)
2317 list<RouteGroup *>::iterator i;
2319 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2320 if ((*i)->name() == name) {
2328 Session::all_route_group() const
2330 return *_all_route_group;
2334 Session::add_commands (vector<Command*> const & cmds)
2336 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2342 Session::begin_reversible_command (const string& name)
2344 begin_reversible_command (g_quark_from_string (name.c_str ()));
2347 /** Begin a reversible command using a GQuark to identify it.
2348 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2349 * but there must be as many begin...()s as there are commit...()s.
2352 Session::begin_reversible_command (GQuark q)
2354 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2355 to hold all the commands that are committed. This keeps the order of
2356 commands correct in the history.
2359 if (_current_trans == 0) {
2360 /* start a new transaction */
2361 assert (_current_trans_quarks.empty ());
2362 _current_trans = new UndoTransaction();
2363 _current_trans->set_name (g_quark_to_string (q));
2366 _current_trans_quarks.push_front (q);
2370 Session::commit_reversible_command (Command *cmd)
2372 assert (_current_trans);
2373 assert (!_current_trans_quarks.empty ());
2378 _current_trans->add_command (cmd);
2381 _current_trans_quarks.pop_front ();
2383 if (!_current_trans_quarks.empty ()) {
2384 /* the transaction we're committing is not the top-level one */
2388 if (_current_trans->empty()) {
2389 /* no commands were added to the transaction, so just get rid of it */
2390 delete _current_trans;
2395 gettimeofday (&now, 0);
2396 _current_trans->set_timestamp (now);
2398 _history.add (_current_trans);
2403 accept_all_audio_files (const string& path, void */*arg*/)
2405 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2409 if (!AudioFileSource::safe_audio_file_extension (path)) {
2417 accept_all_midi_files (const string& path, void */*arg*/)
2419 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2423 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2424 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2425 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2429 accept_all_state_files (const string& path, void */*arg*/)
2431 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2435 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2439 Session::find_all_sources (string path, set<string>& result)
2444 if (!tree.read (path)) {
2448 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2453 XMLNodeConstIterator niter;
2455 nlist = node->children();
2459 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2463 if ((prop = (*niter)->property (X_("type"))) == 0) {
2467 DataType type (prop->value());
2469 if ((prop = (*niter)->property (X_("name"))) == 0) {
2473 if (Glib::path_is_absolute (prop->value())) {
2474 /* external file, ignore */
2482 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2483 result.insert (found_path);
2491 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2493 PathScanner scanner;
2494 vector<string*>* state_files;
2496 string this_snapshot_path;
2502 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2503 ripped = ripped.substr (0, ripped.length() - 1);
2506 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2508 if (state_files == 0) {
2513 this_snapshot_path = _path;
2514 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2515 this_snapshot_path += statefile_suffix;
2517 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2519 if (exclude_this_snapshot && **i == this_snapshot_path) {
2523 if (find_all_sources (**i, result) < 0) {
2531 struct RegionCounter {
2532 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2533 AudioSourceList::iterator iter;
2534 boost::shared_ptr<Region> region;
2537 RegionCounter() : count (0) {}
2541 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2543 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2544 return r.get_value_or (1);
2548 Session::cleanup_regions ()
2550 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2552 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2554 boost::shared_ptr<AudioRegion> audio_region = boost::dynamic_pointer_cast<AudioRegion>( i->second);
2556 if (!audio_region) {
2560 uint32_t used = playlists->region_use_count (audio_region);
2562 if (used == 0 && !audio_region->automatic()) {
2563 RegionFactory::map_remove(i->second);
2567 /* dump the history list */
2574 Session::cleanup_sources (CleanupReport& rep)
2576 // FIXME: needs adaptation to midi
2578 vector<boost::shared_ptr<Source> > dead_sources;
2579 PathScanner scanner;
2582 vector<space_and_path>::iterator i;
2583 vector<space_and_path>::iterator nexti;
2584 vector<string*>* candidates;
2585 vector<string*>* candidates2;
2586 vector<string> unused;
2587 set<string> all_sources;
2592 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2594 /* consider deleting all unused playlists */
2596 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2601 /* sync the "all regions" property of each playlist with its current state
2604 playlists->sync_all_regions_with_regions ();
2606 /* find all un-used sources */
2611 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2613 SourceMap::iterator tmp;
2618 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2622 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2623 dead_sources.push_back (i->second);
2624 i->second->drop_references ();
2630 /* build a list of all the possible audio directories for the session */
2632 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2637 SessionDirectory sdir ((*i).path);
2638 audio_path += sdir.sound_path().to_string();
2640 if (nexti != session_dirs.end()) {
2648 /* build a list of all the possible midi directories for the session */
2650 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2655 SessionDirectory sdir ((*i).path);
2656 midi_path += sdir.midi_path().to_string();
2658 if (nexti != session_dirs.end()) {
2665 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2666 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2672 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2673 candidates->push_back (*i);
2678 candidates = candidates2; // might still be null
2681 /* find all sources, but don't use this snapshot because the
2682 state file on disk still references sources we may have already
2686 find_all_sources_across_snapshots (all_sources, true);
2688 /* add our current source list
2691 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2692 boost::shared_ptr<FileSource> fs;
2693 SourceMap::iterator tmp = i;
2696 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2697 if (playlists->source_use_count (fs) != 0) {
2698 all_sources.insert (fs->path());
2701 /* we might not remove this source from disk, because it may be used
2702 by other snapshots, but its not being used in this version
2703 so lets get rid of it now, along with any representative regions
2707 RegionFactory::remove_regions_using_source (i->second);
2715 char tmppath1[PATH_MAX+1];
2716 char tmppath2[PATH_MAX+1];
2719 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2724 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2726 if (realpath(spath.c_str(), tmppath1) == 0) {
2727 error << string_compose (_("Cannot expand path %1 (%2)"),
2728 spath, strerror (errno)) << endmsg;
2732 if (realpath((*i).c_str(), tmppath2) == 0) {
2733 error << string_compose (_("Cannot expand path %1 (%2)"),
2734 (*i), strerror (errno)) << endmsg;
2738 if (strcmp(tmppath1, tmppath2) == 0) {
2745 unused.push_back (spath);
2754 /* now try to move all unused files into the "dead" directory(ies) */
2756 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2757 struct stat statbuf;
2761 /* don't move the file across filesystems, just
2762 stick it in the `dead_dir_name' directory
2763 on whichever filesystem it was already on.
2766 if ((*x).find ("/sounds/") != string::npos) {
2768 /* old school, go up 1 level */
2770 newpath = Glib::path_get_dirname (*x); // "sounds"
2771 newpath = Glib::path_get_dirname (newpath); // "session-name"
2775 /* new school, go up 4 levels */
2777 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2778 newpath = Glib::path_get_dirname (newpath); // "session-name"
2779 newpath = Glib::path_get_dirname (newpath); // "interchange"
2780 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2783 newpath = Glib::build_filename (newpath, dead_dir_name);
2785 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2786 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2790 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2792 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2794 /* the new path already exists, try versioning */
2796 char buf[PATH_MAX+1];
2800 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2803 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2804 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2808 if (version == 999) {
2809 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2813 newpath = newpath_v;
2818 /* it doesn't exist, or we can't read it or something */
2822 stat ((*x).c_str(), &statbuf);
2824 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2825 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2826 (*x), newpath, strerror (errno))
2831 /* see if there an easy to find peakfile for this file, and remove it.
2834 string base = basename_nosuffix (*x);
2835 base += "%A"; /* this is what we add for the channel suffix of all native files,
2836 or for the first channel of embedded files. it will miss
2837 some peakfiles for other channels
2839 string peakpath = peak_path (base);
2841 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2842 if (::unlink (peakpath.c_str()) != 0) {
2843 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2844 peakpath, _path, strerror (errno))
2846 /* try to back out */
2847 rename (newpath.c_str(), _path.c_str());
2852 rep.paths.push_back (*x);
2853 rep.space += statbuf.st_size;
2856 /* dump the history list */
2860 /* save state so we don't end up a session file
2861 referring to non-existent sources.
2868 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2874 Session::cleanup_trash_sources (CleanupReport& rep)
2876 // FIXME: needs adaptation for MIDI
2878 vector<space_and_path>::iterator i;
2884 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2886 dead_dir = (*i).path;
2887 dead_dir += dead_dir_name;
2889 clear_directory (dead_dir, &rep.space, &rep.paths);
2896 Session::set_dirty ()
2898 bool was_dirty = dirty();
2900 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2904 DirtyChanged(); /* EMIT SIGNAL */
2910 Session::set_clean ()
2912 bool was_dirty = dirty();
2914 _state_of_the_state = Clean;
2918 DirtyChanged(); /* EMIT SIGNAL */
2923 Session::set_deletion_in_progress ()
2925 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2929 Session::clear_deletion_in_progress ()
2931 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2935 Session::add_controllable (boost::shared_ptr<Controllable> c)
2937 /* this adds a controllable to the list managed by the Session.
2938 this is a subset of those managed by the Controllable class
2939 itself, and represents the only ones whose state will be saved
2940 as part of the session.
2943 Glib::Mutex::Lock lm (controllables_lock);
2944 controllables.insert (c);
2947 struct null_deleter { void operator()(void const *) const {} };
2950 Session::remove_controllable (Controllable* c)
2952 if (_state_of_the_state | Deletion) {
2956 Glib::Mutex::Lock lm (controllables_lock);
2958 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2960 if (x != controllables.end()) {
2961 controllables.erase (x);
2965 boost::shared_ptr<Controllable>
2966 Session::controllable_by_id (const PBD::ID& id)
2968 Glib::Mutex::Lock lm (controllables_lock);
2970 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2971 if ((*i)->id() == id) {
2976 return boost::shared_ptr<Controllable>();
2979 boost::shared_ptr<Controllable>
2980 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2982 boost::shared_ptr<Controllable> c;
2983 boost::shared_ptr<Route> r;
2985 switch (desc.top_level_type()) {
2986 case ControllableDescriptor::NamedRoute:
2988 std::string str = desc.top_level_name();
2989 if (str == "master") {
2991 } else if (str == "control" || str == "listen") {
2994 r = route_by_name (desc.top_level_name());
2999 case ControllableDescriptor::RemoteControlID:
3000 r = route_by_remote_id (desc.rid());
3008 switch (desc.subtype()) {
3009 case ControllableDescriptor::Gain:
3010 c = r->gain_control ();
3013 case ControllableDescriptor::Solo:
3014 c = r->solo_control();
3017 case ControllableDescriptor::Mute:
3018 c = r->mute_control();
3021 case ControllableDescriptor::Recenable:
3023 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3026 c = t->rec_enable_control ();
3031 case ControllableDescriptor::PanDirection:
3033 c = r->pannable()->pan_azimuth_control;
3037 case ControllableDescriptor::PanWidth:
3039 c = r->pannable()->pan_width_control;
3043 case ControllableDescriptor::PanElevation:
3045 c = r->pannable()->pan_elevation_control;
3049 case ControllableDescriptor::Balance:
3050 /* XXX simple pan control */
3053 case ControllableDescriptor::PluginParameter:
3055 uint32_t plugin = desc.target (0);
3056 uint32_t parameter_index = desc.target (1);
3058 /* revert to zero based counting */
3064 if (parameter_index > 0) {
3068 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3071 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3072 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3077 case ControllableDescriptor::SendGain:
3079 uint32_t send = desc.target (0);
3081 /* revert to zero-based counting */
3087 boost::shared_ptr<Processor> p = r->nth_send (send);
3090 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3091 boost::shared_ptr<Amp> a = s->amp();
3094 c = s->amp()->gain_control();
3101 /* relax and return a null pointer */
3109 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3112 Stateful::add_instant_xml (node, _path);
3115 if (write_to_config) {
3116 Config->add_instant_xml (node);
3121 Session::instant_xml (const string& node_name)
3123 return Stateful::instant_xml (node_name, _path);
3127 Session::save_history (string snapshot_name)
3135 if (snapshot_name.empty()) {
3136 snapshot_name = _current_snapshot_name;
3139 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3140 const string backup_filename = history_filename + backup_suffix;
3141 const sys::path xml_path = _session_dir->root_path() / history_filename;
3142 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3144 if (sys::exists (xml_path)) {
3147 sys::rename (xml_path, backup_path);
3149 catch (const sys::filesystem_error& err)
3151 error << _("could not backup old history file, current history not saved") << endmsg;
3156 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3160 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3162 if (!tree.write (xml_path.to_string()))
3164 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3168 sys::remove (xml_path);
3169 sys::rename (backup_path, xml_path);
3171 catch (const sys::filesystem_error& err)
3173 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3174 backup_path.to_string(), err.what()) << endmsg;
3184 Session::restore_history (string snapshot_name)
3188 if (snapshot_name.empty()) {
3189 snapshot_name = _current_snapshot_name;
3192 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3193 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3195 info << "Loading history from " << xml_path.to_string() << endmsg;
3197 if (!sys::exists (xml_path)) {
3198 info << string_compose (_("%1: no history file \"%2\" for this session."),
3199 _name, xml_path.to_string()) << endmsg;
3203 if (!tree.read (xml_path.to_string())) {
3204 error << string_compose (_("Could not understand session history file \"%1\""),
3205 xml_path.to_string()) << endmsg;
3212 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3215 UndoTransaction* ut = new UndoTransaction ();
3218 ut->set_name(t->property("name")->value());
3219 stringstream ss(t->property("tv-sec")->value());
3221 ss.str(t->property("tv-usec")->value());
3223 ut->set_timestamp(tv);
3225 for (XMLNodeConstIterator child_it = t->children().begin();
3226 child_it != t->children().end(); child_it++)
3228 XMLNode *n = *child_it;
3231 if (n->name() == "MementoCommand" ||
3232 n->name() == "MementoUndoCommand" ||
3233 n->name() == "MementoRedoCommand") {
3235 if ((c = memento_command_factory(n))) {
3239 } else if (n->name() == "NoteDiffCommand") {
3240 PBD::ID id (n->property("midi-source")->value());
3241 boost::shared_ptr<MidiSource> midi_source =
3242 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3244 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3246 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3249 } else if (n->name() == "SysExDiffCommand") {
3251 PBD::ID id (n->property("midi-source")->value());
3252 boost::shared_ptr<MidiSource> midi_source =
3253 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3255 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3257 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3260 } else if (n->name() == "PatchChangeDiffCommand") {
3262 PBD::ID id (n->property("midi-source")->value());
3263 boost::shared_ptr<MidiSource> midi_source =
3264 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3266 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3268 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3271 } else if (n->name() == "StatefulDiffCommand") {
3272 if ((c = stateful_diff_command_factory (n))) {
3273 ut->add_command (c);
3276 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3287 Session::config_changed (std::string p, bool ours)
3293 if (p == "seamless-loop") {
3295 } else if (p == "rf-speed") {
3297 } else if (p == "auto-loop") {
3299 } else if (p == "auto-input") {
3301 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3302 /* auto-input only makes a difference if we're rolling */
3304 boost::shared_ptr<RouteList> rl = routes.reader ();
3305 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3306 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3307 if (tr && tr->record_enabled ()) {
3308 tr->monitor_input (!config.get_auto_input());
3313 } else if (p == "punch-in") {
3317 if ((location = _locations->auto_punch_location()) != 0) {
3319 if (config.get_punch_in ()) {
3320 replace_event (SessionEvent::PunchIn, location->start());
3322 remove_event (location->start(), SessionEvent::PunchIn);
3326 } else if (p == "punch-out") {
3330 if ((location = _locations->auto_punch_location()) != 0) {
3332 if (config.get_punch_out()) {
3333 replace_event (SessionEvent::PunchOut, location->end());
3335 clear_events (SessionEvent::PunchOut);
3339 } else if (p == "edit-mode") {
3341 Glib::Mutex::Lock lm (playlists->lock);
3343 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3344 (*i)->set_edit_mode (Config->get_edit_mode ());
3347 } else if (p == "use-video-sync") {
3349 waiting_for_sync_offset = config.get_use_video_sync();
3351 } else if (p == "mmc-control") {
3353 //poke_midi_thread ();
3355 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3357 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3359 } else if (p == "mmc-send-id") {
3361 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3363 } else if (p == "midi-control") {
3365 //poke_midi_thread ();
3367 } else if (p == "raid-path") {
3369 setup_raid_path (config.get_raid_path());
3371 } else if (p == "timecode-format") {
3375 } else if (p == "video-pullup") {
3379 } else if (p == "seamless-loop") {
3381 if (play_loop && transport_rolling()) {
3382 // to reset diskstreams etc
3383 request_play_loop (true);
3386 } else if (p == "rf-speed") {
3388 cumulative_rf_motion = 0;
3391 } else if (p == "click-sound") {
3393 setup_click_sounds (1);
3395 } else if (p == "click-emphasis-sound") {
3397 setup_click_sounds (-1);
3399 } else if (p == "clicking") {
3401 if (Config->get_clicking()) {
3402 if (_click_io && click_data) { // don't require emphasis data
3409 } else if (p == "send-mtc") {
3411 if (Config->get_send_mtc ()) {
3412 /* mark us ready to send */
3413 next_quarter_frame_to_send = 0;
3416 } else if (p == "send-mmc") {
3418 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3420 } else if (p == "midi-feedback") {
3422 session_midi_feedback = Config->get_midi_feedback();
3424 } else if (p == "jack-time-master") {
3426 engine().reset_timebase ();
3428 } else if (p == "native-file-header-format") {
3430 if (!first_file_header_format_reset) {
3431 reset_native_file_format ();
3434 first_file_header_format_reset = false;
3436 } else if (p == "native-file-data-format") {
3438 if (!first_file_data_format_reset) {
3439 reset_native_file_format ();
3442 first_file_data_format_reset = false;
3444 } else if (p == "external-sync") {
3445 if (!config.get_external_sync()) {
3446 drop_sync_source ();
3448 switch_to_sync_source (config.get_sync_source());
3450 } else if (p == "remote-model") {
3451 set_remote_control_ids ();
3452 } else if (p == "denormal-model") {
3454 } else if (p == "history-depth") {
3455 set_history_depth (Config->get_history_depth());
3456 } else if (p == "sync-all-route-ordering") {
3457 sync_order_keys ("session");
3458 } else if (p == "initial-program-change") {
3460 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3463 buf[0] = MIDI::program; // channel zero by default
3464 buf[1] = (Config->get_initial_program_change() & 0x7f);
3466 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3468 } else if (p == "solo-mute-override") {
3469 // catch_up_on_solo_mute_override ();
3470 } else if (p == "listen-position" || p == "pfl-position") {
3471 listen_position_changed ();
3472 } else if (p == "solo-control-is-listen-control") {
3473 solo_control_mode_changed ();
3474 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3475 last_timecode_valid = false;
3482 Session::set_history_depth (uint32_t d)
3484 _history.set_depth (d);
3488 Session::load_diskstreams_2X (XMLNode const & node, int)
3491 XMLNodeConstIterator citer;
3493 clist = node.children();
3495 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3498 /* diskstreams added automatically by DiskstreamCreated handler */
3499 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3500 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3501 _diskstreams_2X.push_back (dsp);
3503 error << _("Session: unknown diskstream type in XML") << endmsg;
3507 catch (failed_constructor& err) {
3508 error << _("Session: could not load diskstream via XML state") << endmsg;
3516 /** Connect things to the MMC object */
3518 Session::setup_midi_machine_control ()
3520 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3522 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3523 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3524 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3525 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3526 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3527 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3528 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3529 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3530 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3531 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3532 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3533 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3534 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3536 /* also handle MIDI SPP because its so common */
3538 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3539 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3540 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));
3543 boost::shared_ptr<Controllable>
3544 Session::solo_cut_control() const
3546 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3547 controls in Ardour that currently get presented to the user in the GUI that require
3548 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3550 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3551 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3555 return _solo_cut_control;