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/controllable_descriptor.h"
60 #include "pbd/enumwriter.h"
61 #include "pbd/error.h"
62 #include "pbd/pathscanner.h"
63 #include "pbd/pthread_utils.h"
64 #include "pbd/search_path.h"
65 #include "pbd/stacktrace.h"
66 #include "pbd/convert.h"
67 #include "pbd/clear_dir.h"
69 #include "ardour/amp.h"
70 #include "ardour/audio_diskstream.h"
71 #include "ardour/audio_track.h"
72 #include "ardour/audioengine.h"
73 #include "ardour/audiofilesource.h"
74 #include "ardour/audioplaylist.h"
75 #include "ardour/audioregion.h"
76 #include "ardour/auditioner.h"
77 #include "ardour/automation_control.h"
78 #include "ardour/buffer.h"
79 #include "ardour/butler.h"
80 #include "ardour/configuration.h"
81 #include "ardour/control_protocol_manager.h"
82 #include "ardour/crossfade.h"
83 #include "ardour/cycle_timer.h"
84 #include "ardour/directory_names.h"
85 #include "ardour/filename_extensions.h"
86 #include "ardour/io_processor.h"
87 #include "ardour/location.h"
88 #include "ardour/midi_diskstream.h"
89 #include "ardour/midi_patch_manager.h"
90 #include "ardour/midi_playlist.h"
91 #include "ardour/midi_region.h"
92 #include "ardour/midi_source.h"
93 #include "ardour/midi_track.h"
94 #include "ardour/named_selection.h"
95 #include "ardour/pannable.h"
96 #include "ardour/processor.h"
97 #include "ardour/port.h"
98 #include "ardour/proxy_controllable.h"
99 #include "ardour/region_factory.h"
100 #include "ardour/route_group.h"
101 #include "ardour/send.h"
102 #include "ardour/session.h"
103 #include "ardour/session_directory.h"
104 #include "ardour/session_metadata.h"
105 #include "ardour/session_state_utils.h"
106 #include "ardour/session_playlists.h"
107 #include "ardour/session_utils.h"
108 #include "ardour/silentfilesource.h"
109 #include "ardour/slave.h"
110 #include "ardour/smf_source.h"
111 #include "ardour/sndfile_helpers.h"
112 #include "ardour/sndfilesource.h"
113 #include "ardour/source_factory.h"
114 #include "ardour/template_utils.h"
115 #include "ardour/tempo.h"
116 #include "ardour/ticker.h"
117 #include "ardour/user_bundle.h"
118 #include "ardour/utils.h"
119 #include "ardour/utils.h"
120 #include "ardour/version.h"
121 #include "ardour/playlist_factory.h"
123 #include "control_protocol/control_protocol.h"
129 using namespace ARDOUR;
133 Session::first_stage_init (string fullpath, string snapshot_name)
135 if (fullpath.length() == 0) {
137 throw failed_constructor();
140 char buf[PATH_MAX+1];
141 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
142 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
144 throw failed_constructor();
149 if (_path[_path.length()-1] != '/') {
150 _path += G_DIR_SEPARATOR;
153 if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
159 /* these two are just provisional settings. set_state()
160 will likely override them.
163 _name = _current_snapshot_name = snapshot_name;
165 set_history_depth (Config->get_history_depth());
167 _current_frame_rate = _engine.frame_rate ();
168 _nominal_frame_rate = _current_frame_rate;
169 _base_frame_rate = _current_frame_rate;
171 _tempo_map = new TempoMap (_current_frame_rate);
172 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
175 _non_soloed_outs_muted = false;
177 _solo_isolated_cnt = 0;
178 g_atomic_int_set (&processing_prohibited, 0);
179 _transport_speed = 0;
180 _last_transport_speed = 0;
181 _target_transport_speed = 0;
182 auto_play_legal = false;
183 transport_sub_state = 0;
184 _transport_frame = 0;
185 _requested_return_frame = -1;
186 _session_range_location = 0;
187 g_atomic_int_set (&_record_status, Disabled);
188 loop_changing = false;
191 _last_roll_location = 0;
192 _last_roll_or_reversal_location = 0;
193 _last_record_location = 0;
194 pending_locate_frame = 0;
195 pending_locate_roll = false;
196 pending_locate_flush = false;
197 state_was_pending = false;
199 outbound_mtc_timecode_frame = 0;
200 next_quarter_frame_to_send = -1;
201 current_block_size = 0;
202 solo_update_disabled = false;
203 _have_captured = false;
204 _worst_output_latency = 0;
205 _worst_input_latency = 0;
206 _worst_track_latency = 0;
207 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
208 _was_seamless = Config->get_seamless_loop ();
210 _send_qf_mtc = false;
211 _pframes_since_last_mtc = 0;
212 g_atomic_int_set (&_playback_load, 100);
213 g_atomic_int_set (&_capture_load, 100);
216 pending_abort = false;
217 destructive_index = 0;
218 first_file_data_format_reset = true;
219 first_file_header_format_reset = true;
220 post_export_sync = false;
223 no_questions_about_missing_files = false;
224 _speakers.reset (new Speakers);
226 AudioDiskstream::allocate_working_buffers();
228 /* default short fade = 15ms */
230 Crossfade::set_short_xfade_length ((framecnt_t) floor (config.get_short_xfade_seconds() * frame_rate()));
231 SndFileSource::setup_standard_crossfades (*this, frame_rate());
233 last_mmc_step.tv_sec = 0;
234 last_mmc_step.tv_usec = 0;
237 /* click sounds are unset by default, which causes us to internal
238 waveforms for clicks.
242 click_emphasis_length = 0;
245 process_function = &Session::process_with_events;
247 if (config.get_use_video_sync()) {
248 waiting_for_sync_offset = true;
250 waiting_for_sync_offset = false;
253 last_timecode_when = 0;
254 last_timecode_valid = false;
258 last_rr_session_dir = session_dirs.begin();
259 refresh_disk_space ();
261 /* default: assume simple stereo speaker configuration */
263 _speakers->setup_default_speakers (2);
267 average_slave_delta = 1800; // !!! why 1800 ????
268 have_first_delta_accumulator = false;
269 delta_accumulator_cnt = 0;
270 _slave_state = Stopped;
272 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
273 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
274 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
275 add_controllable (_solo_cut_control);
277 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
279 /* These are all static "per-class" signals */
281 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
282 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
283 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
284 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
285 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
287 /* stop IO objects from doing stuff until we're ready for them */
289 Delivery::disable_panners ();
290 IO::disable_connecting ();
294 Session::second_stage_init ()
296 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
299 if (load_state (_current_snapshot_name)) {
302 cleanup_stubfiles ();
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().sound_stub_path().to_string();
472 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
473 error << string_compose(_("Session: cannot create session stub sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
477 dir = session_directory().midi_path().to_string();
479 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
480 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
484 dir = session_directory().midi_stub_path().to_string();
486 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
487 error << string_compose(_("Session: cannot create session stub midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
491 dir = session_directory().dead_sound_path().to_string();
493 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
494 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
498 dir = session_directory().export_path().to_string();
500 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
501 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
505 dir = analysis_dir ();
507 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
508 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
512 dir = plugins_dir ();
514 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
515 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
522 /** Caller must not hold process lock */
524 Session::create (const string& mix_template, BusProfile* bus_profile)
526 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
527 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
531 if (ensure_subdirs ()) {
535 if (!mix_template.empty()) {
536 std::string in_path = mix_template;
538 ifstream in(in_path.c_str());
541 string out_path = _path;
543 out_path += statefile_suffix;
545 ofstream out(out_path.c_str());
553 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
559 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
566 /* Instantiate metadata */
568 _metadata = new SessionMetadata ();
570 /* set initial start + end point */
572 _state_of_the_state = Clean;
574 /* set up Master Out and Control Out if necessary */
580 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
582 if (bus_profile->master_out_channels) {
583 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
588 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
589 boost_debug_shared_ptr_mark_interesting (rt, "Route");
591 boost::shared_ptr<Route> r (rt);
593 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
594 r->input()->ensure_io (count, false, this);
595 r->output()->ensure_io (count, false, this);
597 r->set_remote_control_id (control_id++);
601 if (Config->get_use_monitor_bus()) {
602 Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO);
607 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
608 boost_debug_shared_ptr_mark_interesting (rt, "Route");
610 boost::shared_ptr<Route> r (rt);
612 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
613 r->input()->ensure_io (count, false, this);
614 r->output()->ensure_io (count, false, this);
616 r->set_remote_control_id (control_id);
622 /* prohibit auto-connect to master, because there isn't one */
623 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
627 add_routes (rl, false);
630 /* this allows the user to override settings with an environment variable.
633 if (no_auto_connect()) {
634 bus_profile->input_ac = AutoConnectOption (0);
635 bus_profile->output_ac = AutoConnectOption (0);
638 Config->set_input_auto_connect (bus_profile->input_ac);
639 Config->set_output_auto_connect (bus_profile->output_ac);
648 Session::maybe_write_autosave()
650 if (dirty() && record_status() != Recording) {
651 save_state("", true);
656 Session::remove_pending_capture_state ()
658 sys::path pending_state_file_path(_session_dir->root_path());
660 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
664 sys::remove (pending_state_file_path);
666 catch(sys::filesystem_error& ex)
668 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
669 pending_state_file_path.to_string(), ex.what()) << endmsg;
673 /** Rename a state file.
674 * @param snapshot_name Snapshot name.
677 Session::rename_state (string old_name, string new_name)
679 if (old_name == _current_snapshot_name || old_name == _name) {
680 /* refuse to rename the current snapshot or the "main" one */
684 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
685 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
687 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
688 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
692 sys::rename (old_xml_path, new_xml_path);
694 catch (const sys::filesystem_error& err)
696 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
697 old_name, new_name, err.what()) << endmsg;
701 /** Remove a state file.
702 * @param snapshot_name Snapshot name.
705 Session::remove_state (string snapshot_name)
707 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
708 // refuse to remove the current snapshot or the "main" one
712 sys::path xml_path(_session_dir->root_path());
714 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
716 if (!create_backup_file (xml_path)) {
717 // don't remove it if a backup can't be made
718 // create_backup_file will log the error.
723 sys::remove (xml_path);
726 #ifdef HAVE_JACK_SESSION
728 Session::jack_session_event (jack_session_event_t * event)
732 struct tm local_time;
735 localtime_r (&n, &local_time);
736 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
738 if (event->type == JackSessionSaveTemplate)
740 if (save_template( timebuf )) {
741 event->flags = JackSessionSaveError;
743 string cmd ("ardour3 -P -U ");
744 cmd += event->client_uuid;
748 event->command_line = strdup (cmd.c_str());
753 if (save_state (timebuf)) {
754 event->flags = JackSessionSaveError;
756 sys::path xml_path (_session_dir->root_path());
757 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
759 string cmd ("ardour3 -P -U ");
760 cmd += event->client_uuid;
762 cmd += xml_path.to_string();
765 event->command_line = strdup (cmd.c_str());
769 jack_session_reply (_engine.jack(), event);
771 if (event->type == JackSessionSaveAndQuit) {
772 Quit (); /* EMIT SIGNAL */
775 jack_session_event_free( event );
780 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
783 sys::path xml_path(_session_dir->root_path());
785 if (!_writable || (_state_of_the_state & CannotSave)) {
789 if (!_engine.connected ()) {
790 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
796 /* tell sources we're saving first, in case they write out to a new file
797 * which should be saved with the state rather than the old one */
798 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
799 i->second->session_saved();
802 tree.set_root (&get_state());
804 if (snapshot_name.empty()) {
805 snapshot_name = _current_snapshot_name;
806 } else if (switch_to_snapshot) {
807 _current_snapshot_name = snapshot_name;
812 /* proper save: use statefile_suffix (.ardour in English) */
814 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
816 /* make a backup copy of the old file */
818 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
819 // create_backup_file will log the error
825 /* pending save: use pending_suffix (.pending in English) */
826 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
829 sys::path tmp_path(_session_dir->root_path());
831 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
833 // cerr << "actually writing state to " << xml_path.to_string() << endl;
835 if (!tree.write (tmp_path.to_string())) {
836 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
837 sys::remove (tmp_path);
842 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
843 error << string_compose (_("could not rename temporary session file %1 to %2"),
844 tmp_path.to_string(), xml_path.to_string()) << endmsg;
845 sys::remove (tmp_path);
852 save_history (snapshot_name);
854 bool was_dirty = dirty();
856 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
859 DirtyChanged (); /* EMIT SIGNAL */
862 StateSaved (snapshot_name); /* EMIT SIGNAL */
869 Session::restore_state (string snapshot_name)
871 if (load_state (snapshot_name) == 0) {
872 set_state (*state_tree->root(), Stateful::loading_state_version);
879 Session::load_state (string snapshot_name)
884 state_was_pending = false;
886 /* check for leftover pending state from a crashed capture attempt */
888 sys::path xmlpath(_session_dir->root_path());
889 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
891 if (sys::exists (xmlpath)) {
893 /* there is pending state from a crashed capture attempt */
895 boost::optional<int> r = AskAboutPendingState();
896 if (r.get_value_or (1)) {
897 state_was_pending = true;
901 if (!state_was_pending) {
902 xmlpath = _session_dir->root_path();
903 xmlpath /= snapshot_name;
906 if (!sys::exists (xmlpath)) {
907 xmlpath = _session_dir->root_path();
908 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
909 if (!sys::exists (xmlpath)) {
910 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
915 state_tree = new XMLTree;
919 /* writable() really reflects the whole folder, but if for any
920 reason the session state file can't be written to, still
924 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
928 if (!state_tree->read (xmlpath.to_string())) {
929 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
935 XMLNode& root (*state_tree->root());
937 if (root.name() != X_("Session")) {
938 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
944 const XMLProperty* prop;
946 if ((prop = root.property ("version")) == 0) {
947 /* no version implies very old version of Ardour */
948 Stateful::loading_state_version = 1000;
954 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
955 Stateful::loading_state_version = (major * 1000) + minor;
958 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
960 sys::path backup_path(_session_dir->root_path());
962 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
964 // only create a backup once
965 if (sys::exists (backup_path)) {
969 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
970 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
975 sys::copy_file (xmlpath, backup_path);
977 catch(sys::filesystem_error& ex)
979 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
980 xmlpath.to_string(), ex.what())
990 Session::load_options (const XMLNode& node)
992 LocaleGuard lg (X_("POSIX"));
993 config.set_variables (node);
1004 Session::get_template()
1006 /* if we don't disable rec-enable, diskstreams
1007 will believe they need to store their capture
1008 sources in their state node.
1011 disable_record (false);
1013 return state(false);
1017 Session::state(bool full_state)
1019 XMLNode* node = new XMLNode("Session");
1022 // store libardour version, just in case
1024 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
1025 node->add_property("version", string(buf));
1027 /* store configuration settings */
1031 node->add_property ("name", _name);
1032 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1033 node->add_property ("sample-rate", buf);
1035 if (session_dirs.size() > 1) {
1039 vector<space_and_path>::iterator i = session_dirs.begin();
1040 vector<space_and_path>::iterator next;
1042 ++i; /* skip the first one */
1046 while (i != session_dirs.end()) {
1050 if (next != session_dirs.end()) {
1060 child = node->add_child ("Path");
1061 child->add_content (p);
1065 /* save the ID counter */
1067 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1068 node->add_property ("id-counter", buf);
1070 /* save the event ID counter */
1072 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1073 node->add_property ("event-counter", buf);
1075 /* various options */
1077 node->add_child_nocopy (config.get_variables ());
1079 node->add_child_nocopy (_metadata->get_state());
1081 child = node->add_child ("Sources");
1084 Glib::Mutex::Lock sl (source_lock);
1086 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1088 /* Don't save information about non-destructive file sources that are empty
1089 and unused by any regions.
1092 boost::shared_ptr<FileSource> fs;
1093 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1094 if (!fs->destructive()) {
1095 if (fs->empty() && !fs->used()) {
1101 child->add_child_nocopy (siter->second->get_state());
1105 child = node->add_child ("Regions");
1108 Glib::Mutex::Lock rl (region_lock);
1109 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1110 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1111 boost::shared_ptr<Region> r = i->second;
1112 /* only store regions not attached to playlists */
1113 if (r->playlist() == 0) {
1114 child->add_child_nocopy (r->state ());
1120 node->add_child_nocopy (_locations->get_state());
1122 // for a template, just create a new Locations, populate it
1123 // with the default start and end, and get the state for that.
1124 Locations loc (*this);
1125 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1126 range->set (max_framepos, 0);
1128 node->add_child_nocopy (loc.get_state());
1131 child = node->add_child ("Bundles");
1133 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1134 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1135 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1137 child->add_child_nocopy (b->get_state());
1142 child = node->add_child ("Routes");
1144 boost::shared_ptr<RouteList> r = routes.reader ();
1146 RoutePublicOrderSorter cmp;
1147 RouteList public_order (*r);
1148 public_order.sort (cmp);
1150 /* the sort should have put control outs first */
1153 assert (_monitor_out == public_order.front());
1156 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1157 if (!(*i)->is_hidden()) {
1159 child->add_child_nocopy ((*i)->get_state());
1161 child->add_child_nocopy ((*i)->get_template());
1167 playlists->add_state (node, full_state);
1169 child = node->add_child ("RouteGroups");
1170 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1171 child->add_child_nocopy ((*i)->get_state());
1175 child = node->add_child ("Click");
1176 child->add_child_nocopy (_click_io->state (full_state));
1180 child = node->add_child ("NamedSelections");
1181 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1183 child->add_child_nocopy ((*i)->get_state());
1188 node->add_child_nocopy (_speakers->get_state());
1189 node->add_child_nocopy (_tempo_map->get_state());
1190 node->add_child_nocopy (get_control_protocol_state());
1193 node->add_child_copy (*_extra_xml);
1200 Session::get_control_protocol_state ()
1202 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1203 return cpm.get_state();
1207 Session::set_state (const XMLNode& node, int version)
1211 const XMLProperty* prop;
1214 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1216 if (node.name() != X_("Session")) {
1217 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1221 if ((prop = node.property ("version")) != 0) {
1222 version = atoi (prop->value ()) * 1000;
1225 if ((prop = node.property ("name")) != 0) {
1226 _name = prop->value ();
1229 if ((prop = node.property (X_("sample-rate"))) != 0) {
1231 _nominal_frame_rate = atoi (prop->value());
1233 if (_nominal_frame_rate != _current_frame_rate) {
1234 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1235 if (r.get_value_or (0)) {
1241 setup_raid_path(_session_dir->root_path().to_string());
1243 if ((prop = node.property (X_("id-counter"))) != 0) {
1245 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1246 ID::init_counter (x);
1248 /* old sessions used a timebased counter, so fake
1249 the startup ID counter based on a standard
1254 ID::init_counter (now);
1257 if ((prop = node.property (X_("event-counter"))) != 0) {
1258 Evoral::init_event_id_counter (atoi (prop->value()));
1261 IO::disable_connecting ();
1263 /* Object loading order:
1268 MIDI Control // relies on data from Options/Config
1281 if ((child = find_named_node (node, "Extra")) != 0) {
1282 _extra_xml = new XMLNode (*child);
1285 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1286 load_options (*child);
1287 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1288 load_options (*child);
1290 error << _("Session: XML state has no options section") << endmsg;
1293 if (version >= 3000) {
1294 if ((child = find_named_node (node, "Metadata")) == 0) {
1295 warning << _("Session: XML state has no metadata section") << endmsg;
1296 } else if (_metadata->set_state (*child, version)) {
1301 if ((child = find_named_node (node, "Locations")) == 0) {
1302 error << _("Session: XML state has no locations section") << endmsg;
1304 } else if (_locations->set_state (*child, version)) {
1308 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1309 _speakers->set_state (*child, version);
1314 if ((location = _locations->auto_loop_location()) != 0) {
1315 set_auto_loop_location (location);
1318 if ((location = _locations->auto_punch_location()) != 0) {
1319 set_auto_punch_location (location);
1322 if ((location = _locations->session_range_location()) != 0) {
1323 delete _session_range_location;
1324 _session_range_location = location;
1327 if (_session_range_location) {
1328 AudioFileSource::set_header_position_offset (_session_range_location->start());
1331 if ((child = find_named_node (node, "Sources")) == 0) {
1332 error << _("Session: XML state has no sources section") << endmsg;
1334 } else if (load_sources (*child)) {
1338 if ((child = find_named_node (node, "Regions")) == 0) {
1339 error << _("Session: XML state has no Regions section") << endmsg;
1341 } else if (load_regions (*child)) {
1345 if ((child = find_named_node (node, "Playlists")) == 0) {
1346 error << _("Session: XML state has no playlists section") << endmsg;
1348 } else if (playlists->load (*this, *child)) {
1352 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1354 } else if (playlists->load_unused (*this, *child)) {
1358 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1359 if (load_named_selections (*child)) {
1364 if (version >= 3000) {
1365 if ((child = find_named_node (node, "Bundles")) == 0) {
1366 warning << _("Session: XML state has no bundles section") << endmsg;
1369 /* We can't load Bundles yet as they need to be able
1370 to convert from port names to Port objects, which can't happen until
1372 _bundle_xml_node = new XMLNode (*child);
1376 if ((child = find_named_node (node, "TempoMap")) == 0) {
1377 error << _("Session: XML state has no Tempo Map section") << endmsg;
1379 } else if (_tempo_map->set_state (*child, version)) {
1383 if (version < 3000) {
1384 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1385 error << _("Session: XML state has no diskstreams section") << endmsg;
1387 } else if (load_diskstreams_2X (*child, version)) {
1392 if ((child = find_named_node (node, "Routes")) == 0) {
1393 error << _("Session: XML state has no routes section") << endmsg;
1395 } else if (load_routes (*child, version)) {
1399 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1400 _diskstreams_2X.clear ();
1402 if (version >= 3000) {
1404 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1405 error << _("Session: XML state has no route groups section") << endmsg;
1407 } else if (load_route_groups (*child, version)) {
1411 } else if (version < 3000) {
1413 if ((child = find_named_node (node, "EditGroups")) == 0) {
1414 error << _("Session: XML state has no edit groups section") << endmsg;
1416 } else if (load_route_groups (*child, version)) {
1420 if ((child = find_named_node (node, "MixGroups")) == 0) {
1421 error << _("Session: XML state has no mix groups section") << endmsg;
1423 } else if (load_route_groups (*child, version)) {
1428 if ((child = find_named_node (node, "Click")) == 0) {
1429 warning << _("Session: XML state has no click section") << endmsg;
1430 } else if (_click_io) {
1431 _click_io->set_state (*child, version);
1434 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1435 ControlProtocolManager::instance().set_protocol_states (*child);
1438 /* here beginneth the second phase ... */
1440 StateReady (); /* EMIT SIGNAL */
1449 Session::load_routes (const XMLNode& node, int version)
1452 XMLNodeConstIterator niter;
1453 RouteList new_routes;
1455 nlist = node.children();
1459 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1461 boost::shared_ptr<Route> route;
1462 if (version < 3000) {
1463 route = XMLRouteFactory_2X (**niter, version);
1465 route = XMLRouteFactory (**niter, version);
1469 error << _("Session: cannot create Route from XML description.") << endmsg;
1473 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1475 new_routes.push_back (route);
1478 add_routes (new_routes, false);
1483 boost::shared_ptr<Route>
1484 Session::XMLRouteFactory (const XMLNode& node, int version)
1486 boost::shared_ptr<Route> ret;
1488 if (node.name() != "Route") {
1492 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1494 DataType type = DataType::AUDIO;
1495 const XMLProperty* prop = node.property("default-type");
1498 type = DataType (prop->value());
1501 assert (type != DataType::NIL);
1507 if (type == DataType::AUDIO) {
1508 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1511 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1514 if (track->init()) {
1519 if (track->set_state (node, version)) {
1524 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1525 boost_debug_shared_ptr_mark_interesting (track, "Track");
1530 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1532 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1533 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1534 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1545 boost::shared_ptr<Route>
1546 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1548 boost::shared_ptr<Route> ret;
1550 if (node.name() != "Route") {
1554 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1556 ds_prop = node.property (X_("diskstream"));
1559 DataType type = DataType::AUDIO;
1560 const XMLProperty* prop = node.property("default-type");
1563 type = DataType (prop->value());
1566 assert (type != DataType::NIL);
1570 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1571 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1575 if (i == _diskstreams_2X.end()) {
1576 error << _("Could not find diskstream for route") << endmsg;
1577 return boost::shared_ptr<Route> ();
1582 if (type == DataType::AUDIO) {
1583 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1586 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1589 if (track->init()) {
1594 if (track->set_state (node, version)) {
1599 track->set_diskstream (*i);
1601 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1602 boost_debug_shared_ptr_mark_interesting (track, "Track");
1607 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1609 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1610 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1611 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1623 Session::load_regions (const XMLNode& node)
1626 XMLNodeConstIterator niter;
1627 boost::shared_ptr<Region> region;
1629 nlist = node.children();
1633 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1634 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1635 error << _("Session: cannot create Region from XML description.");
1636 const XMLProperty *name = (**niter).property("name");
1639 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1649 boost::shared_ptr<Region>
1650 Session::XMLRegionFactory (const XMLNode& node, bool full)
1652 const XMLProperty* type = node.property("type");
1656 if (!type || type->value() == "audio") {
1657 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1658 } else if (type->value() == "midi") {
1659 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1662 } catch (failed_constructor& err) {
1663 return boost::shared_ptr<Region> ();
1666 return boost::shared_ptr<Region> ();
1669 boost::shared_ptr<AudioRegion>
1670 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1672 const XMLProperty* prop;
1673 boost::shared_ptr<Source> source;
1674 boost::shared_ptr<AudioSource> as;
1676 SourceList master_sources;
1677 uint32_t nchans = 1;
1680 if (node.name() != X_("Region")) {
1681 return boost::shared_ptr<AudioRegion>();
1684 if ((prop = node.property (X_("channels"))) != 0) {
1685 nchans = atoi (prop->value().c_str());
1688 if ((prop = node.property ("name")) == 0) {
1689 cerr << "no name for this region\n";
1693 if ((prop = node.property (X_("source-0"))) == 0) {
1694 if ((prop = node.property ("source")) == 0) {
1695 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1696 return boost::shared_ptr<AudioRegion>();
1700 PBD::ID s_id (prop->value());
1702 if ((source = source_by_id (s_id)) == 0) {
1703 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1704 return boost::shared_ptr<AudioRegion>();
1707 as = boost::dynamic_pointer_cast<AudioSource>(source);
1709 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1710 return boost::shared_ptr<AudioRegion>();
1713 sources.push_back (as);
1715 /* pickup other channels */
1717 for (uint32_t n=1; n < nchans; ++n) {
1718 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1719 if ((prop = node.property (buf)) != 0) {
1721 PBD::ID id2 (prop->value());
1723 if ((source = source_by_id (id2)) == 0) {
1724 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1725 return boost::shared_ptr<AudioRegion>();
1728 as = boost::dynamic_pointer_cast<AudioSource>(source);
1730 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1731 return boost::shared_ptr<AudioRegion>();
1733 sources.push_back (as);
1737 for (uint32_t n = 0; n < nchans; ++n) {
1738 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1739 if ((prop = node.property (buf)) != 0) {
1741 PBD::ID id2 (prop->value());
1743 if ((source = source_by_id (id2)) == 0) {
1744 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1745 return boost::shared_ptr<AudioRegion>();
1748 as = boost::dynamic_pointer_cast<AudioSource>(source);
1750 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1751 return boost::shared_ptr<AudioRegion>();
1753 master_sources.push_back (as);
1758 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1760 /* a final detail: this is the one and only place that we know how long missing files are */
1762 if (region->whole_file()) {
1763 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1764 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1766 sfp->set_length (region->length());
1771 if (!master_sources.empty()) {
1772 if (master_sources.size() != nchans) {
1773 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1775 region->set_master_sources (master_sources);
1783 catch (failed_constructor& err) {
1784 return boost::shared_ptr<AudioRegion>();
1788 boost::shared_ptr<MidiRegion>
1789 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1791 const XMLProperty* prop;
1792 boost::shared_ptr<Source> source;
1793 boost::shared_ptr<MidiSource> ms;
1796 if (node.name() != X_("Region")) {
1797 return boost::shared_ptr<MidiRegion>();
1800 if ((prop = node.property ("name")) == 0) {
1801 cerr << "no name for this region\n";
1805 if ((prop = node.property (X_("source-0"))) == 0) {
1806 if ((prop = node.property ("source")) == 0) {
1807 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1808 return boost::shared_ptr<MidiRegion>();
1812 PBD::ID s_id (prop->value());
1814 if ((source = source_by_id (s_id)) == 0) {
1815 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1816 return boost::shared_ptr<MidiRegion>();
1819 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1821 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1822 return boost::shared_ptr<MidiRegion>();
1825 sources.push_back (ms);
1828 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1829 /* a final detail: this is the one and only place that we know how long missing files are */
1831 if (region->whole_file()) {
1832 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1833 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1835 sfp->set_length (region->length());
1843 catch (failed_constructor& err) {
1844 return boost::shared_ptr<MidiRegion>();
1849 Session::get_sources_as_xml ()
1852 XMLNode* node = new XMLNode (X_("Sources"));
1853 Glib::Mutex::Lock lm (source_lock);
1855 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1856 node->add_child_nocopy (i->second->get_state());
1863 Session::path_from_region_name (DataType type, string name, string identifier)
1865 char buf[PATH_MAX+1];
1867 SessionDirectory sdir(get_best_session_directory_for_new_source());
1868 sys::path source_dir = ((type == DataType::AUDIO)
1869 ? sdir.sound_path() : sdir.midi_path());
1871 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1873 for (n = 0; n < 999999; ++n) {
1874 if (identifier.length()) {
1875 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1876 identifier.c_str(), n, ext.c_str());
1878 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1882 sys::path source_path = source_dir / buf;
1884 if (!sys::exists (source_path)) {
1885 return source_path.to_string();
1889 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1898 Session::load_sources (const XMLNode& node)
1901 XMLNodeConstIterator niter;
1902 boost::shared_ptr<Source> source;
1904 nlist = node.children();
1908 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1911 if ((source = XMLSourceFactory (**niter)) == 0) {
1912 error << _("Session: cannot create Source from XML description.") << endmsg;
1915 } catch (MissingSource& err) {
1919 if (!no_questions_about_missing_files) {
1920 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1925 switch (user_choice) {
1927 /* user added a new search location, so try again */
1932 /* user asked to quit the entire session load
1937 no_questions_about_missing_files = true;
1941 no_questions_about_missing_files = true;
1946 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1947 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1956 boost::shared_ptr<Source>
1957 Session::XMLSourceFactory (const XMLNode& node)
1959 if (node.name() != "Source") {
1960 return boost::shared_ptr<Source>();
1964 /* note: do peak building in another thread when loading session state */
1965 return SourceFactory::create (*this, node, true);
1968 catch (failed_constructor& err) {
1969 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1970 return boost::shared_ptr<Source>();
1975 Session::save_template (string template_name)
1979 if (_state_of_the_state & CannotSave) {
1983 sys::path user_template_dir(user_template_directory());
1987 sys::create_directories (user_template_dir);
1989 catch(sys::filesystem_error& ex)
1991 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1992 user_template_dir.to_string(), ex.what()) << endmsg;
1996 tree.set_root (&get_template());
1998 sys::path template_file_path(user_template_dir);
1999 template_file_path /= template_name + template_suffix;
2001 if (sys::exists (template_file_path))
2003 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2004 template_file_path.to_string()) << endmsg;
2008 if (!tree.write (template_file_path.to_string())) {
2009 error << _("template not saved") << endmsg;
2017 Session::rename_template (string old_name, string new_name)
2019 sys::path old_path (user_template_directory());
2020 old_path /= old_name + template_suffix;
2022 sys::path new_path(user_template_directory());
2023 new_path /= new_name + template_suffix;
2025 if (sys::exists (new_path)) {
2026 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
2027 new_path.to_string()) << endmsg;
2032 sys::rename (old_path, new_path);
2040 Session::delete_template (string name)
2042 sys::path path = user_template_directory();
2043 path /= name + template_suffix;
2054 Session::refresh_disk_space ()
2057 struct statfs statfsbuf;
2058 vector<space_and_path>::iterator i;
2059 Glib::Mutex::Lock lm (space_lock);
2062 /* get freespace on every FS that is part of the session path */
2064 _total_free_4k_blocks = 0;
2066 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2067 statfs ((*i).path.c_str(), &statfsbuf);
2069 scale = statfsbuf.f_bsize/4096.0;
2071 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2072 _total_free_4k_blocks += (*i).blocks;
2078 Session::get_best_session_directory_for_new_source ()
2080 vector<space_and_path>::iterator i;
2081 string result = _session_dir->root_path().to_string();
2083 /* handle common case without system calls */
2085 if (session_dirs.size() == 1) {
2089 /* OK, here's the algorithm we're following here:
2091 We want to select which directory to use for
2092 the next file source to be created. Ideally,
2093 we'd like to use a round-robin process so as to
2094 get maximum performance benefits from splitting
2095 the files across multiple disks.
2097 However, in situations without much diskspace, an
2098 RR approach may end up filling up a filesystem
2099 with new files while others still have space.
2100 Its therefore important to pay some attention to
2101 the freespace in the filesystem holding each
2102 directory as well. However, if we did that by
2103 itself, we'd keep creating new files in the file
2104 system with the most space until it was as full
2105 as all others, thus negating any performance
2106 benefits of this RAID-1 like approach.
2108 So, we use a user-configurable space threshold. If
2109 there are at least 2 filesystems with more than this
2110 much space available, we use RR selection between them.
2111 If not, then we pick the filesystem with the most space.
2113 This gets a good balance between the two
2117 refresh_disk_space ();
2119 int free_enough = 0;
2121 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2122 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2127 if (free_enough >= 2) {
2128 /* use RR selection process, ensuring that the one
2132 i = last_rr_session_dir;
2135 if (++i == session_dirs.end()) {
2136 i = session_dirs.begin();
2139 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2140 if (create_session_directory ((*i).path)) {
2142 last_rr_session_dir = i;
2147 } while (i != last_rr_session_dir);
2151 /* pick FS with the most freespace (and that
2152 seems to actually work ...)
2155 vector<space_and_path> sorted;
2156 space_and_path_ascending_cmp cmp;
2158 sorted = session_dirs;
2159 sort (sorted.begin(), sorted.end(), cmp);
2161 for (i = sorted.begin(); i != sorted.end(); ++i) {
2162 if (create_session_directory ((*i).path)) {
2164 last_rr_session_dir = i;
2174 Session::load_named_selections (const XMLNode& node)
2177 XMLNodeConstIterator niter;
2180 nlist = node.children();
2184 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2186 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2187 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2195 Session::XMLNamedSelectionFactory (const XMLNode& node)
2198 return new NamedSelection (*this, node);
2201 catch (failed_constructor& err) {
2207 Session::automation_dir () const
2209 return Glib::build_filename (_path, "automation");
2213 Session::analysis_dir () const
2215 return Glib::build_filename (_path, "analysis");
2219 Session::plugins_dir () const
2221 return Glib::build_filename (_path, "plugins");
2225 Session::load_bundles (XMLNode const & node)
2227 XMLNodeList nlist = node.children();
2228 XMLNodeConstIterator niter;
2232 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2233 if ((*niter)->name() == "InputBundle") {
2234 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2235 } else if ((*niter)->name() == "OutputBundle") {
2236 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2238 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2247 Session::load_route_groups (const XMLNode& node, int version)
2249 XMLNodeList nlist = node.children();
2250 XMLNodeConstIterator niter;
2254 if (version >= 3000) {
2256 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2257 if ((*niter)->name() == "RouteGroup") {
2258 RouteGroup* rg = new RouteGroup (*this, "");
2259 add_route_group (rg);
2260 rg->set_state (**niter, version);
2264 } else if (version < 3000) {
2266 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2267 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2268 RouteGroup* rg = new RouteGroup (*this, "");
2269 add_route_group (rg);
2270 rg->set_state (**niter, version);
2279 Session::auto_save()
2281 save_state (_current_snapshot_name);
2285 state_file_filter (const string &str, void */*arg*/)
2287 return (str.length() > strlen(statefile_suffix) &&
2288 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2292 bool operator()(const string* a, const string* b) {
2298 remove_end(string* state)
2300 string statename(*state);
2302 string::size_type start,end;
2303 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2304 statename = statename.substr (start+1);
2307 if ((end = statename.rfind(".ardour")) == string::npos) {
2308 end = statename.length();
2311 return new string(statename.substr (0, end));
2315 Session::possible_states (string path)
2317 PathScanner scanner;
2318 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2320 transform(states->begin(), states->end(), states->begin(), remove_end);
2323 sort (states->begin(), states->end(), cmp);
2329 Session::possible_states () const
2331 return possible_states(_path);
2335 Session::add_route_group (RouteGroup* g)
2337 _route_groups.push_back (g);
2338 route_group_added (g); /* EMIT SIGNAL */
2340 g->MembershipChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2341 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2347 Session::remove_route_group (RouteGroup& rg)
2349 list<RouteGroup*>::iterator i;
2351 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2352 _route_groups.erase (i);
2355 route_group_removed (); /* EMIT SIGNAL */
2361 Session::route_group_by_name (string name)
2363 list<RouteGroup *>::iterator i;
2365 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2366 if ((*i)->name() == name) {
2374 Session::all_route_group() const
2376 return *_all_route_group;
2380 Session::add_commands (vector<Command*> const & cmds)
2382 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2388 Session::begin_reversible_command (const string& name)
2390 begin_reversible_command (g_quark_from_string (name.c_str ()));
2393 /** Begin a reversible command using a GQuark to identify it.
2394 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2395 * but there must be as many begin...()s as there are commit...()s.
2398 Session::begin_reversible_command (GQuark q)
2400 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2401 to hold all the commands that are committed. This keeps the order of
2402 commands correct in the history.
2405 if (_current_trans == 0) {
2406 /* start a new transaction */
2407 assert (_current_trans_quarks.empty ());
2408 _current_trans = new UndoTransaction();
2409 _current_trans->set_name (g_quark_to_string (q));
2412 _current_trans_quarks.push_front (q);
2416 Session::commit_reversible_command (Command *cmd)
2418 assert (_current_trans);
2419 assert (!_current_trans_quarks.empty ());
2424 _current_trans->add_command (cmd);
2427 _current_trans_quarks.pop_front ();
2429 if (!_current_trans_quarks.empty ()) {
2430 /* the transaction we're committing is not the top-level one */
2434 if (_current_trans->empty()) {
2435 /* no commands were added to the transaction, so just get rid of it */
2436 delete _current_trans;
2441 gettimeofday (&now, 0);
2442 _current_trans->set_timestamp (now);
2444 _history.add (_current_trans);
2449 accept_all_non_peak_files (const string& path, void */*arg*/)
2451 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2455 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2459 accept_all_state_files (const string& path, void */*arg*/)
2461 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2465 Session::find_all_sources (string path, set<string>& result)
2470 if (!tree.read (path)) {
2474 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2479 XMLNodeConstIterator niter;
2481 nlist = node->children();
2485 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2489 if ((prop = (*niter)->property (X_("type"))) == 0) {
2493 DataType type (prop->value());
2495 if ((prop = (*niter)->property (X_("name"))) == 0) {
2499 if (Glib::path_is_absolute (prop->value())) {
2500 /* external file, ignore */
2508 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2509 result.insert (found_path);
2517 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2519 PathScanner scanner;
2520 vector<string*>* state_files;
2522 string this_snapshot_path;
2528 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2529 ripped = ripped.substr (0, ripped.length() - 1);
2532 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2534 if (state_files == 0) {
2539 this_snapshot_path = _path;
2540 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2541 this_snapshot_path += statefile_suffix;
2543 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2545 if (exclude_this_snapshot && **i == this_snapshot_path) {
2549 if (find_all_sources (**i, result) < 0) {
2557 struct RegionCounter {
2558 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2559 AudioSourceList::iterator iter;
2560 boost::shared_ptr<Region> region;
2563 RegionCounter() : count (0) {}
2567 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2569 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2570 return r.get_value_or (1);
2574 Session::cleanup_regions ()
2576 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2578 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2580 boost::shared_ptr<AudioRegion> audio_region = boost::dynamic_pointer_cast<AudioRegion>( i->second);
2582 if (!audio_region) {
2586 uint32_t used = playlists->region_use_count (audio_region);
2588 if (used == 0 && !audio_region->automatic()) {
2589 RegionFactory::map_remove(i->second);
2593 /* dump the history list */
2600 Session::cleanup_sources (CleanupReport& rep)
2602 // FIXME: needs adaptation to midi
2604 vector<boost::shared_ptr<Source> > dead_sources;
2605 PathScanner scanner;
2607 vector<space_and_path>::iterator i;
2608 vector<space_and_path>::iterator nexti;
2609 vector<string*>* soundfiles;
2610 vector<string> unused;
2611 set<string> all_sources;
2616 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2618 /* step 1: consider deleting all unused playlists */
2620 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2625 /* step 2: find all un-used sources */
2630 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2632 SourceMap::iterator tmp;
2637 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2641 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2642 dead_sources.push_back (i->second);
2643 i->second->drop_references ();
2649 /* build a list of all the possible sound directories for the session */
2651 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2656 SessionDirectory sdir ((*i).path);
2657 sound_path += sdir.sound_path().to_string();
2659 if (nexti != session_dirs.end()) {
2666 /* now do the same thing for the files that ended up in the sounds dir(s)
2667 but are not referenced as sources in any snapshot.
2670 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2672 if (soundfiles == 0) {
2676 /* find all sources, but don't use this snapshot because the
2677 state file on disk still references sources we may have already
2681 find_all_sources_across_snapshots (all_sources, true);
2683 /* add our current source list
2686 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2687 boost::shared_ptr<FileSource> fs;
2689 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2690 all_sources.insert (fs->path());
2694 char tmppath1[PATH_MAX+1];
2695 char tmppath2[PATH_MAX+1];
2697 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2702 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2704 if (realpath(spath.c_str(), tmppath1) == 0) {
2705 error << string_compose (_("Cannot expand path %1 (%2)"),
2706 spath, strerror (errno)) << endmsg;
2710 if (realpath((*i).c_str(), tmppath2) == 0) {
2711 error << string_compose (_("Cannot expand path %1 (%2)"),
2712 (*i), strerror (errno)) << endmsg;
2716 if (strcmp(tmppath1, tmppath2) == 0) {
2723 unused.push_back (spath);
2727 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2729 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2730 struct stat statbuf;
2732 rep.paths.push_back (*x);
2733 if (stat ((*x).c_str(), &statbuf) == 0) {
2734 rep.space += statbuf.st_size;
2739 /* don't move the file across filesystems, just
2740 stick it in the `dead_sound_dir_name' directory
2741 on whichever filesystem it was already on.
2744 if ((*x).find ("/sounds/") != string::npos) {
2746 /* old school, go up 1 level */
2748 newpath = Glib::path_get_dirname (*x); // "sounds"
2749 newpath = Glib::path_get_dirname (newpath); // "session-name"
2753 /* new school, go up 4 levels */
2755 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2756 newpath = Glib::path_get_dirname (newpath); // "session-name"
2757 newpath = Glib::path_get_dirname (newpath); // "interchange"
2758 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2761 newpath = Glib::build_filename (newpath, dead_sound_dir_name);
2763 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2764 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2768 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2770 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2772 /* the new path already exists, try versioning */
2774 char buf[PATH_MAX+1];
2778 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2781 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2782 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2786 if (version == 999) {
2787 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2791 newpath = newpath_v;
2796 /* it doesn't exist, or we can't read it or something */
2800 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2801 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2802 (*x), newpath, strerror (errno))
2807 /* see if there an easy to find peakfile for this file, and remove it.
2810 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2811 peakpath += peakfile_suffix;
2813 if (access (peakpath.c_str(), W_OK) == 0) {
2814 if (::unlink (peakpath.c_str()) != 0) {
2815 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2816 peakpath, _path, strerror (errno))
2818 /* try to back out */
2819 rename (newpath.c_str(), _path.c_str());
2827 /* dump the history list */
2831 /* save state so we don't end up a session file
2832 referring to non-existent sources.
2838 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2844 Session::cleanup_trash_sources (CleanupReport& rep)
2846 // FIXME: needs adaptation for MIDI
2848 vector<space_and_path>::iterator i;
2849 string dead_sound_dir;
2854 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2856 dead_sound_dir = (*i).path;
2857 dead_sound_dir += dead_sound_dir_name;
2859 clear_directory (dead_sound_dir, &rep.space, &rep.paths);
2866 Session::cleanup_stubfiles ()
2868 vector<space_and_path>::iterator i;
2870 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2873 string lname = legalize_for_path (_name);
2877 /* XXX this is a hack caused by semantic conflicts
2878 between space_and_path and the SessionDirectory concept.
2881 v.push_back ((*i).path);
2882 v.push_back ("interchange");
2883 v.push_back (lname);
2884 v.push_back ("audiofiles");
2885 v.push_back (stub_dir_name);
2887 dir = Glib::build_filename (v);
2889 clear_directory (dir);
2892 v.push_back ((*i).path);
2893 v.push_back ("interchange");
2894 v.push_back (lname);
2895 v.push_back ("midifiles");
2896 v.push_back (stub_dir_name);
2898 dir = Glib::build_filename (v);
2900 clear_directory (dir);
2905 Session::set_dirty ()
2907 bool was_dirty = dirty();
2909 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2913 DirtyChanged(); /* EMIT SIGNAL */
2919 Session::set_clean ()
2921 bool was_dirty = dirty();
2923 _state_of_the_state = Clean;
2927 DirtyChanged(); /* EMIT SIGNAL */
2932 Session::set_deletion_in_progress ()
2934 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2938 Session::clear_deletion_in_progress ()
2940 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2944 Session::add_controllable (boost::shared_ptr<Controllable> c)
2946 /* this adds a controllable to the list managed by the Session.
2947 this is a subset of those managed by the Controllable class
2948 itself, and represents the only ones whose state will be saved
2949 as part of the session.
2952 Glib::Mutex::Lock lm (controllables_lock);
2953 controllables.insert (c);
2956 struct null_deleter { void operator()(void const *) const {} };
2959 Session::remove_controllable (Controllable* c)
2961 if (_state_of_the_state | Deletion) {
2965 Glib::Mutex::Lock lm (controllables_lock);
2967 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2969 if (x != controllables.end()) {
2970 controllables.erase (x);
2974 boost::shared_ptr<Controllable>
2975 Session::controllable_by_id (const PBD::ID& id)
2977 Glib::Mutex::Lock lm (controllables_lock);
2979 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2980 if ((*i)->id() == id) {
2985 return boost::shared_ptr<Controllable>();
2988 boost::shared_ptr<Controllable>
2989 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2991 boost::shared_ptr<Controllable> c;
2992 boost::shared_ptr<Route> r;
2994 switch (desc.top_level_type()) {
2995 case ControllableDescriptor::NamedRoute:
2997 std::string str = desc.top_level_name();
2998 if (str == "master") {
3000 } else if (str == "control" || str == "listen") {
3003 r = route_by_name (desc.top_level_name());
3008 case ControllableDescriptor::RemoteControlID:
3009 r = route_by_remote_id (desc.rid());
3017 switch (desc.subtype()) {
3018 case ControllableDescriptor::Gain:
3019 c = r->gain_control ();
3022 case ControllableDescriptor::Solo:
3023 c = r->solo_control();
3026 case ControllableDescriptor::Mute:
3027 c = r->mute_control();
3030 case ControllableDescriptor::Recenable:
3032 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3035 c = t->rec_enable_control ();
3040 case ControllableDescriptor::PanDirection:
3042 c = r->pannable()->pan_azimuth_control;
3046 case ControllableDescriptor::PanWidth:
3048 c = r->pannable()->pan_width_control;
3052 case ControllableDescriptor::PanElevation:
3054 c = r->pannable()->pan_elevation_control;
3058 case ControllableDescriptor::Balance:
3059 /* XXX simple pan control */
3062 case ControllableDescriptor::PluginParameter:
3064 uint32_t plugin = desc.target (0);
3065 uint32_t parameter_index = desc.target (1);
3067 /* revert to zero based counting */
3073 if (parameter_index > 0) {
3077 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3080 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3081 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3086 case ControllableDescriptor::SendGain:
3088 uint32_t send = desc.target (0);
3090 /* revert to zero-based counting */
3096 boost::shared_ptr<Processor> p = r->nth_send (send);
3099 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3100 boost::shared_ptr<Amp> a = s->amp();
3103 c = s->amp()->gain_control();
3110 /* relax and return a null pointer */
3118 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3121 Stateful::add_instant_xml (node, _path);
3124 if (write_to_config) {
3125 Config->add_instant_xml (node);
3130 Session::instant_xml (const string& node_name)
3132 return Stateful::instant_xml (node_name, _path);
3136 Session::save_history (string snapshot_name)
3144 if (snapshot_name.empty()) {
3145 snapshot_name = _current_snapshot_name;
3148 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3149 const string backup_filename = history_filename + backup_suffix;
3150 const sys::path xml_path = _session_dir->root_path() / history_filename;
3151 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3153 if (sys::exists (xml_path)) {
3156 sys::rename (xml_path, backup_path);
3158 catch (const sys::filesystem_error& err)
3160 error << _("could not backup old history file, current history not saved") << endmsg;
3165 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3169 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3171 if (!tree.write (xml_path.to_string()))
3173 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3177 sys::remove (xml_path);
3178 sys::rename (backup_path, xml_path);
3180 catch (const sys::filesystem_error& err)
3182 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3183 backup_path.to_string(), err.what()) << endmsg;
3193 Session::restore_history (string snapshot_name)
3197 if (snapshot_name.empty()) {
3198 snapshot_name = _current_snapshot_name;
3201 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3202 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3204 info << "Loading history from " << xml_path.to_string() << endmsg;
3206 if (!sys::exists (xml_path)) {
3207 info << string_compose (_("%1: no history file \"%2\" for this session."),
3208 _name, xml_path.to_string()) << endmsg;
3212 if (!tree.read (xml_path.to_string())) {
3213 error << string_compose (_("Could not understand session history file \"%1\""),
3214 xml_path.to_string()) << endmsg;
3221 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3224 UndoTransaction* ut = new UndoTransaction ();
3227 ut->set_name(t->property("name")->value());
3228 stringstream ss(t->property("tv-sec")->value());
3230 ss.str(t->property("tv-usec")->value());
3232 ut->set_timestamp(tv);
3234 for (XMLNodeConstIterator child_it = t->children().begin();
3235 child_it != t->children().end(); child_it++)
3237 XMLNode *n = *child_it;
3240 if (n->name() == "MementoCommand" ||
3241 n->name() == "MementoUndoCommand" ||
3242 n->name() == "MementoRedoCommand") {
3244 if ((c = memento_command_factory(n))) {
3248 } else if (n->name() == "NoteDiffCommand") {
3249 PBD::ID id (n->property("midi-source")->value());
3250 boost::shared_ptr<MidiSource> midi_source =
3251 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3253 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3255 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3258 } else if (n->name() == "SysExDiffCommand") {
3260 PBD::ID id (n->property("midi-source")->value());
3261 boost::shared_ptr<MidiSource> midi_source =
3262 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3264 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3266 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3269 } else if (n->name() == "PatchChangeDiffCommand") {
3271 PBD::ID id (n->property("midi-source")->value());
3272 boost::shared_ptr<MidiSource> midi_source =
3273 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3275 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3277 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3280 } else if (n->name() == "StatefulDiffCommand") {
3281 if ((c = stateful_diff_command_factory (n))) {
3282 ut->add_command (c);
3285 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3296 Session::config_changed (std::string p, bool ours)
3302 if (p == "seamless-loop") {
3304 } else if (p == "rf-speed") {
3306 } else if (p == "auto-loop") {
3308 } else if (p == "auto-input") {
3310 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3311 /* auto-input only makes a difference if we're rolling */
3313 boost::shared_ptr<RouteList> rl = routes.reader ();
3314 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3315 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3316 if (tr && tr->record_enabled ()) {
3317 tr->monitor_input (!config.get_auto_input());
3322 } else if (p == "punch-in") {
3326 if ((location = _locations->auto_punch_location()) != 0) {
3328 if (config.get_punch_in ()) {
3329 replace_event (SessionEvent::PunchIn, location->start());
3331 remove_event (location->start(), SessionEvent::PunchIn);
3335 } else if (p == "punch-out") {
3339 if ((location = _locations->auto_punch_location()) != 0) {
3341 if (config.get_punch_out()) {
3342 replace_event (SessionEvent::PunchOut, location->end());
3344 clear_events (SessionEvent::PunchOut);
3348 } else if (p == "edit-mode") {
3350 Glib::Mutex::Lock lm (playlists->lock);
3352 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3353 (*i)->set_edit_mode (Config->get_edit_mode ());
3356 } else if (p == "use-video-sync") {
3358 waiting_for_sync_offset = config.get_use_video_sync();
3360 } else if (p == "mmc-control") {
3362 //poke_midi_thread ();
3364 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3366 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3368 } else if (p == "mmc-send-id") {
3370 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3372 } else if (p == "midi-control") {
3374 //poke_midi_thread ();
3376 } else if (p == "raid-path") {
3378 setup_raid_path (config.get_raid_path());
3380 } else if (p == "timecode-format") {
3384 } else if (p == "video-pullup") {
3388 } else if (p == "seamless-loop") {
3390 if (play_loop && transport_rolling()) {
3391 // to reset diskstreams etc
3392 request_play_loop (true);
3395 } else if (p == "rf-speed") {
3397 cumulative_rf_motion = 0;
3400 } else if (p == "click-sound") {
3402 setup_click_sounds (1);
3404 } else if (p == "click-emphasis-sound") {
3406 setup_click_sounds (-1);
3408 } else if (p == "clicking") {
3410 if (Config->get_clicking()) {
3411 if (_click_io && click_data) { // don't require emphasis data
3418 } else if (p == "send-mtc") {
3420 if (Config->get_send_mtc ()) {
3421 /* mark us ready to send */
3422 next_quarter_frame_to_send = 0;
3425 } else if (p == "send-mmc") {
3427 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3429 } else if (p == "midi-feedback") {
3431 session_midi_feedback = Config->get_midi_feedback();
3433 } else if (p == "jack-time-master") {
3435 engine().reset_timebase ();
3437 } else if (p == "native-file-header-format") {
3439 if (!first_file_header_format_reset) {
3440 reset_native_file_format ();
3443 first_file_header_format_reset = false;
3445 } else if (p == "native-file-data-format") {
3447 if (!first_file_data_format_reset) {
3448 reset_native_file_format ();
3451 first_file_data_format_reset = false;
3453 } else if (p == "external-sync") {
3454 if (!config.get_external_sync()) {
3455 drop_sync_source ();
3457 switch_to_sync_source (config.get_sync_source());
3459 } else if (p == "remote-model") {
3460 set_remote_control_ids ();
3461 } else if (p == "denormal-model") {
3463 } else if (p == "history-depth") {
3464 set_history_depth (Config->get_history_depth());
3465 } else if (p == "sync-all-route-ordering") {
3466 sync_order_keys ("session");
3467 } else if (p == "initial-program-change") {
3469 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3472 buf[0] = MIDI::program; // channel zero by default
3473 buf[1] = (Config->get_initial_program_change() & 0x7f);
3475 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3477 } else if (p == "solo-mute-override") {
3478 // catch_up_on_solo_mute_override ();
3479 } else if (p == "listen-position") {
3480 listen_position_changed ();
3481 } else if (p == "solo-control-is-listen-control") {
3482 solo_control_mode_changed ();
3483 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3484 last_timecode_valid = false;
3491 Session::set_history_depth (uint32_t d)
3493 _history.set_depth (d);
3497 Session::load_diskstreams_2X (XMLNode const & node, int)
3500 XMLNodeConstIterator citer;
3502 clist = node.children();
3504 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3507 /* diskstreams added automatically by DiskstreamCreated handler */
3508 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3509 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3510 _diskstreams_2X.push_back (dsp);
3512 error << _("Session: unknown diskstream type in XML") << endmsg;
3516 catch (failed_constructor& err) {
3517 error << _("Session: could not load diskstream via XML state") << endmsg;
3525 /** Connect things to the MMC object */
3527 Session::setup_midi_machine_control ()
3529 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3531 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3532 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3533 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3534 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3535 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3536 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3537 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3538 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3539 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3540 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3541 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3542 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3543 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3545 /* also handle MIDI SPP because its so common */
3547 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3548 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3549 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));
3552 boost::shared_ptr<Controllable>
3553 Session::solo_cut_control() const
3555 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3556 controls in Ardour that currently get presented to the user in the GUI that require
3557 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3559 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3560 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3564 return _solo_cut_control;