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 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
587 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
588 boost_debug_shared_ptr_mark_interesting (rt.get(), "Route");
591 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
592 r->input()->ensure_io (count, false, this);
593 r->output()->ensure_io (count, false, this);
595 r->set_remote_control_id (control_id++);
599 if (Config->get_use_monitor_bus()) {
600 boost::shared_ptr<Route> r (new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO));
604 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
605 boost_debug_shared_ptr_mark_interesting (rt, "Route");
608 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
609 r->input()->ensure_io (count, false, this);
610 r->output()->ensure_io (count, false, this);
612 r->set_remote_control_id (control_id);
618 /* prohibit auto-connect to master, because there isn't one */
619 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
623 add_routes (rl, false);
626 /* this allows the user to override settings with an environment variable.
629 if (no_auto_connect()) {
630 bus_profile->input_ac = AutoConnectOption (0);
631 bus_profile->output_ac = AutoConnectOption (0);
634 Config->set_input_auto_connect (bus_profile->input_ac);
635 Config->set_output_auto_connect (bus_profile->output_ac);
644 Session::maybe_write_autosave()
646 if (dirty() && record_status() != Recording) {
647 save_state("", true);
652 Session::remove_pending_capture_state ()
654 sys::path pending_state_file_path(_session_dir->root_path());
656 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
660 sys::remove (pending_state_file_path);
662 catch(sys::filesystem_error& ex)
664 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
665 pending_state_file_path.to_string(), ex.what()) << endmsg;
669 /** Rename a state file.
670 * @param snapshot_name Snapshot name.
673 Session::rename_state (string old_name, string new_name)
675 if (old_name == _current_snapshot_name || old_name == _name) {
676 /* refuse to rename the current snapshot or the "main" one */
680 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
681 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
683 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
684 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
688 sys::rename (old_xml_path, new_xml_path);
690 catch (const sys::filesystem_error& err)
692 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
693 old_name, new_name, err.what()) << endmsg;
697 /** Remove a state file.
698 * @param snapshot_name Snapshot name.
701 Session::remove_state (string snapshot_name)
703 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
704 // refuse to remove the current snapshot or the "main" one
708 sys::path xml_path(_session_dir->root_path());
710 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
712 if (!create_backup_file (xml_path)) {
713 // don't remove it if a backup can't be made
714 // create_backup_file will log the error.
719 sys::remove (xml_path);
722 #ifdef HAVE_JACK_SESSION
724 Session::jack_session_event (jack_session_event_t * event)
728 struct tm local_time;
731 localtime_r (&n, &local_time);
732 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
734 if (event->type == JackSessionSaveTemplate)
736 if (save_template( timebuf )) {
737 event->flags = JackSessionSaveError;
739 string cmd ("ardour3 -P -U ");
740 cmd += event->client_uuid;
744 event->command_line = strdup (cmd.c_str());
749 if (save_state (timebuf)) {
750 event->flags = JackSessionSaveError;
752 sys::path xml_path (_session_dir->root_path());
753 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
755 string cmd ("ardour3 -P -U ");
756 cmd += event->client_uuid;
758 cmd += xml_path.to_string();
761 event->command_line = strdup (cmd.c_str());
765 jack_session_reply (_engine.jack(), event);
767 if (event->type == JackSessionSaveAndQuit) {
768 Quit (); /* EMIT SIGNAL */
771 jack_session_event_free( event );
776 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
779 sys::path xml_path(_session_dir->root_path());
781 if (!_writable || (_state_of_the_state & CannotSave)) {
785 if (!_engine.connected ()) {
786 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
792 /* tell sources we're saving first, in case they write out to a new file
793 * which should be saved with the state rather than the old one */
794 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
795 i->second->session_saved();
798 tree.set_root (&get_state());
800 if (snapshot_name.empty()) {
801 snapshot_name = _current_snapshot_name;
802 } else if (switch_to_snapshot) {
803 _current_snapshot_name = snapshot_name;
808 /* proper save: use statefile_suffix (.ardour in English) */
810 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
812 /* make a backup copy of the old file */
814 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
815 // create_backup_file will log the error
821 /* pending save: use pending_suffix (.pending in English) */
822 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
825 sys::path tmp_path(_session_dir->root_path());
827 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
829 // cerr << "actually writing state to " << xml_path.to_string() << endl;
831 if (!tree.write (tmp_path.to_string())) {
832 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
833 sys::remove (tmp_path);
838 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
839 error << string_compose (_("could not rename temporary session file %1 to %2"),
840 tmp_path.to_string(), xml_path.to_string()) << endmsg;
841 sys::remove (tmp_path);
848 save_history (snapshot_name);
850 bool was_dirty = dirty();
852 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
855 DirtyChanged (); /* EMIT SIGNAL */
858 StateSaved (snapshot_name); /* EMIT SIGNAL */
865 Session::restore_state (string snapshot_name)
867 if (load_state (snapshot_name) == 0) {
868 set_state (*state_tree->root(), Stateful::loading_state_version);
875 Session::load_state (string snapshot_name)
880 state_was_pending = false;
882 /* check for leftover pending state from a crashed capture attempt */
884 sys::path xmlpath(_session_dir->root_path());
885 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
887 if (sys::exists (xmlpath)) {
889 /* there is pending state from a crashed capture attempt */
891 boost::optional<int> r = AskAboutPendingState();
892 if (r.get_value_or (1)) {
893 state_was_pending = true;
897 if (!state_was_pending) {
898 xmlpath = _session_dir->root_path();
899 xmlpath /= snapshot_name;
902 if (!sys::exists (xmlpath)) {
903 xmlpath = _session_dir->root_path();
904 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
905 if (!sys::exists (xmlpath)) {
906 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
911 state_tree = new XMLTree;
915 /* writable() really reflects the whole folder, but if for any
916 reason the session state file can't be written to, still
920 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
924 if (!state_tree->read (xmlpath.to_string())) {
925 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
931 XMLNode& root (*state_tree->root());
933 if (root.name() != X_("Session")) {
934 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
940 const XMLProperty* prop;
942 if ((prop = root.property ("version")) == 0) {
943 /* no version implies very old version of Ardour */
944 Stateful::loading_state_version = 1000;
950 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
951 Stateful::loading_state_version = (major * 1000) + minor;
954 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
956 sys::path backup_path(_session_dir->root_path());
958 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
960 // only create a backup once
961 if (sys::exists (backup_path)) {
965 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
966 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
971 sys::copy_file (xmlpath, backup_path);
973 catch(sys::filesystem_error& ex)
975 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
976 xmlpath.to_string(), ex.what())
986 Session::load_options (const XMLNode& node)
988 LocaleGuard lg (X_("POSIX"));
989 config.set_variables (node);
1000 Session::get_template()
1002 /* if we don't disable rec-enable, diskstreams
1003 will believe they need to store their capture
1004 sources in their state node.
1007 disable_record (false);
1009 return state(false);
1013 Session::state(bool full_state)
1015 XMLNode* node = new XMLNode("Session");
1018 // store libardour version, just in case
1020 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
1021 node->add_property("version", string(buf));
1023 /* store configuration settings */
1027 node->add_property ("name", _name);
1028 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1029 node->add_property ("sample-rate", buf);
1031 if (session_dirs.size() > 1) {
1035 vector<space_and_path>::iterator i = session_dirs.begin();
1036 vector<space_and_path>::iterator next;
1038 ++i; /* skip the first one */
1042 while (i != session_dirs.end()) {
1046 if (next != session_dirs.end()) {
1056 child = node->add_child ("Path");
1057 child->add_content (p);
1061 /* save the ID counter */
1063 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1064 node->add_property ("id-counter", buf);
1066 /* save the event ID counter */
1068 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1069 node->add_property ("event-counter", buf);
1071 /* various options */
1073 node->add_child_nocopy (config.get_variables ());
1075 node->add_child_nocopy (_metadata->get_state());
1077 child = node->add_child ("Sources");
1080 Glib::Mutex::Lock sl (source_lock);
1082 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1084 /* Don't save information about non-destructive file sources that are empty
1085 and unused by any regions.
1088 boost::shared_ptr<FileSource> fs;
1089 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1090 if (!fs->destructive()) {
1091 if (fs->empty() && !fs->used()) {
1097 child->add_child_nocopy (siter->second->get_state());
1101 child = node->add_child ("Regions");
1104 Glib::Mutex::Lock rl (region_lock);
1105 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1106 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1107 boost::shared_ptr<Region> r = i->second;
1108 /* only store regions not attached to playlists */
1109 if (r->playlist() == 0) {
1110 child->add_child_nocopy (r->state ());
1116 node->add_child_nocopy (_locations->get_state());
1118 // for a template, just create a new Locations, populate it
1119 // with the default start and end, and get the state for that.
1120 Locations loc (*this);
1121 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1122 range->set (max_framepos, 0);
1124 node->add_child_nocopy (loc.get_state());
1127 child = node->add_child ("Bundles");
1129 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1130 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1131 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1133 child->add_child_nocopy (b->get_state());
1138 child = node->add_child ("Routes");
1140 boost::shared_ptr<RouteList> r = routes.reader ();
1142 RoutePublicOrderSorter cmp;
1143 RouteList public_order (*r);
1144 public_order.sort (cmp);
1146 /* the sort should have put control outs first */
1149 assert (_monitor_out == public_order.front());
1152 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1153 if (!(*i)->is_hidden()) {
1155 child->add_child_nocopy ((*i)->get_state());
1157 child->add_child_nocopy ((*i)->get_template());
1163 playlists->add_state (node, full_state);
1165 child = node->add_child ("RouteGroups");
1166 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1167 child->add_child_nocopy ((*i)->get_state());
1171 child = node->add_child ("Click");
1172 child->add_child_nocopy (_click_io->state (full_state));
1176 child = node->add_child ("NamedSelections");
1177 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1179 child->add_child_nocopy ((*i)->get_state());
1184 node->add_child_nocopy (_speakers->get_state());
1185 node->add_child_nocopy (_tempo_map->get_state());
1186 node->add_child_nocopy (get_control_protocol_state());
1189 node->add_child_copy (*_extra_xml);
1196 Session::get_control_protocol_state ()
1198 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1199 return cpm.get_state();
1203 Session::set_state (const XMLNode& node, int version)
1207 const XMLProperty* prop;
1210 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1212 if (node.name() != X_("Session")) {
1213 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1217 if ((prop = node.property ("version")) != 0) {
1218 version = atoi (prop->value ()) * 1000;
1221 if ((prop = node.property ("name")) != 0) {
1222 _name = prop->value ();
1225 if ((prop = node.property (X_("sample-rate"))) != 0) {
1227 _nominal_frame_rate = atoi (prop->value());
1229 if (_nominal_frame_rate != _current_frame_rate) {
1230 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1231 if (r.get_value_or (0)) {
1237 setup_raid_path(_session_dir->root_path().to_string());
1239 if ((prop = node.property (X_("id-counter"))) != 0) {
1241 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1242 ID::init_counter (x);
1244 /* old sessions used a timebased counter, so fake
1245 the startup ID counter based on a standard
1250 ID::init_counter (now);
1253 if ((prop = node.property (X_("event-counter"))) != 0) {
1254 Evoral::init_event_id_counter (atoi (prop->value()));
1257 IO::disable_connecting ();
1259 /* Object loading order:
1264 MIDI Control // relies on data from Options/Config
1277 if ((child = find_named_node (node, "Extra")) != 0) {
1278 _extra_xml = new XMLNode (*child);
1281 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1282 load_options (*child);
1283 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1284 load_options (*child);
1286 error << _("Session: XML state has no options section") << endmsg;
1289 if (version >= 3000) {
1290 if ((child = find_named_node (node, "Metadata")) == 0) {
1291 warning << _("Session: XML state has no metadata section") << endmsg;
1292 } else if (_metadata->set_state (*child, version)) {
1297 if ((child = find_named_node (node, "Locations")) == 0) {
1298 error << _("Session: XML state has no locations section") << endmsg;
1300 } else if (_locations->set_state (*child, version)) {
1304 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1305 _speakers->set_state (*child, version);
1310 if ((location = _locations->auto_loop_location()) != 0) {
1311 set_auto_loop_location (location);
1314 if ((location = _locations->auto_punch_location()) != 0) {
1315 set_auto_punch_location (location);
1318 if ((location = _locations->session_range_location()) != 0) {
1319 delete _session_range_location;
1320 _session_range_location = location;
1323 if (_session_range_location) {
1324 AudioFileSource::set_header_position_offset (_session_range_location->start());
1327 if ((child = find_named_node (node, "Sources")) == 0) {
1328 error << _("Session: XML state has no sources section") << endmsg;
1330 } else if (load_sources (*child)) {
1334 if ((child = find_named_node (node, "Regions")) == 0) {
1335 error << _("Session: XML state has no Regions section") << endmsg;
1337 } else if (load_regions (*child)) {
1341 if ((child = find_named_node (node, "Playlists")) == 0) {
1342 error << _("Session: XML state has no playlists section") << endmsg;
1344 } else if (playlists->load (*this, *child)) {
1348 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1350 } else if (playlists->load_unused (*this, *child)) {
1354 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1355 if (load_named_selections (*child)) {
1360 if (version >= 3000) {
1361 if ((child = find_named_node (node, "Bundles")) == 0) {
1362 warning << _("Session: XML state has no bundles section") << endmsg;
1365 /* We can't load Bundles yet as they need to be able
1366 to convert from port names to Port objects, which can't happen until
1368 _bundle_xml_node = new XMLNode (*child);
1372 if ((child = find_named_node (node, "TempoMap")) == 0) {
1373 error << _("Session: XML state has no Tempo Map section") << endmsg;
1375 } else if (_tempo_map->set_state (*child, version)) {
1379 if (version < 3000) {
1380 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1381 error << _("Session: XML state has no diskstreams section") << endmsg;
1383 } else if (load_diskstreams_2X (*child, version)) {
1388 if ((child = find_named_node (node, "Routes")) == 0) {
1389 error << _("Session: XML state has no routes section") << endmsg;
1391 } else if (load_routes (*child, version)) {
1395 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1396 _diskstreams_2X.clear ();
1398 if (version >= 3000) {
1400 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1401 error << _("Session: XML state has no route groups section") << endmsg;
1403 } else if (load_route_groups (*child, version)) {
1407 } else if (version < 3000) {
1409 if ((child = find_named_node (node, "EditGroups")) == 0) {
1410 error << _("Session: XML state has no edit groups section") << endmsg;
1412 } else if (load_route_groups (*child, version)) {
1416 if ((child = find_named_node (node, "MixGroups")) == 0) {
1417 error << _("Session: XML state has no mix groups section") << endmsg;
1419 } else if (load_route_groups (*child, version)) {
1424 if ((child = find_named_node (node, "Click")) == 0) {
1425 warning << _("Session: XML state has no click section") << endmsg;
1426 } else if (_click_io) {
1427 _click_io->set_state (*child, version);
1430 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1431 ControlProtocolManager::instance().set_protocol_states (*child);
1434 /* here beginneth the second phase ... */
1436 StateReady (); /* EMIT SIGNAL */
1445 Session::load_routes (const XMLNode& node, int version)
1448 XMLNodeConstIterator niter;
1449 RouteList new_routes;
1451 nlist = node.children();
1455 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1457 boost::shared_ptr<Route> route;
1458 if (version < 3000) {
1459 route = XMLRouteFactory_2X (**niter, version);
1461 route = XMLRouteFactory (**niter, version);
1465 error << _("Session: cannot create Route from XML description.") << endmsg;
1469 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1471 new_routes.push_back (route);
1474 add_routes (new_routes, false);
1479 boost::shared_ptr<Route>
1480 Session::XMLRouteFactory (const XMLNode& node, int version)
1482 boost::shared_ptr<Route> ret;
1484 if (node.name() != "Route") {
1488 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1490 DataType type = DataType::AUDIO;
1491 const XMLProperty* prop = node.property("default-type");
1494 type = DataType (prop->value());
1497 assert (type != DataType::NIL);
1501 boost::shared_ptr<Track> track;
1503 if (type == DataType::AUDIO) {
1504 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1506 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1509 if (track->init()) {
1513 if (track->set_state (node, version)) {
1517 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1518 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1523 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1525 if (r->init () == 0 && r->set_state (node, version) == 0) {
1526 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1527 boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1536 boost::shared_ptr<Route>
1537 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1539 boost::shared_ptr<Route> ret;
1541 if (node.name() != "Route") {
1545 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1547 ds_prop = node.property (X_("diskstream"));
1550 DataType type = DataType::AUDIO;
1551 const XMLProperty* prop = node.property("default-type");
1554 type = DataType (prop->value());
1557 assert (type != DataType::NIL);
1561 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1562 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1566 if (i == _diskstreams_2X.end()) {
1567 error << _("Could not find diskstream for route") << endmsg;
1568 return boost::shared_ptr<Route> ();
1571 boost::shared_ptr<Track> track;
1573 if (type == DataType::AUDIO) {
1574 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1576 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1579 if (track->init()) {
1583 if (track->set_state (node, version)) {
1587 track->set_diskstream (*i);
1589 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1590 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1595 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1597 if (r->init () == 0 && r->set_state (node, version) == 0) {
1598 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1599 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1609 Session::load_regions (const XMLNode& node)
1612 XMLNodeConstIterator niter;
1613 boost::shared_ptr<Region> region;
1615 nlist = node.children();
1619 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1620 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1621 error << _("Session: cannot create Region from XML description.");
1622 const XMLProperty *name = (**niter).property("name");
1625 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1635 boost::shared_ptr<Region>
1636 Session::XMLRegionFactory (const XMLNode& node, bool full)
1638 const XMLProperty* type = node.property("type");
1642 if (!type || type->value() == "audio") {
1643 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1644 } else if (type->value() == "midi") {
1645 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1648 } catch (failed_constructor& err) {
1649 return boost::shared_ptr<Region> ();
1652 return boost::shared_ptr<Region> ();
1655 boost::shared_ptr<AudioRegion>
1656 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1658 const XMLProperty* prop;
1659 boost::shared_ptr<Source> source;
1660 boost::shared_ptr<AudioSource> as;
1662 SourceList master_sources;
1663 uint32_t nchans = 1;
1666 if (node.name() != X_("Region")) {
1667 return boost::shared_ptr<AudioRegion>();
1670 if ((prop = node.property (X_("channels"))) != 0) {
1671 nchans = atoi (prop->value().c_str());
1674 if ((prop = node.property ("name")) == 0) {
1675 cerr << "no name for this region\n";
1679 if ((prop = node.property (X_("source-0"))) == 0) {
1680 if ((prop = node.property ("source")) == 0) {
1681 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1682 return boost::shared_ptr<AudioRegion>();
1686 PBD::ID s_id (prop->value());
1688 if ((source = source_by_id (s_id)) == 0) {
1689 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1690 return boost::shared_ptr<AudioRegion>();
1693 as = boost::dynamic_pointer_cast<AudioSource>(source);
1695 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1696 return boost::shared_ptr<AudioRegion>();
1699 sources.push_back (as);
1701 /* pickup other channels */
1703 for (uint32_t n=1; n < nchans; ++n) {
1704 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1705 if ((prop = node.property (buf)) != 0) {
1707 PBD::ID id2 (prop->value());
1709 if ((source = source_by_id (id2)) == 0) {
1710 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1711 return boost::shared_ptr<AudioRegion>();
1714 as = boost::dynamic_pointer_cast<AudioSource>(source);
1716 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1717 return boost::shared_ptr<AudioRegion>();
1719 sources.push_back (as);
1723 for (uint32_t n = 0; n < nchans; ++n) {
1724 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1725 if ((prop = node.property (buf)) != 0) {
1727 PBD::ID id2 (prop->value());
1729 if ((source = source_by_id (id2)) == 0) {
1730 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1731 return boost::shared_ptr<AudioRegion>();
1734 as = boost::dynamic_pointer_cast<AudioSource>(source);
1736 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1737 return boost::shared_ptr<AudioRegion>();
1739 master_sources.push_back (as);
1744 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1746 /* a final detail: this is the one and only place that we know how long missing files are */
1748 if (region->whole_file()) {
1749 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1750 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1752 sfp->set_length (region->length());
1757 if (!master_sources.empty()) {
1758 if (master_sources.size() != nchans) {
1759 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1761 region->set_master_sources (master_sources);
1769 catch (failed_constructor& err) {
1770 return boost::shared_ptr<AudioRegion>();
1774 boost::shared_ptr<MidiRegion>
1775 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1777 const XMLProperty* prop;
1778 boost::shared_ptr<Source> source;
1779 boost::shared_ptr<MidiSource> ms;
1782 if (node.name() != X_("Region")) {
1783 return boost::shared_ptr<MidiRegion>();
1786 if ((prop = node.property ("name")) == 0) {
1787 cerr << "no name for this region\n";
1791 if ((prop = node.property (X_("source-0"))) == 0) {
1792 if ((prop = node.property ("source")) == 0) {
1793 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1794 return boost::shared_ptr<MidiRegion>();
1798 PBD::ID s_id (prop->value());
1800 if ((source = source_by_id (s_id)) == 0) {
1801 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1802 return boost::shared_ptr<MidiRegion>();
1805 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1807 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1808 return boost::shared_ptr<MidiRegion>();
1811 sources.push_back (ms);
1814 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1815 /* a final detail: this is the one and only place that we know how long missing files are */
1817 if (region->whole_file()) {
1818 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1819 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1821 sfp->set_length (region->length());
1829 catch (failed_constructor& err) {
1830 return boost::shared_ptr<MidiRegion>();
1835 Session::get_sources_as_xml ()
1838 XMLNode* node = new XMLNode (X_("Sources"));
1839 Glib::Mutex::Lock lm (source_lock);
1841 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1842 node->add_child_nocopy (i->second->get_state());
1849 Session::path_from_region_name (DataType type, string name, string identifier)
1851 char buf[PATH_MAX+1];
1853 SessionDirectory sdir(get_best_session_directory_for_new_source());
1854 sys::path source_dir = ((type == DataType::AUDIO)
1855 ? sdir.sound_path() : sdir.midi_path());
1857 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1859 for (n = 0; n < 999999; ++n) {
1860 if (identifier.length()) {
1861 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1862 identifier.c_str(), n, ext.c_str());
1864 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1868 sys::path source_path = source_dir / buf;
1870 if (!sys::exists (source_path)) {
1871 return source_path.to_string();
1875 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1884 Session::load_sources (const XMLNode& node)
1887 XMLNodeConstIterator niter;
1888 boost::shared_ptr<Source> source;
1890 nlist = node.children();
1894 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1897 if ((source = XMLSourceFactory (**niter)) == 0) {
1898 error << _("Session: cannot create Source from XML description.") << endmsg;
1901 } catch (MissingSource& err) {
1905 if (!no_questions_about_missing_files) {
1906 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1911 switch (user_choice) {
1913 /* user added a new search location, so try again */
1918 /* user asked to quit the entire session load
1923 no_questions_about_missing_files = true;
1927 no_questions_about_missing_files = true;
1932 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1933 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1942 boost::shared_ptr<Source>
1943 Session::XMLSourceFactory (const XMLNode& node)
1945 if (node.name() != "Source") {
1946 return boost::shared_ptr<Source>();
1950 /* note: do peak building in another thread when loading session state */
1951 return SourceFactory::create (*this, node, true);
1954 catch (failed_constructor& err) {
1955 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1956 return boost::shared_ptr<Source>();
1961 Session::save_template (string template_name)
1965 if (_state_of_the_state & CannotSave) {
1969 sys::path user_template_dir(user_template_directory());
1973 sys::create_directories (user_template_dir);
1975 catch(sys::filesystem_error& ex)
1977 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1978 user_template_dir.to_string(), ex.what()) << endmsg;
1982 tree.set_root (&get_template());
1984 sys::path template_file_path(user_template_dir);
1985 template_file_path /= template_name + template_suffix;
1987 if (sys::exists (template_file_path))
1989 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1990 template_file_path.to_string()) << endmsg;
1994 if (!tree.write (template_file_path.to_string())) {
1995 error << _("template not saved") << endmsg;
2003 Session::rename_template (string old_name, string new_name)
2005 sys::path old_path (user_template_directory());
2006 old_path /= old_name + template_suffix;
2008 sys::path new_path(user_template_directory());
2009 new_path /= new_name + template_suffix;
2011 if (sys::exists (new_path)) {
2012 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
2013 new_path.to_string()) << endmsg;
2018 sys::rename (old_path, new_path);
2026 Session::delete_template (string name)
2028 sys::path path = user_template_directory();
2029 path /= name + template_suffix;
2040 Session::refresh_disk_space ()
2043 struct statfs statfsbuf;
2044 vector<space_and_path>::iterator i;
2045 Glib::Mutex::Lock lm (space_lock);
2048 /* get freespace on every FS that is part of the session path */
2050 _total_free_4k_blocks = 0;
2052 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2053 statfs ((*i).path.c_str(), &statfsbuf);
2055 scale = statfsbuf.f_bsize/4096.0;
2057 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2058 _total_free_4k_blocks += (*i).blocks;
2064 Session::get_best_session_directory_for_new_source ()
2066 vector<space_and_path>::iterator i;
2067 string result = _session_dir->root_path().to_string();
2069 /* handle common case without system calls */
2071 if (session_dirs.size() == 1) {
2075 /* OK, here's the algorithm we're following here:
2077 We want to select which directory to use for
2078 the next file source to be created. Ideally,
2079 we'd like to use a round-robin process so as to
2080 get maximum performance benefits from splitting
2081 the files across multiple disks.
2083 However, in situations without much diskspace, an
2084 RR approach may end up filling up a filesystem
2085 with new files while others still have space.
2086 Its therefore important to pay some attention to
2087 the freespace in the filesystem holding each
2088 directory as well. However, if we did that by
2089 itself, we'd keep creating new files in the file
2090 system with the most space until it was as full
2091 as all others, thus negating any performance
2092 benefits of this RAID-1 like approach.
2094 So, we use a user-configurable space threshold. If
2095 there are at least 2 filesystems with more than this
2096 much space available, we use RR selection between them.
2097 If not, then we pick the filesystem with the most space.
2099 This gets a good balance between the two
2103 refresh_disk_space ();
2105 int free_enough = 0;
2107 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2108 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2113 if (free_enough >= 2) {
2114 /* use RR selection process, ensuring that the one
2118 i = last_rr_session_dir;
2121 if (++i == session_dirs.end()) {
2122 i = session_dirs.begin();
2125 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2126 if (create_session_directory ((*i).path)) {
2128 last_rr_session_dir = i;
2133 } while (i != last_rr_session_dir);
2137 /* pick FS with the most freespace (and that
2138 seems to actually work ...)
2141 vector<space_and_path> sorted;
2142 space_and_path_ascending_cmp cmp;
2144 sorted = session_dirs;
2145 sort (sorted.begin(), sorted.end(), cmp);
2147 for (i = sorted.begin(); i != sorted.end(); ++i) {
2148 if (create_session_directory ((*i).path)) {
2150 last_rr_session_dir = i;
2160 Session::load_named_selections (const XMLNode& node)
2163 XMLNodeConstIterator niter;
2166 nlist = node.children();
2170 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2172 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2173 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2181 Session::XMLNamedSelectionFactory (const XMLNode& node)
2184 return new NamedSelection (*this, node);
2187 catch (failed_constructor& err) {
2193 Session::automation_dir () const
2195 return Glib::build_filename (_path, "automation");
2199 Session::analysis_dir () const
2201 return Glib::build_filename (_path, "analysis");
2205 Session::plugins_dir () const
2207 return Glib::build_filename (_path, "plugins");
2211 Session::load_bundles (XMLNode const & node)
2213 XMLNodeList nlist = node.children();
2214 XMLNodeConstIterator niter;
2218 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2219 if ((*niter)->name() == "InputBundle") {
2220 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2221 } else if ((*niter)->name() == "OutputBundle") {
2222 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2224 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2233 Session::load_route_groups (const XMLNode& node, int version)
2235 XMLNodeList nlist = node.children();
2236 XMLNodeConstIterator niter;
2240 if (version >= 3000) {
2242 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2243 if ((*niter)->name() == "RouteGroup") {
2244 RouteGroup* rg = new RouteGroup (*this, "");
2245 add_route_group (rg);
2246 rg->set_state (**niter, version);
2250 } else if (version < 3000) {
2252 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2253 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2254 RouteGroup* rg = new RouteGroup (*this, "");
2255 add_route_group (rg);
2256 rg->set_state (**niter, version);
2265 Session::auto_save()
2267 save_state (_current_snapshot_name);
2271 state_file_filter (const string &str, void */*arg*/)
2273 return (str.length() > strlen(statefile_suffix) &&
2274 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2278 bool operator()(const string* a, const string* b) {
2284 remove_end(string* state)
2286 string statename(*state);
2288 string::size_type start,end;
2289 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2290 statename = statename.substr (start+1);
2293 if ((end = statename.rfind(".ardour")) == string::npos) {
2294 end = statename.length();
2297 return new string(statename.substr (0, end));
2301 Session::possible_states (string path)
2303 PathScanner scanner;
2304 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2306 transform(states->begin(), states->end(), states->begin(), remove_end);
2309 sort (states->begin(), states->end(), cmp);
2315 Session::possible_states () const
2317 return possible_states(_path);
2321 Session::add_route_group (RouteGroup* g)
2323 _route_groups.push_back (g);
2324 route_group_added (g); /* EMIT SIGNAL */
2326 g->MembershipChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2327 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2333 Session::remove_route_group (RouteGroup& rg)
2335 list<RouteGroup*>::iterator i;
2337 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2338 _route_groups.erase (i);
2341 route_group_removed (); /* EMIT SIGNAL */
2347 Session::route_group_by_name (string name)
2349 list<RouteGroup *>::iterator i;
2351 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2352 if ((*i)->name() == name) {
2360 Session::all_route_group() const
2362 return *_all_route_group;
2366 Session::add_commands (vector<Command*> const & cmds)
2368 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2374 Session::begin_reversible_command (const string& name)
2376 begin_reversible_command (g_quark_from_string (name.c_str ()));
2379 /** Begin a reversible command using a GQuark to identify it.
2380 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2381 * but there must be as many begin...()s as there are commit...()s.
2384 Session::begin_reversible_command (GQuark q)
2386 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2387 to hold all the commands that are committed. This keeps the order of
2388 commands correct in the history.
2391 if (_current_trans == 0) {
2392 /* start a new transaction */
2393 assert (_current_trans_quarks.empty ());
2394 _current_trans = new UndoTransaction();
2395 _current_trans->set_name (g_quark_to_string (q));
2398 _current_trans_quarks.push_front (q);
2402 Session::commit_reversible_command (Command *cmd)
2404 assert (_current_trans);
2405 assert (!_current_trans_quarks.empty ());
2410 _current_trans->add_command (cmd);
2413 _current_trans_quarks.pop_front ();
2415 if (!_current_trans_quarks.empty ()) {
2416 /* the transaction we're committing is not the top-level one */
2420 if (_current_trans->empty()) {
2421 /* no commands were added to the transaction, so just get rid of it */
2422 delete _current_trans;
2427 gettimeofday (&now, 0);
2428 _current_trans->set_timestamp (now);
2430 _history.add (_current_trans);
2435 accept_all_non_peak_files (const string& path, void */*arg*/)
2437 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2441 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2445 accept_all_state_files (const string& path, void */*arg*/)
2447 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2451 Session::find_all_sources (string path, set<string>& result)
2456 if (!tree.read (path)) {
2460 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2465 XMLNodeConstIterator niter;
2467 nlist = node->children();
2471 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2475 if ((prop = (*niter)->property (X_("type"))) == 0) {
2479 DataType type (prop->value());
2481 if ((prop = (*niter)->property (X_("name"))) == 0) {
2485 if (Glib::path_is_absolute (prop->value())) {
2486 /* external file, ignore */
2494 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2495 result.insert (found_path);
2503 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2505 PathScanner scanner;
2506 vector<string*>* state_files;
2508 string this_snapshot_path;
2514 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2515 ripped = ripped.substr (0, ripped.length() - 1);
2518 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2520 if (state_files == 0) {
2525 this_snapshot_path = _path;
2526 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2527 this_snapshot_path += statefile_suffix;
2529 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2531 if (exclude_this_snapshot && **i == this_snapshot_path) {
2535 if (find_all_sources (**i, result) < 0) {
2543 struct RegionCounter {
2544 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2545 AudioSourceList::iterator iter;
2546 boost::shared_ptr<Region> region;
2549 RegionCounter() : count (0) {}
2553 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2555 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2556 return r.get_value_or (1);
2560 Session::cleanup_regions ()
2562 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2564 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2566 boost::shared_ptr<AudioRegion> audio_region = boost::dynamic_pointer_cast<AudioRegion>( i->second);
2568 if (!audio_region) {
2572 uint32_t used = playlists->region_use_count (audio_region);
2574 if (used == 0 && !audio_region->automatic()) {
2575 RegionFactory::map_remove(i->second);
2579 /* dump the history list */
2586 Session::cleanup_sources (CleanupReport& rep)
2588 // FIXME: needs adaptation to midi
2590 vector<boost::shared_ptr<Source> > dead_sources;
2591 PathScanner scanner;
2593 vector<space_and_path>::iterator i;
2594 vector<space_and_path>::iterator nexti;
2595 vector<string*>* soundfiles;
2596 vector<string> unused;
2597 set<string> all_sources;
2602 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2604 /* step 1: consider deleting all unused playlists */
2606 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2611 /* step 2: find all un-used sources */
2616 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2618 SourceMap::iterator tmp;
2623 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2627 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2628 dead_sources.push_back (i->second);
2629 i->second->drop_references ();
2635 /* build a list of all the possible sound directories for the session */
2637 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2642 SessionDirectory sdir ((*i).path);
2643 sound_path += sdir.sound_path().to_string();
2645 if (nexti != session_dirs.end()) {
2652 /* now do the same thing for the files that ended up in the sounds dir(s)
2653 but are not referenced as sources in any snapshot.
2656 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2658 if (soundfiles == 0) {
2662 /* find all sources, but don't use this snapshot because the
2663 state file on disk still references sources we may have already
2667 find_all_sources_across_snapshots (all_sources, true);
2669 /* add our current source list
2672 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2673 boost::shared_ptr<FileSource> fs;
2675 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2676 all_sources.insert (fs->path());
2680 char tmppath1[PATH_MAX+1];
2681 char tmppath2[PATH_MAX+1];
2683 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2688 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2690 if (realpath(spath.c_str(), tmppath1) == 0) {
2691 error << string_compose (_("Cannot expand path %1 (%2)"),
2692 spath, strerror (errno)) << endmsg;
2696 if (realpath((*i).c_str(), tmppath2) == 0) {
2697 error << string_compose (_("Cannot expand path %1 (%2)"),
2698 (*i), strerror (errno)) << endmsg;
2702 if (strcmp(tmppath1, tmppath2) == 0) {
2709 unused.push_back (spath);
2713 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2715 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2716 struct stat statbuf;
2718 rep.paths.push_back (*x);
2719 if (stat ((*x).c_str(), &statbuf) == 0) {
2720 rep.space += statbuf.st_size;
2725 /* don't move the file across filesystems, just
2726 stick it in the `dead_sound_dir_name' directory
2727 on whichever filesystem it was already on.
2730 if ((*x).find ("/sounds/") != string::npos) {
2732 /* old school, go up 1 level */
2734 newpath = Glib::path_get_dirname (*x); // "sounds"
2735 newpath = Glib::path_get_dirname (newpath); // "session-name"
2739 /* new school, go up 4 levels */
2741 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2742 newpath = Glib::path_get_dirname (newpath); // "session-name"
2743 newpath = Glib::path_get_dirname (newpath); // "interchange"
2744 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2747 newpath = Glib::build_filename (newpath, dead_sound_dir_name);
2749 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2750 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2754 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2756 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2758 /* the new path already exists, try versioning */
2760 char buf[PATH_MAX+1];
2764 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2767 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2768 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2772 if (version == 999) {
2773 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2777 newpath = newpath_v;
2782 /* it doesn't exist, or we can't read it or something */
2786 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2787 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2788 (*x), newpath, strerror (errno))
2793 /* see if there an easy to find peakfile for this file, and remove it.
2796 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2797 peakpath += peakfile_suffix;
2799 if (access (peakpath.c_str(), W_OK) == 0) {
2800 if (::unlink (peakpath.c_str()) != 0) {
2801 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2802 peakpath, _path, strerror (errno))
2804 /* try to back out */
2805 rename (newpath.c_str(), _path.c_str());
2813 /* dump the history list */
2817 /* save state so we don't end up a session file
2818 referring to non-existent sources.
2824 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2830 Session::cleanup_trash_sources (CleanupReport& rep)
2832 // FIXME: needs adaptation for MIDI
2834 vector<space_and_path>::iterator i;
2835 string dead_sound_dir;
2840 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2842 dead_sound_dir = (*i).path;
2843 dead_sound_dir += dead_sound_dir_name;
2845 clear_directory (dead_sound_dir, &rep.space, &rep.paths);
2852 Session::cleanup_stubfiles ()
2854 vector<space_and_path>::iterator i;
2856 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2859 string lname = legalize_for_path (_name);
2863 /* XXX this is a hack caused by semantic conflicts
2864 between space_and_path and the SessionDirectory concept.
2867 v.push_back ((*i).path);
2868 v.push_back ("interchange");
2869 v.push_back (lname);
2870 v.push_back ("audiofiles");
2871 v.push_back (stub_dir_name);
2873 dir = Glib::build_filename (v);
2875 clear_directory (dir);
2878 v.push_back ((*i).path);
2879 v.push_back ("interchange");
2880 v.push_back (lname);
2881 v.push_back ("midifiles");
2882 v.push_back (stub_dir_name);
2884 dir = Glib::build_filename (v);
2886 clear_directory (dir);
2891 Session::set_dirty ()
2893 bool was_dirty = dirty();
2895 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2899 DirtyChanged(); /* EMIT SIGNAL */
2905 Session::set_clean ()
2907 bool was_dirty = dirty();
2909 _state_of_the_state = Clean;
2913 DirtyChanged(); /* EMIT SIGNAL */
2918 Session::set_deletion_in_progress ()
2920 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2924 Session::clear_deletion_in_progress ()
2926 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2930 Session::add_controllable (boost::shared_ptr<Controllable> c)
2932 /* this adds a controllable to the list managed by the Session.
2933 this is a subset of those managed by the Controllable class
2934 itself, and represents the only ones whose state will be saved
2935 as part of the session.
2938 Glib::Mutex::Lock lm (controllables_lock);
2939 controllables.insert (c);
2942 struct null_deleter { void operator()(void const *) const {} };
2945 Session::remove_controllable (Controllable* c)
2947 if (_state_of_the_state | Deletion) {
2951 Glib::Mutex::Lock lm (controllables_lock);
2953 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2955 if (x != controllables.end()) {
2956 controllables.erase (x);
2960 boost::shared_ptr<Controllable>
2961 Session::controllable_by_id (const PBD::ID& id)
2963 Glib::Mutex::Lock lm (controllables_lock);
2965 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2966 if ((*i)->id() == id) {
2971 return boost::shared_ptr<Controllable>();
2974 boost::shared_ptr<Controllable>
2975 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2977 boost::shared_ptr<Controllable> c;
2978 boost::shared_ptr<Route> r;
2980 switch (desc.top_level_type()) {
2981 case ControllableDescriptor::NamedRoute:
2983 std::string str = desc.top_level_name();
2984 if (str == "master") {
2986 } else if (str == "control" || str == "listen") {
2989 r = route_by_name (desc.top_level_name());
2994 case ControllableDescriptor::RemoteControlID:
2995 r = route_by_remote_id (desc.rid());
3003 switch (desc.subtype()) {
3004 case ControllableDescriptor::Gain:
3005 c = r->gain_control ();
3008 case ControllableDescriptor::Solo:
3009 c = r->solo_control();
3012 case ControllableDescriptor::Mute:
3013 c = r->mute_control();
3016 case ControllableDescriptor::Recenable:
3018 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3021 c = t->rec_enable_control ();
3026 case ControllableDescriptor::PanDirection:
3028 c = r->pannable()->pan_azimuth_control;
3032 case ControllableDescriptor::PanWidth:
3034 c = r->pannable()->pan_width_control;
3038 case ControllableDescriptor::PanElevation:
3040 c = r->pannable()->pan_elevation_control;
3044 case ControllableDescriptor::Balance:
3045 /* XXX simple pan control */
3048 case ControllableDescriptor::PluginParameter:
3050 uint32_t plugin = desc.target (0);
3051 uint32_t parameter_index = desc.target (1);
3053 /* revert to zero based counting */
3059 if (parameter_index > 0) {
3063 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3066 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3067 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3072 case ControllableDescriptor::SendGain:
3074 uint32_t send = desc.target (0);
3076 /* revert to zero-based counting */
3082 boost::shared_ptr<Processor> p = r->nth_send (send);
3085 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3086 boost::shared_ptr<Amp> a = s->amp();
3089 c = s->amp()->gain_control();
3096 /* relax and return a null pointer */
3104 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3107 Stateful::add_instant_xml (node, _path);
3110 if (write_to_config) {
3111 Config->add_instant_xml (node);
3116 Session::instant_xml (const string& node_name)
3118 return Stateful::instant_xml (node_name, _path);
3122 Session::save_history (string snapshot_name)
3130 if (snapshot_name.empty()) {
3131 snapshot_name = _current_snapshot_name;
3134 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3135 const string backup_filename = history_filename + backup_suffix;
3136 const sys::path xml_path = _session_dir->root_path() / history_filename;
3137 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3139 if (sys::exists (xml_path)) {
3142 sys::rename (xml_path, backup_path);
3144 catch (const sys::filesystem_error& err)
3146 error << _("could not backup old history file, current history not saved") << endmsg;
3151 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3155 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3157 if (!tree.write (xml_path.to_string()))
3159 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3163 sys::remove (xml_path);
3164 sys::rename (backup_path, xml_path);
3166 catch (const sys::filesystem_error& err)
3168 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3169 backup_path.to_string(), err.what()) << endmsg;
3179 Session::restore_history (string snapshot_name)
3183 if (snapshot_name.empty()) {
3184 snapshot_name = _current_snapshot_name;
3187 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3188 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3190 info << "Loading history from " << xml_path.to_string() << endmsg;
3192 if (!sys::exists (xml_path)) {
3193 info << string_compose (_("%1: no history file \"%2\" for this session."),
3194 _name, xml_path.to_string()) << endmsg;
3198 if (!tree.read (xml_path.to_string())) {
3199 error << string_compose (_("Could not understand session history file \"%1\""),
3200 xml_path.to_string()) << endmsg;
3207 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3210 UndoTransaction* ut = new UndoTransaction ();
3213 ut->set_name(t->property("name")->value());
3214 stringstream ss(t->property("tv-sec")->value());
3216 ss.str(t->property("tv-usec")->value());
3218 ut->set_timestamp(tv);
3220 for (XMLNodeConstIterator child_it = t->children().begin();
3221 child_it != t->children().end(); child_it++)
3223 XMLNode *n = *child_it;
3226 if (n->name() == "MementoCommand" ||
3227 n->name() == "MementoUndoCommand" ||
3228 n->name() == "MementoRedoCommand") {
3230 if ((c = memento_command_factory(n))) {
3234 } else if (n->name() == "NoteDiffCommand") {
3235 PBD::ID id (n->property("midi-source")->value());
3236 boost::shared_ptr<MidiSource> midi_source =
3237 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3239 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3241 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3244 } else if (n->name() == "SysExDiffCommand") {
3246 PBD::ID id (n->property("midi-source")->value());
3247 boost::shared_ptr<MidiSource> midi_source =
3248 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3250 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3252 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3255 } else if (n->name() == "PatchChangeDiffCommand") {
3257 PBD::ID id (n->property("midi-source")->value());
3258 boost::shared_ptr<MidiSource> midi_source =
3259 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3261 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3263 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3266 } else if (n->name() == "StatefulDiffCommand") {
3267 if ((c = stateful_diff_command_factory (n))) {
3268 ut->add_command (c);
3271 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3282 Session::config_changed (std::string p, bool ours)
3288 if (p == "seamless-loop") {
3290 } else if (p == "rf-speed") {
3292 } else if (p == "auto-loop") {
3294 } else if (p == "auto-input") {
3296 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3297 /* auto-input only makes a difference if we're rolling */
3299 boost::shared_ptr<RouteList> rl = routes.reader ();
3300 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3301 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3302 if (tr && tr->record_enabled ()) {
3303 tr->monitor_input (!config.get_auto_input());
3308 } else if (p == "punch-in") {
3312 if ((location = _locations->auto_punch_location()) != 0) {
3314 if (config.get_punch_in ()) {
3315 replace_event (SessionEvent::PunchIn, location->start());
3317 remove_event (location->start(), SessionEvent::PunchIn);
3321 } else if (p == "punch-out") {
3325 if ((location = _locations->auto_punch_location()) != 0) {
3327 if (config.get_punch_out()) {
3328 replace_event (SessionEvent::PunchOut, location->end());
3330 clear_events (SessionEvent::PunchOut);
3334 } else if (p == "edit-mode") {
3336 Glib::Mutex::Lock lm (playlists->lock);
3338 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3339 (*i)->set_edit_mode (Config->get_edit_mode ());
3342 } else if (p == "use-video-sync") {
3344 waiting_for_sync_offset = config.get_use_video_sync();
3346 } else if (p == "mmc-control") {
3348 //poke_midi_thread ();
3350 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3352 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3354 } else if (p == "mmc-send-id") {
3356 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3358 } else if (p == "midi-control") {
3360 //poke_midi_thread ();
3362 } else if (p == "raid-path") {
3364 setup_raid_path (config.get_raid_path());
3366 } else if (p == "timecode-format") {
3370 } else if (p == "video-pullup") {
3374 } else if (p == "seamless-loop") {
3376 if (play_loop && transport_rolling()) {
3377 // to reset diskstreams etc
3378 request_play_loop (true);
3381 } else if (p == "rf-speed") {
3383 cumulative_rf_motion = 0;
3386 } else if (p == "click-sound") {
3388 setup_click_sounds (1);
3390 } else if (p == "click-emphasis-sound") {
3392 setup_click_sounds (-1);
3394 } else if (p == "clicking") {
3396 if (Config->get_clicking()) {
3397 if (_click_io && click_data) { // don't require emphasis data
3404 } else if (p == "send-mtc") {
3406 if (Config->get_send_mtc ()) {
3407 /* mark us ready to send */
3408 next_quarter_frame_to_send = 0;
3411 } else if (p == "send-mmc") {
3413 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3415 } else if (p == "midi-feedback") {
3417 session_midi_feedback = Config->get_midi_feedback();
3419 } else if (p == "jack-time-master") {
3421 engine().reset_timebase ();
3423 } else if (p == "native-file-header-format") {
3425 if (!first_file_header_format_reset) {
3426 reset_native_file_format ();
3429 first_file_header_format_reset = false;
3431 } else if (p == "native-file-data-format") {
3433 if (!first_file_data_format_reset) {
3434 reset_native_file_format ();
3437 first_file_data_format_reset = false;
3439 } else if (p == "external-sync") {
3440 if (!config.get_external_sync()) {
3441 drop_sync_source ();
3443 switch_to_sync_source (config.get_sync_source());
3445 } else if (p == "remote-model") {
3446 set_remote_control_ids ();
3447 } else if (p == "denormal-model") {
3449 } else if (p == "history-depth") {
3450 set_history_depth (Config->get_history_depth());
3451 } else if (p == "sync-all-route-ordering") {
3452 sync_order_keys ("session");
3453 } else if (p == "initial-program-change") {
3455 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3458 buf[0] = MIDI::program; // channel zero by default
3459 buf[1] = (Config->get_initial_program_change() & 0x7f);
3461 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3463 } else if (p == "solo-mute-override") {
3464 // catch_up_on_solo_mute_override ();
3465 } else if (p == "listen-position" || p == "pfl-position") {
3466 listen_position_changed ();
3467 } else if (p == "solo-control-is-listen-control") {
3468 solo_control_mode_changed ();
3469 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3470 last_timecode_valid = false;
3477 Session::set_history_depth (uint32_t d)
3479 _history.set_depth (d);
3483 Session::load_diskstreams_2X (XMLNode const & node, int)
3486 XMLNodeConstIterator citer;
3488 clist = node.children();
3490 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3493 /* diskstreams added automatically by DiskstreamCreated handler */
3494 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3495 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3496 _diskstreams_2X.push_back (dsp);
3498 error << _("Session: unknown diskstream type in XML") << endmsg;
3502 catch (failed_constructor& err) {
3503 error << _("Session: could not load diskstream via XML state") << endmsg;
3511 /** Connect things to the MMC object */
3513 Session::setup_midi_machine_control ()
3515 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3517 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3518 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3519 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3520 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3521 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3522 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3523 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3524 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3525 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3526 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3527 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3528 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3529 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3531 /* also handle MIDI SPP because its so common */
3533 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3534 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3535 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));
3538 boost::shared_ptr<Controllable>
3539 Session::solo_cut_control() const
3541 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3542 controls in Ardour that currently get presented to the user in the GUI that require
3543 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3545 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3546 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3550 return _solo_cut_control;