2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "libardour-config.h"
33 #include <cstdio> /* snprintf(3) ... grrr */
47 #include <sys/param.h>
48 #include <sys/mount.h>
52 #include <glibmm/thread.h>
54 #include "midi++/mmc.h"
55 #include "midi++/port.h"
56 #include "midi++/manager.h"
58 #include "pbd/boost_debug.h"
59 #include "pbd/basename.h"
60 #include "pbd/controllable_descriptor.h"
61 #include "pbd/enumwriter.h"
62 #include "pbd/error.h"
63 #include "pbd/pathscanner.h"
64 #include "pbd/pthread_utils.h"
65 #include "pbd/search_path.h"
66 #include "pbd/stacktrace.h"
67 #include "pbd/convert.h"
68 #include "pbd/clear_dir.h"
70 #include "ardour/amp.h"
71 #include "ardour/audio_diskstream.h"
72 #include "ardour/audio_track.h"
73 #include "ardour/audioengine.h"
74 #include "ardour/audiofilesource.h"
75 #include "ardour/audioplaylist.h"
76 #include "ardour/audioregion.h"
77 #include "ardour/auditioner.h"
78 #include "ardour/automation_control.h"
79 #include "ardour/buffer.h"
80 #include "ardour/butler.h"
81 #include "ardour/configuration.h"
82 #include "ardour/control_protocol_manager.h"
83 #include "ardour/crossfade.h"
84 #include "ardour/cycle_timer.h"
85 #include "ardour/directory_names.h"
86 #include "ardour/filename_extensions.h"
87 #include "ardour/io_processor.h"
88 #include "ardour/location.h"
89 #include "ardour/midi_diskstream.h"
90 #include "ardour/midi_patch_manager.h"
91 #include "ardour/midi_playlist.h"
92 #include "ardour/midi_region.h"
93 #include "ardour/midi_source.h"
94 #include "ardour/midi_track.h"
95 #include "ardour/named_selection.h"
96 #include "ardour/pannable.h"
97 #include "ardour/processor.h"
98 #include "ardour/port.h"
99 #include "ardour/proxy_controllable.h"
100 #include "ardour/region_factory.h"
101 #include "ardour/route_group.h"
102 #include "ardour/send.h"
103 #include "ardour/session.h"
104 #include "ardour/session_directory.h"
105 #include "ardour/session_metadata.h"
106 #include "ardour/session_state_utils.h"
107 #include "ardour/session_playlists.h"
108 #include "ardour/session_utils.h"
109 #include "ardour/silentfilesource.h"
110 #include "ardour/slave.h"
111 #include "ardour/smf_source.h"
112 #include "ardour/sndfile_helpers.h"
113 #include "ardour/sndfilesource.h"
114 #include "ardour/source_factory.h"
115 #include "ardour/template_utils.h"
116 #include "ardour/tempo.h"
117 #include "ardour/ticker.h"
118 #include "ardour/user_bundle.h"
119 #include "ardour/utils.h"
120 #include "ardour/utils.h"
121 #include "ardour/version.h"
122 #include "ardour/playlist_factory.h"
124 #include "control_protocol/control_protocol.h"
130 using namespace ARDOUR;
135 Session::first_stage_init (string fullpath, string snapshot_name)
137 if (fullpath.length() == 0) {
139 throw failed_constructor();
142 char buf[PATH_MAX+1];
143 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
144 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
146 throw failed_constructor();
151 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
152 _path += G_DIR_SEPARATOR;
155 /* these two are just provisional settings. set_state()
156 will likely override them.
159 _name = _current_snapshot_name = snapshot_name;
161 set_history_depth (Config->get_history_depth());
163 _current_frame_rate = _engine.frame_rate ();
164 _nominal_frame_rate = _current_frame_rate;
165 _base_frame_rate = _current_frame_rate;
167 _tempo_map = new TempoMap (_current_frame_rate);
168 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
171 _non_soloed_outs_muted = false;
173 _solo_isolated_cnt = 0;
174 g_atomic_int_set (&processing_prohibited, 0);
175 _transport_speed = 0;
176 _last_transport_speed = 0;
177 _target_transport_speed = 0;
178 auto_play_legal = false;
179 transport_sub_state = 0;
180 _transport_frame = 0;
181 _requested_return_frame = -1;
182 _session_range_location = 0;
183 g_atomic_int_set (&_record_status, Disabled);
184 loop_changing = false;
187 _last_roll_location = 0;
188 _last_roll_or_reversal_location = 0;
189 _last_record_location = 0;
190 pending_locate_frame = 0;
191 pending_locate_roll = false;
192 pending_locate_flush = false;
193 state_was_pending = false;
195 outbound_mtc_timecode_frame = 0;
196 next_quarter_frame_to_send = -1;
197 current_block_size = 0;
198 solo_update_disabled = false;
199 _have_captured = false;
200 _worst_output_latency = 0;
201 _worst_input_latency = 0;
202 _worst_track_latency = 0;
203 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
204 _was_seamless = Config->get_seamless_loop ();
206 _send_qf_mtc = false;
207 _pframes_since_last_mtc = 0;
208 g_atomic_int_set (&_playback_load, 100);
209 g_atomic_int_set (&_capture_load, 100);
212 pending_abort = false;
213 destructive_index = 0;
214 first_file_data_format_reset = true;
215 first_file_header_format_reset = true;
216 post_export_sync = false;
219 no_questions_about_missing_files = false;
220 _speakers.reset (new Speakers);
222 AudioDiskstream::allocate_working_buffers();
224 /* default short fade = 15ms */
226 Crossfade::set_short_xfade_length ((framecnt_t) floor (config.get_short_xfade_seconds() * frame_rate()));
227 SndFileSource::setup_standard_crossfades (*this, frame_rate());
229 last_mmc_step.tv_sec = 0;
230 last_mmc_step.tv_usec = 0;
233 /* click sounds are unset by default, which causes us to internal
234 waveforms for clicks.
238 click_emphasis_length = 0;
241 process_function = &Session::process_with_events;
243 if (config.get_use_video_sync()) {
244 waiting_for_sync_offset = true;
246 waiting_for_sync_offset = false;
249 last_timecode_when = 0;
250 last_timecode_valid = false;
254 last_rr_session_dir = session_dirs.begin();
255 refresh_disk_space ();
257 /* default: assume simple stereo speaker configuration */
259 _speakers->setup_default_speakers (2);
263 average_slave_delta = 1800; // !!! why 1800 ????
264 have_first_delta_accumulator = false;
265 delta_accumulator_cnt = 0;
266 _slave_state = Stopped;
268 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
269 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
270 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
271 add_controllable (_solo_cut_control);
273 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
275 /* These are all static "per-class" signals */
277 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
278 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
279 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
280 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
281 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
283 /* stop IO objects from doing stuff until we're ready for them */
285 Delivery::disable_panners ();
286 IO::disable_connecting ();
290 Session::second_stage_init ()
292 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
295 if (load_state (_current_snapshot_name)) {
300 if (_butler->start_thread()) {
304 if (start_midi_thread ()) {
308 setup_midi_machine_control ();
310 // set_state() will call setup_raid_path(), but if it's a new session we need
311 // to call setup_raid_path() here.
314 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
318 setup_raid_path(_path);
321 /* we can't save till after ::when_engine_running() is called,
322 because otherwise we save state with no connections made.
323 therefore, we reset _state_of_the_state because ::set_state()
324 will have cleared it.
326 we also have to include Loading so that any events that get
327 generated between here and the end of ::when_engine_running()
328 will be processed directly rather than queued.
331 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
333 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
334 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
335 setup_click_sounds (0);
336 setup_midi_control ();
338 /* Pay attention ... */
340 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
341 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
344 when_engine_running ();
347 /* handle this one in a different way than all others, so that its clear what happened */
349 catch (AudioEngine::PortRegistrationFailure& err) {
350 error << err.what() << endmsg;
358 BootMessage (_("Reset Remote Controls"));
360 send_full_time_code (0);
361 _engine.transport_locate (0);
363 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
364 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
366 MidiClockTicker::instance().set_session (this);
367 MIDI::Name::MidiPatchManager::instance().set_session (this);
369 /* initial program change will be delivered later; see ::config_changed() */
371 BootMessage (_("Reset Control Protocols"));
373 ControlProtocolManager::instance().set_session (this);
375 _state_of_the_state = Clean;
377 Port::set_connecting_blocked (false);
379 DirtyChanged (); /* EMIT SIGNAL */
381 if (state_was_pending) {
382 save_state (_current_snapshot_name);
383 remove_pending_capture_state ();
384 state_was_pending = false;
387 BootMessage (_("Session loading complete"));
393 Session::raid_path () const
395 SearchPath raid_search_path;
397 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
398 raid_search_path += sys::path((*i).path);
401 return raid_search_path.to_string ();
405 Session::setup_raid_path (string path)
414 session_dirs.clear ();
416 SearchPath search_path(path);
417 SearchPath sound_search_path;
418 SearchPath midi_search_path;
420 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
421 sp.path = (*i).to_string ();
422 sp.blocks = 0; // not needed
423 session_dirs.push_back (sp);
425 SessionDirectory sdir(sp.path);
427 sound_search_path += sdir.sound_path ();
428 midi_search_path += sdir.midi_path ();
431 // reset the round-robin soundfile path thingie
432 last_rr_session_dir = session_dirs.begin();
436 Session::path_is_within_session (const std::string& path)
438 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
439 if (path.find ((*i).path) == 0) {
447 Session::ensure_subdirs ()
451 dir = session_directory().peak_path().to_string();
453 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
454 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
458 dir = session_directory().sound_path().to_string();
460 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
461 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
465 dir = session_directory().midi_path().to_string();
467 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
468 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
472 dir = session_directory().dead_path().to_string();
474 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
475 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
479 dir = session_directory().export_path().to_string();
481 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
482 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
486 dir = analysis_dir ();
488 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
489 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
493 dir = plugins_dir ();
495 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
496 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
503 /** Caller must not hold process lock */
505 Session::create (const string& mix_template, BusProfile* bus_profile)
507 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
508 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
512 if (ensure_subdirs ()) {
516 _writable = exists_and_writable (sys::path (_path));
518 if (!mix_template.empty()) {
519 std::string in_path = mix_template;
521 ifstream in(in_path.c_str());
524 string out_path = _path;
526 out_path += statefile_suffix;
528 ofstream out(out_path.c_str());
536 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
542 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
549 /* Instantiate metadata */
551 _metadata = new SessionMetadata ();
553 /* set initial start + end point */
555 _state_of_the_state = Clean;
557 /* set up Master Out and Control Out if necessary */
563 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
565 if (bus_profile->master_out_channels) {
566 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
570 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
571 boost_debug_shared_ptr_mark_interesting (rt.get(), "Route");
574 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
575 r->input()->ensure_io (count, false, this);
576 r->output()->ensure_io (count, false, this);
578 r->set_remote_control_id (control_id++);
582 if (Config->get_use_monitor_bus()) {
583 boost::shared_ptr<Route> r (new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO));
587 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
588 boost_debug_shared_ptr_mark_interesting (rt, "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);
601 /* prohibit auto-connect to master, because there isn't one */
602 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
606 add_routes (rl, false, false);
609 /* this allows the user to override settings with an environment variable.
612 if (no_auto_connect()) {
613 bus_profile->input_ac = AutoConnectOption (0);
614 bus_profile->output_ac = AutoConnectOption (0);
617 Config->set_input_auto_connect (bus_profile->input_ac);
618 Config->set_output_auto_connect (bus_profile->output_ac);
627 Session::maybe_write_autosave()
629 if (dirty() && record_status() != Recording) {
630 save_state("", true);
635 Session::remove_pending_capture_state ()
637 sys::path pending_state_file_path(_session_dir->root_path());
639 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
643 sys::remove (pending_state_file_path);
645 catch(sys::filesystem_error& ex)
647 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
648 pending_state_file_path.to_string(), ex.what()) << endmsg;
652 /** Rename a state file.
653 * @param snapshot_name Snapshot name.
656 Session::rename_state (string old_name, string new_name)
658 if (old_name == _current_snapshot_name || old_name == _name) {
659 /* refuse to rename the current snapshot or the "main" one */
663 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
664 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
666 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
667 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
671 sys::rename (old_xml_path, new_xml_path);
673 catch (const sys::filesystem_error& err)
675 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
676 old_name, new_name, err.what()) << endmsg;
680 /** Remove a state file.
681 * @param snapshot_name Snapshot name.
684 Session::remove_state (string snapshot_name)
686 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
687 // refuse to remove the current snapshot or the "main" one
691 sys::path xml_path(_session_dir->root_path());
693 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
695 if (!create_backup_file (xml_path)) {
696 // don't remove it if a backup can't be made
697 // create_backup_file will log the error.
702 sys::remove (xml_path);
705 #ifdef HAVE_JACK_SESSION
707 Session::jack_session_event (jack_session_event_t * event)
711 struct tm local_time;
714 localtime_r (&n, &local_time);
715 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
717 if (event->type == JackSessionSaveTemplate)
719 if (save_template( timebuf )) {
720 event->flags = JackSessionSaveError;
722 string cmd ("ardour3 -P -U ");
723 cmd += event->client_uuid;
727 event->command_line = strdup (cmd.c_str());
732 if (save_state (timebuf)) {
733 event->flags = JackSessionSaveError;
735 sys::path xml_path (_session_dir->root_path());
736 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
738 string cmd ("ardour3 -P -U ");
739 cmd += event->client_uuid;
741 cmd += xml_path.to_string();
744 event->command_line = strdup (cmd.c_str());
748 jack_session_reply (_engine.jack(), event);
750 if (event->type == JackSessionSaveAndQuit) {
751 Quit (); /* EMIT SIGNAL */
754 jack_session_event_free( event );
758 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
760 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
763 sys::path xml_path(_session_dir->root_path());
765 if (!_writable || (_state_of_the_state & CannotSave)) {
769 if (!_engine.connected ()) {
770 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
776 /* tell sources we're saving first, in case they write out to a new file
777 * which should be saved with the state rather than the old one */
778 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
779 i->second->session_saved();
782 tree.set_root (&get_state());
784 if (snapshot_name.empty()) {
785 snapshot_name = _current_snapshot_name;
786 } else if (switch_to_snapshot) {
787 _current_snapshot_name = snapshot_name;
792 /* proper save: use statefile_suffix (.ardour in English) */
794 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
796 /* make a backup copy of the old file */
798 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
799 // create_backup_file will log the error
805 /* pending save: use pending_suffix (.pending in English) */
806 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
809 sys::path tmp_path(_session_dir->root_path());
811 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
813 // cerr << "actually writing state to " << xml_path.to_string() << endl;
815 if (!tree.write (tmp_path.to_string())) {
816 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
817 sys::remove (tmp_path);
822 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
823 error << string_compose (_("could not rename temporary session file %1 to %2"),
824 tmp_path.to_string(), xml_path.to_string()) << endmsg;
825 sys::remove (tmp_path);
832 save_history (snapshot_name);
834 bool was_dirty = dirty();
836 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
839 DirtyChanged (); /* EMIT SIGNAL */
842 StateSaved (snapshot_name); /* EMIT SIGNAL */
849 Session::restore_state (string snapshot_name)
851 if (load_state (snapshot_name) == 0) {
852 set_state (*state_tree->root(), Stateful::loading_state_version);
859 Session::load_state (string snapshot_name)
864 state_was_pending = false;
866 /* check for leftover pending state from a crashed capture attempt */
868 sys::path xmlpath(_session_dir->root_path());
869 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
871 if (sys::exists (xmlpath)) {
873 /* there is pending state from a crashed capture attempt */
875 boost::optional<int> r = AskAboutPendingState();
876 if (r.get_value_or (1)) {
877 state_was_pending = true;
881 if (!state_was_pending) {
882 xmlpath = _session_dir->root_path();
883 xmlpath /= snapshot_name;
886 if (!sys::exists (xmlpath)) {
887 xmlpath = _session_dir->root_path();
888 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
889 if (!sys::exists (xmlpath)) {
890 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
895 state_tree = new XMLTree;
899 _writable = exists_and_writable (xmlpath);
901 if (!state_tree->read (xmlpath.to_string())) {
902 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
908 XMLNode& root (*state_tree->root());
910 if (root.name() != X_("Session")) {
911 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
917 const XMLProperty* prop;
919 if ((prop = root.property ("version")) == 0) {
920 /* no version implies very old version of Ardour */
921 Stateful::loading_state_version = 1000;
927 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
928 Stateful::loading_state_version = (major * 1000) + minor;
931 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
933 sys::path backup_path(_session_dir->root_path());
935 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
937 // only create a backup once
938 if (sys::exists (backup_path)) {
942 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
943 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
948 sys::copy_file (xmlpath, backup_path);
950 catch(sys::filesystem_error& ex)
952 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
953 xmlpath.to_string(), ex.what())
963 Session::load_options (const XMLNode& node)
965 LocaleGuard lg (X_("POSIX"));
966 config.set_variables (node);
977 Session::get_template()
979 /* if we don't disable rec-enable, diskstreams
980 will believe they need to store their capture
981 sources in their state node.
984 disable_record (false);
990 Session::state(bool full_state)
992 XMLNode* node = new XMLNode("Session");
995 // store libardour version, just in case
997 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
998 node->add_property("version", string(buf));
1000 /* store configuration settings */
1004 node->add_property ("name", _name);
1005 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1006 node->add_property ("sample-rate", buf);
1008 if (session_dirs.size() > 1) {
1012 vector<space_and_path>::iterator i = session_dirs.begin();
1013 vector<space_and_path>::iterator next;
1015 ++i; /* skip the first one */
1019 while (i != session_dirs.end()) {
1023 if (next != session_dirs.end()) {
1033 child = node->add_child ("Path");
1034 child->add_content (p);
1038 /* save the ID counter */
1040 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1041 node->add_property ("id-counter", buf);
1043 /* save the event ID counter */
1045 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1046 node->add_property ("event-counter", buf);
1048 /* various options */
1050 node->add_child_nocopy (config.get_variables ());
1052 node->add_child_nocopy (_metadata->get_state());
1054 child = node->add_child ("Sources");
1057 Glib::Mutex::Lock sl (source_lock);
1059 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1061 /* Don't save information about non-destructive file sources that are empty
1062 and unused by any regions.
1065 boost::shared_ptr<FileSource> fs;
1066 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1067 if (!fs->destructive()) {
1068 if (fs->empty() && !fs->used()) {
1074 child->add_child_nocopy (siter->second->get_state());
1078 child = node->add_child ("Regions");
1081 Glib::Mutex::Lock rl (region_lock);
1082 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1083 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1084 boost::shared_ptr<Region> r = i->second;
1085 /* only store regions not attached to playlists */
1086 if (r->playlist() == 0) {
1087 child->add_child_nocopy (r->state ());
1093 node->add_child_nocopy (_locations->get_state());
1095 // for a template, just create a new Locations, populate it
1096 // with the default start and end, and get the state for that.
1097 Locations loc (*this);
1098 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1099 range->set (max_framepos, 0);
1101 node->add_child_nocopy (loc.get_state());
1104 child = node->add_child ("Bundles");
1106 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1107 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1108 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1110 child->add_child_nocopy (b->get_state());
1115 child = node->add_child ("Routes");
1117 boost::shared_ptr<RouteList> r = routes.reader ();
1119 RoutePublicOrderSorter cmp;
1120 RouteList public_order (*r);
1121 public_order.sort (cmp);
1123 /* the sort should have put control outs first */
1126 assert (_monitor_out == public_order.front());
1129 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1130 if (!(*i)->is_hidden()) {
1132 child->add_child_nocopy ((*i)->get_state());
1134 child->add_child_nocopy ((*i)->get_template());
1140 playlists->add_state (node, full_state);
1142 child = node->add_child ("RouteGroups");
1143 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1144 child->add_child_nocopy ((*i)->get_state());
1148 child = node->add_child ("Click");
1149 child->add_child_nocopy (_click_io->state (full_state));
1153 child = node->add_child ("NamedSelections");
1154 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1156 child->add_child_nocopy ((*i)->get_state());
1161 node->add_child_nocopy (_speakers->get_state());
1162 node->add_child_nocopy (_tempo_map->get_state());
1163 node->add_child_nocopy (get_control_protocol_state());
1166 node->add_child_copy (*_extra_xml);
1173 Session::get_control_protocol_state ()
1175 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1176 return cpm.get_state();
1180 Session::set_state (const XMLNode& node, int version)
1184 const XMLProperty* prop;
1187 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1189 if (node.name() != X_("Session")) {
1190 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1194 if ((prop = node.property ("version")) != 0) {
1195 version = atoi (prop->value ()) * 1000;
1198 if ((prop = node.property ("name")) != 0) {
1199 _name = prop->value ();
1202 if ((prop = node.property (X_("sample-rate"))) != 0) {
1204 _nominal_frame_rate = atoi (prop->value());
1206 if (_nominal_frame_rate != _current_frame_rate) {
1207 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1208 if (r.get_value_or (0)) {
1214 setup_raid_path(_session_dir->root_path().to_string());
1216 if ((prop = node.property (X_("id-counter"))) != 0) {
1218 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1219 ID::init_counter (x);
1221 /* old sessions used a timebased counter, so fake
1222 the startup ID counter based on a standard
1227 ID::init_counter (now);
1230 if ((prop = node.property (X_("event-counter"))) != 0) {
1231 Evoral::init_event_id_counter (atoi (prop->value()));
1234 IO::disable_connecting ();
1236 if ((child = find_named_node (node, "Extra")) != 0) {
1237 _extra_xml = new XMLNode (*child);
1240 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1241 load_options (*child);
1242 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1243 load_options (*child);
1245 error << _("Session: XML state has no options section") << endmsg;
1248 if (version >= 3000) {
1249 if ((child = find_named_node (node, "Metadata")) == 0) {
1250 warning << _("Session: XML state has no metadata section") << endmsg;
1251 } else if (_metadata->set_state (*child, version)) {
1256 if ((child = find_named_node (node, "Locations")) == 0) {
1257 error << _("Session: XML state has no locations section") << endmsg;
1259 } else if (_locations->set_state (*child, version)) {
1263 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1264 _speakers->set_state (*child, version);
1269 if ((location = _locations->auto_loop_location()) != 0) {
1270 set_auto_loop_location (location);
1273 if ((location = _locations->auto_punch_location()) != 0) {
1274 set_auto_punch_location (location);
1277 if ((location = _locations->session_range_location()) != 0) {
1278 delete _session_range_location;
1279 _session_range_location = location;
1282 if (_session_range_location) {
1283 AudioFileSource::set_header_position_offset (_session_range_location->start());
1286 if ((child = find_named_node (node, "Sources")) == 0) {
1287 error << _("Session: XML state has no sources section") << endmsg;
1289 } else if (load_sources (*child)) {
1293 if ((child = find_named_node (node, "TempoMap")) == 0) {
1294 error << _("Session: XML state has no Tempo Map section") << endmsg;
1296 } else if (_tempo_map->set_state (*child, version)) {
1300 if ((child = find_named_node (node, "Regions")) == 0) {
1301 error << _("Session: XML state has no Regions section") << endmsg;
1303 } else if (load_regions (*child)) {
1307 if ((child = find_named_node (node, "Playlists")) == 0) {
1308 error << _("Session: XML state has no playlists section") << endmsg;
1310 } else if (playlists->load (*this, *child)) {
1314 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1316 } else if (playlists->load_unused (*this, *child)) {
1320 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1321 if (load_named_selections (*child)) {
1326 if (version >= 3000) {
1327 if ((child = find_named_node (node, "Bundles")) == 0) {
1328 warning << _("Session: XML state has no bundles section") << endmsg;
1331 /* We can't load Bundles yet as they need to be able
1332 to convert from port names to Port objects, which can't happen until
1334 _bundle_xml_node = new XMLNode (*child);
1338 if (version < 3000) {
1339 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1340 error << _("Session: XML state has no diskstreams section") << endmsg;
1342 } else if (load_diskstreams_2X (*child, version)) {
1347 if ((child = find_named_node (node, "Routes")) == 0) {
1348 error << _("Session: XML state has no routes section") << endmsg;
1350 } else if (load_routes (*child, version)) {
1354 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1355 _diskstreams_2X.clear ();
1357 if (version >= 3000) {
1359 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1360 error << _("Session: XML state has no route groups section") << endmsg;
1362 } else if (load_route_groups (*child, version)) {
1366 } else if (version < 3000) {
1368 if ((child = find_named_node (node, "EditGroups")) == 0) {
1369 error << _("Session: XML state has no edit groups section") << endmsg;
1371 } else if (load_route_groups (*child, version)) {
1375 if ((child = find_named_node (node, "MixGroups")) == 0) {
1376 error << _("Session: XML state has no mix groups section") << endmsg;
1378 } else if (load_route_groups (*child, version)) {
1383 if ((child = find_named_node (node, "Click")) == 0) {
1384 warning << _("Session: XML state has no click section") << endmsg;
1385 } else if (_click_io) {
1386 _click_io->set_state (*child, version);
1389 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1390 ControlProtocolManager::instance().set_protocol_states (*child);
1393 /* here beginneth the second phase ... */
1395 StateReady (); /* EMIT SIGNAL */
1404 Session::load_routes (const XMLNode& node, int version)
1407 XMLNodeConstIterator niter;
1408 RouteList new_routes;
1410 nlist = node.children();
1414 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1416 boost::shared_ptr<Route> route;
1417 if (version < 3000) {
1418 route = XMLRouteFactory_2X (**niter, version);
1420 route = XMLRouteFactory (**niter, version);
1424 error << _("Session: cannot create Route from XML description.") << endmsg;
1428 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1430 new_routes.push_back (route);
1433 add_routes (new_routes, false, false);
1438 boost::shared_ptr<Route>
1439 Session::XMLRouteFactory (const XMLNode& node, int version)
1441 boost::shared_ptr<Route> ret;
1443 if (node.name() != "Route") {
1447 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1449 DataType type = DataType::AUDIO;
1450 const XMLProperty* prop = node.property("default-type");
1453 type = DataType (prop->value());
1456 assert (type != DataType::NIL);
1460 boost::shared_ptr<Track> track;
1462 if (type == DataType::AUDIO) {
1463 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1465 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1468 if (track->init()) {
1472 if (track->set_state (node, version)) {
1476 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1477 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1482 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1484 if (r->init () == 0 && r->set_state (node, version) == 0) {
1485 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1486 boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1495 boost::shared_ptr<Route>
1496 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1498 boost::shared_ptr<Route> ret;
1500 if (node.name() != "Route") {
1504 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1506 ds_prop = node.property (X_("diskstream"));
1509 DataType type = DataType::AUDIO;
1510 const XMLProperty* prop = node.property("default-type");
1513 type = DataType (prop->value());
1516 assert (type != DataType::NIL);
1520 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1521 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1525 if (i == _diskstreams_2X.end()) {
1526 error << _("Could not find diskstream for route") << endmsg;
1527 return boost::shared_ptr<Route> ();
1530 boost::shared_ptr<Track> track;
1532 if (type == DataType::AUDIO) {
1533 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1535 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1538 if (track->init()) {
1542 if (track->set_state (node, version)) {
1546 track->set_diskstream (*i);
1548 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1549 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1554 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1556 if (r->init () == 0 && r->set_state (node, version) == 0) {
1557 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1558 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1568 Session::load_regions (const XMLNode& node)
1571 XMLNodeConstIterator niter;
1572 boost::shared_ptr<Region> region;
1574 nlist = node.children();
1578 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1579 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1580 error << _("Session: cannot create Region from XML description.");
1581 const XMLProperty *name = (**niter).property("name");
1584 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1594 boost::shared_ptr<Region>
1595 Session::XMLRegionFactory (const XMLNode& node, bool full)
1597 const XMLProperty* type = node.property("type");
1601 if (!type || type->value() == "audio") {
1602 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1603 } else if (type->value() == "midi") {
1604 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1607 } catch (failed_constructor& err) {
1608 return boost::shared_ptr<Region> ();
1611 return boost::shared_ptr<Region> ();
1614 boost::shared_ptr<AudioRegion>
1615 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1617 const XMLProperty* prop;
1618 boost::shared_ptr<Source> source;
1619 boost::shared_ptr<AudioSource> as;
1621 SourceList master_sources;
1622 uint32_t nchans = 1;
1625 if (node.name() != X_("Region")) {
1626 return boost::shared_ptr<AudioRegion>();
1629 if ((prop = node.property (X_("channels"))) != 0) {
1630 nchans = atoi (prop->value().c_str());
1633 if ((prop = node.property ("name")) == 0) {
1634 cerr << "no name for this region\n";
1638 if ((prop = node.property (X_("source-0"))) == 0) {
1639 if ((prop = node.property ("source")) == 0) {
1640 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1641 return boost::shared_ptr<AudioRegion>();
1645 PBD::ID s_id (prop->value());
1647 if ((source = source_by_id (s_id)) == 0) {
1648 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1649 return boost::shared_ptr<AudioRegion>();
1652 as = boost::dynamic_pointer_cast<AudioSource>(source);
1654 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1655 return boost::shared_ptr<AudioRegion>();
1658 sources.push_back (as);
1660 /* pickup other channels */
1662 for (uint32_t n=1; n < nchans; ++n) {
1663 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1664 if ((prop = node.property (buf)) != 0) {
1666 PBD::ID id2 (prop->value());
1668 if ((source = source_by_id (id2)) == 0) {
1669 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1670 return boost::shared_ptr<AudioRegion>();
1673 as = boost::dynamic_pointer_cast<AudioSource>(source);
1675 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1676 return boost::shared_ptr<AudioRegion>();
1678 sources.push_back (as);
1682 for (uint32_t n = 0; n < nchans; ++n) {
1683 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1684 if ((prop = node.property (buf)) != 0) {
1686 PBD::ID id2 (prop->value());
1688 if ((source = source_by_id (id2)) == 0) {
1689 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << 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"), id2) << endmsg;
1696 return boost::shared_ptr<AudioRegion>();
1698 master_sources.push_back (as);
1703 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1705 /* a final detail: this is the one and only place that we know how long missing files are */
1707 if (region->whole_file()) {
1708 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1709 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1711 sfp->set_length (region->length());
1716 if (!master_sources.empty()) {
1717 if (master_sources.size() != nchans) {
1718 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1720 region->set_master_sources (master_sources);
1728 catch (failed_constructor& err) {
1729 return boost::shared_ptr<AudioRegion>();
1733 boost::shared_ptr<MidiRegion>
1734 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1736 const XMLProperty* prop;
1737 boost::shared_ptr<Source> source;
1738 boost::shared_ptr<MidiSource> ms;
1741 if (node.name() != X_("Region")) {
1742 return boost::shared_ptr<MidiRegion>();
1745 if ((prop = node.property ("name")) == 0) {
1746 cerr << "no name for this region\n";
1750 if ((prop = node.property (X_("source-0"))) == 0) {
1751 if ((prop = node.property ("source")) == 0) {
1752 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1753 return boost::shared_ptr<MidiRegion>();
1757 PBD::ID s_id (prop->value());
1759 if ((source = source_by_id (s_id)) == 0) {
1760 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1761 return boost::shared_ptr<MidiRegion>();
1764 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1766 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1767 return boost::shared_ptr<MidiRegion>();
1770 sources.push_back (ms);
1773 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1774 /* a final detail: this is the one and only place that we know how long missing files are */
1776 if (region->whole_file()) {
1777 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1778 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1780 sfp->set_length (region->length());
1788 catch (failed_constructor& err) {
1789 return boost::shared_ptr<MidiRegion>();
1794 Session::get_sources_as_xml ()
1797 XMLNode* node = new XMLNode (X_("Sources"));
1798 Glib::Mutex::Lock lm (source_lock);
1800 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1801 node->add_child_nocopy (i->second->get_state());
1808 Session::path_from_region_name (DataType type, string name, string identifier)
1810 char buf[PATH_MAX+1];
1812 SessionDirectory sdir(get_best_session_directory_for_new_source());
1813 sys::path source_dir = ((type == DataType::AUDIO)
1814 ? sdir.sound_path() : sdir.midi_path());
1816 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1818 for (n = 0; n < 999999; ++n) {
1819 if (identifier.length()) {
1820 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1821 identifier.c_str(), n, ext.c_str());
1823 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1827 sys::path source_path = source_dir / buf;
1829 if (!sys::exists (source_path)) {
1830 return source_path.to_string();
1834 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1843 Session::load_sources (const XMLNode& node)
1846 XMLNodeConstIterator niter;
1847 boost::shared_ptr<Source> source;
1849 nlist = node.children();
1853 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1856 if ((source = XMLSourceFactory (**niter)) == 0) {
1857 error << _("Session: cannot create Source from XML description.") << endmsg;
1860 } catch (MissingSource& err) {
1864 if (!no_questions_about_missing_files) {
1865 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1870 switch (user_choice) {
1872 /* user added a new search location, so try again */
1877 /* user asked to quit the entire session load
1882 no_questions_about_missing_files = true;
1886 no_questions_about_missing_files = true;
1891 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1892 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1901 boost::shared_ptr<Source>
1902 Session::XMLSourceFactory (const XMLNode& node)
1904 if (node.name() != "Source") {
1905 return boost::shared_ptr<Source>();
1909 /* note: do peak building in another thread when loading session state */
1910 return SourceFactory::create (*this, node, true);
1913 catch (failed_constructor& err) {
1914 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1915 return boost::shared_ptr<Source>();
1920 Session::save_template (string template_name)
1924 if (_state_of_the_state & CannotSave) {
1928 sys::path user_template_dir(user_template_directory());
1932 sys::create_directories (user_template_dir);
1934 catch(sys::filesystem_error& ex)
1936 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1937 user_template_dir.to_string(), ex.what()) << endmsg;
1941 tree.set_root (&get_template());
1943 sys::path template_file_path(user_template_dir);
1944 template_file_path /= template_name + template_suffix;
1946 if (sys::exists (template_file_path))
1948 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1949 template_file_path.to_string()) << endmsg;
1953 if (!tree.write (template_file_path.to_string())) {
1954 error << _("template not saved") << endmsg;
1962 Session::rename_template (string old_name, string new_name)
1964 sys::path old_path (user_template_directory());
1965 old_path /= old_name + template_suffix;
1967 sys::path new_path(user_template_directory());
1968 new_path /= new_name + template_suffix;
1970 if (sys::exists (new_path)) {
1971 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1972 new_path.to_string()) << endmsg;
1977 sys::rename (old_path, new_path);
1985 Session::delete_template (string name)
1987 sys::path path = user_template_directory();
1988 path /= name + template_suffix;
1999 Session::refresh_disk_space ()
2002 struct statfs statfsbuf;
2003 vector<space_and_path>::iterator i;
2004 Glib::Mutex::Lock lm (space_lock);
2007 /* get freespace on every FS that is part of the session path */
2009 _total_free_4k_blocks = 0;
2011 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2012 statfs ((*i).path.c_str(), &statfsbuf);
2014 scale = statfsbuf.f_bsize/4096.0;
2016 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2017 _total_free_4k_blocks += (*i).blocks;
2023 Session::get_best_session_directory_for_new_source ()
2025 vector<space_and_path>::iterator i;
2026 string result = _session_dir->root_path().to_string();
2028 /* handle common case without system calls */
2030 if (session_dirs.size() == 1) {
2034 /* OK, here's the algorithm we're following here:
2036 We want to select which directory to use for
2037 the next file source to be created. Ideally,
2038 we'd like to use a round-robin process so as to
2039 get maximum performance benefits from splitting
2040 the files across multiple disks.
2042 However, in situations without much diskspace, an
2043 RR approach may end up filling up a filesystem
2044 with new files while others still have space.
2045 Its therefore important to pay some attention to
2046 the freespace in the filesystem holding each
2047 directory as well. However, if we did that by
2048 itself, we'd keep creating new files in the file
2049 system with the most space until it was as full
2050 as all others, thus negating any performance
2051 benefits of this RAID-1 like approach.
2053 So, we use a user-configurable space threshold. If
2054 there are at least 2 filesystems with more than this
2055 much space available, we use RR selection between them.
2056 If not, then we pick the filesystem with the most space.
2058 This gets a good balance between the two
2062 refresh_disk_space ();
2064 int free_enough = 0;
2066 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2067 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2072 if (free_enough >= 2) {
2073 /* use RR selection process, ensuring that the one
2077 i = last_rr_session_dir;
2080 if (++i == session_dirs.end()) {
2081 i = session_dirs.begin();
2084 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2085 if (create_session_directory ((*i).path)) {
2087 last_rr_session_dir = i;
2092 } while (i != last_rr_session_dir);
2096 /* pick FS with the most freespace (and that
2097 seems to actually work ...)
2100 vector<space_and_path> sorted;
2101 space_and_path_ascending_cmp cmp;
2103 sorted = session_dirs;
2104 sort (sorted.begin(), sorted.end(), cmp);
2106 for (i = sorted.begin(); i != sorted.end(); ++i) {
2107 if (create_session_directory ((*i).path)) {
2109 last_rr_session_dir = i;
2119 Session::load_named_selections (const XMLNode& node)
2122 XMLNodeConstIterator niter;
2125 nlist = node.children();
2129 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2131 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2132 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2140 Session::XMLNamedSelectionFactory (const XMLNode& node)
2143 return new NamedSelection (*this, node);
2146 catch (failed_constructor& err) {
2152 Session::automation_dir () const
2154 return Glib::build_filename (_path, "automation");
2158 Session::analysis_dir () const
2160 return Glib::build_filename (_path, "analysis");
2164 Session::plugins_dir () const
2166 return Glib::build_filename (_path, "plugins");
2170 Session::load_bundles (XMLNode const & node)
2172 XMLNodeList nlist = node.children();
2173 XMLNodeConstIterator niter;
2177 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2178 if ((*niter)->name() == "InputBundle") {
2179 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2180 } else if ((*niter)->name() == "OutputBundle") {
2181 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2183 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2192 Session::load_route_groups (const XMLNode& node, int version)
2194 XMLNodeList nlist = node.children();
2195 XMLNodeConstIterator niter;
2199 if (version >= 3000) {
2201 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2202 if ((*niter)->name() == "RouteGroup") {
2203 RouteGroup* rg = new RouteGroup (*this, "");
2204 add_route_group (rg);
2205 rg->set_state (**niter, version);
2209 } else if (version < 3000) {
2211 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2212 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2213 RouteGroup* rg = new RouteGroup (*this, "");
2214 add_route_group (rg);
2215 rg->set_state (**niter, version);
2224 Session::auto_save()
2226 save_state (_current_snapshot_name);
2230 state_file_filter (const string &str, void */*arg*/)
2232 return (str.length() > strlen(statefile_suffix) &&
2233 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2237 bool operator()(const string* a, const string* b) {
2243 remove_end(string* state)
2245 string statename(*state);
2247 string::size_type start,end;
2248 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2249 statename = statename.substr (start+1);
2252 if ((end = statename.rfind(".ardour")) == string::npos) {
2253 end = statename.length();
2256 return new string(statename.substr (0, end));
2260 Session::possible_states (string path)
2262 PathScanner scanner;
2263 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2265 transform(states->begin(), states->end(), states->begin(), remove_end);
2268 sort (states->begin(), states->end(), cmp);
2274 Session::possible_states () const
2276 return possible_states(_path);
2280 Session::add_route_group (RouteGroup* g)
2282 _route_groups.push_back (g);
2283 route_group_added (g); /* EMIT SIGNAL */
2285 g->MembershipChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2286 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2292 Session::remove_route_group (RouteGroup& rg)
2294 list<RouteGroup*>::iterator i;
2296 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2297 _route_groups.erase (i);
2300 route_group_removed (); /* EMIT SIGNAL */
2304 /** Set a new order for our route groups, without adding or removing any.
2305 * @param groups Route group list in the new order.
2308 Session::reorder_route_groups (list<RouteGroup*> groups)
2310 _route_groups = groups;
2312 route_groups_reordered (); /* EMIT SIGNAL */
2318 Session::route_group_by_name (string name)
2320 list<RouteGroup *>::iterator i;
2322 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2323 if ((*i)->name() == name) {
2331 Session::all_route_group() const
2333 return *_all_route_group;
2337 Session::add_commands (vector<Command*> const & cmds)
2339 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2345 Session::begin_reversible_command (const string& name)
2347 begin_reversible_command (g_quark_from_string (name.c_str ()));
2350 /** Begin a reversible command using a GQuark to identify it.
2351 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2352 * but there must be as many begin...()s as there are commit...()s.
2355 Session::begin_reversible_command (GQuark q)
2357 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2358 to hold all the commands that are committed. This keeps the order of
2359 commands correct in the history.
2362 if (_current_trans == 0) {
2363 /* start a new transaction */
2364 assert (_current_trans_quarks.empty ());
2365 _current_trans = new UndoTransaction();
2366 _current_trans->set_name (g_quark_to_string (q));
2369 _current_trans_quarks.push_front (q);
2373 Session::commit_reversible_command (Command *cmd)
2375 assert (_current_trans);
2376 assert (!_current_trans_quarks.empty ());
2381 _current_trans->add_command (cmd);
2384 _current_trans_quarks.pop_front ();
2386 if (!_current_trans_quarks.empty ()) {
2387 /* the transaction we're committing is not the top-level one */
2391 if (_current_trans->empty()) {
2392 /* no commands were added to the transaction, so just get rid of it */
2393 delete _current_trans;
2398 gettimeofday (&now, 0);
2399 _current_trans->set_timestamp (now);
2401 _history.add (_current_trans);
2406 accept_all_audio_files (const string& path, void */*arg*/)
2408 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2412 if (!AudioFileSource::safe_audio_file_extension (path)) {
2420 accept_all_midi_files (const string& path, void */*arg*/)
2422 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2426 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2427 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2428 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2432 accept_all_state_files (const string& path, void */*arg*/)
2434 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2438 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2442 Session::find_all_sources (string path, set<string>& result)
2447 if (!tree.read (path)) {
2451 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2456 XMLNodeConstIterator niter;
2458 nlist = node->children();
2462 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2466 if ((prop = (*niter)->property (X_("type"))) == 0) {
2470 DataType type (prop->value());
2472 if ((prop = (*niter)->property (X_("name"))) == 0) {
2476 if (Glib::path_is_absolute (prop->value())) {
2477 /* external file, ignore */
2485 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2486 result.insert (found_path);
2494 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2496 PathScanner scanner;
2497 vector<string*>* state_files;
2499 string this_snapshot_path;
2505 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2506 ripped = ripped.substr (0, ripped.length() - 1);
2509 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2511 if (state_files == 0) {
2516 this_snapshot_path = _path;
2517 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2518 this_snapshot_path += statefile_suffix;
2520 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2522 if (exclude_this_snapshot && **i == this_snapshot_path) {
2526 if (find_all_sources (**i, result) < 0) {
2534 struct RegionCounter {
2535 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2536 AudioSourceList::iterator iter;
2537 boost::shared_ptr<Region> region;
2540 RegionCounter() : count (0) {}
2544 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2546 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2547 return r.get_value_or (1);
2551 Session::cleanup_regions ()
2553 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2555 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2557 boost::shared_ptr<AudioRegion> audio_region = boost::dynamic_pointer_cast<AudioRegion>( i->second);
2559 if (!audio_region) {
2563 uint32_t used = playlists->region_use_count (audio_region);
2565 if (used == 0 && !audio_region->automatic()) {
2566 RegionFactory::map_remove(i->second);
2570 /* dump the history list */
2577 Session::cleanup_sources (CleanupReport& rep)
2579 // FIXME: needs adaptation to midi
2581 vector<boost::shared_ptr<Source> > dead_sources;
2582 PathScanner scanner;
2585 vector<space_and_path>::iterator i;
2586 vector<space_and_path>::iterator nexti;
2587 vector<string*>* candidates;
2588 vector<string*>* candidates2;
2589 vector<string> unused;
2590 set<string> all_sources;
2595 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2597 /* consider deleting all unused playlists */
2599 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2604 /* sync the "all regions" property of each playlist with its current state
2607 playlists->sync_all_regions_with_regions ();
2609 /* find all un-used sources */
2614 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2616 SourceMap::iterator tmp;
2621 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2625 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2626 dead_sources.push_back (i->second);
2627 i->second->drop_references ();
2633 /* build a list of all the possible audio directories for the session */
2635 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2640 SessionDirectory sdir ((*i).path);
2641 audio_path += sdir.sound_path().to_string();
2643 if (nexti != session_dirs.end()) {
2651 /* build a list of all the possible midi directories for the session */
2653 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2658 SessionDirectory sdir ((*i).path);
2659 midi_path += sdir.midi_path().to_string();
2661 if (nexti != session_dirs.end()) {
2668 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2669 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2675 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2676 candidates->push_back (*i);
2681 candidates = candidates2; // might still be null
2684 /* find all sources, but don't use this snapshot because the
2685 state file on disk still references sources we may have already
2689 find_all_sources_across_snapshots (all_sources, true);
2691 /* add our current source list
2694 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2695 boost::shared_ptr<FileSource> fs;
2696 SourceMap::iterator tmp = i;
2699 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2700 if (playlists->source_use_count (fs) != 0) {
2701 all_sources.insert (fs->path());
2704 /* we might not remove this source from disk, because it may be used
2705 by other snapshots, but its not being used in this version
2706 so lets get rid of it now, along with any representative regions
2710 RegionFactory::remove_regions_using_source (i->second);
2718 char tmppath1[PATH_MAX+1];
2719 char tmppath2[PATH_MAX+1];
2722 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2727 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2729 if (realpath(spath.c_str(), tmppath1) == 0) {
2730 error << string_compose (_("Cannot expand path %1 (%2)"),
2731 spath, strerror (errno)) << endmsg;
2735 if (realpath((*i).c_str(), tmppath2) == 0) {
2736 error << string_compose (_("Cannot expand path %1 (%2)"),
2737 (*i), strerror (errno)) << endmsg;
2741 if (strcmp(tmppath1, tmppath2) == 0) {
2748 unused.push_back (spath);
2757 /* now try to move all unused files into the "dead" directory(ies) */
2759 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2760 struct stat statbuf;
2764 /* don't move the file across filesystems, just
2765 stick it in the `dead_dir_name' directory
2766 on whichever filesystem it was already on.
2769 if ((*x).find ("/sounds/") != string::npos) {
2771 /* old school, go up 1 level */
2773 newpath = Glib::path_get_dirname (*x); // "sounds"
2774 newpath = Glib::path_get_dirname (newpath); // "session-name"
2778 /* new school, go up 4 levels */
2780 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2781 newpath = Glib::path_get_dirname (newpath); // "session-name"
2782 newpath = Glib::path_get_dirname (newpath); // "interchange"
2783 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2786 newpath = Glib::build_filename (newpath, dead_dir_name);
2788 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2789 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2793 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2795 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2797 /* the new path already exists, try versioning */
2799 char buf[PATH_MAX+1];
2803 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2806 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2807 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2811 if (version == 999) {
2812 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2816 newpath = newpath_v;
2821 /* it doesn't exist, or we can't read it or something */
2825 stat ((*x).c_str(), &statbuf);
2827 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2828 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2829 (*x), newpath, strerror (errno))
2834 /* see if there an easy to find peakfile for this file, and remove it.
2837 string base = basename_nosuffix (*x);
2838 base += "%A"; /* this is what we add for the channel suffix of all native files,
2839 or for the first channel of embedded files. it will miss
2840 some peakfiles for other channels
2842 string peakpath = peak_path (base);
2844 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2845 if (::unlink (peakpath.c_str()) != 0) {
2846 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2847 peakpath, _path, strerror (errno))
2849 /* try to back out */
2850 rename (newpath.c_str(), _path.c_str());
2855 rep.paths.push_back (*x);
2856 rep.space += statbuf.st_size;
2859 /* dump the history list */
2863 /* save state so we don't end up a session file
2864 referring to non-existent sources.
2871 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2877 Session::cleanup_trash_sources (CleanupReport& rep)
2879 // FIXME: needs adaptation for MIDI
2881 vector<space_and_path>::iterator i;
2887 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2889 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2891 clear_directory (dead_dir, &rep.space, &rep.paths);
2898 Session::set_dirty ()
2900 bool was_dirty = dirty();
2902 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2906 DirtyChanged(); /* EMIT SIGNAL */
2912 Session::set_clean ()
2914 bool was_dirty = dirty();
2916 _state_of_the_state = Clean;
2920 DirtyChanged(); /* EMIT SIGNAL */
2925 Session::set_deletion_in_progress ()
2927 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2931 Session::clear_deletion_in_progress ()
2933 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2937 Session::add_controllable (boost::shared_ptr<Controllable> c)
2939 /* this adds a controllable to the list managed by the Session.
2940 this is a subset of those managed by the Controllable class
2941 itself, and represents the only ones whose state will be saved
2942 as part of the session.
2945 Glib::Mutex::Lock lm (controllables_lock);
2946 controllables.insert (c);
2949 struct null_deleter { void operator()(void const *) const {} };
2952 Session::remove_controllable (Controllable* c)
2954 if (_state_of_the_state | Deletion) {
2958 Glib::Mutex::Lock lm (controllables_lock);
2960 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2962 if (x != controllables.end()) {
2963 controllables.erase (x);
2967 boost::shared_ptr<Controllable>
2968 Session::controllable_by_id (const PBD::ID& id)
2970 Glib::Mutex::Lock lm (controllables_lock);
2972 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2973 if ((*i)->id() == id) {
2978 return boost::shared_ptr<Controllable>();
2981 boost::shared_ptr<Controllable>
2982 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2984 boost::shared_ptr<Controllable> c;
2985 boost::shared_ptr<Route> r;
2987 switch (desc.top_level_type()) {
2988 case ControllableDescriptor::NamedRoute:
2990 std::string str = desc.top_level_name();
2991 if (str == "master") {
2993 } else if (str == "control" || str == "listen") {
2996 r = route_by_name (desc.top_level_name());
3001 case ControllableDescriptor::RemoteControlID:
3002 r = route_by_remote_id (desc.rid());
3010 switch (desc.subtype()) {
3011 case ControllableDescriptor::Gain:
3012 c = r->gain_control ();
3015 case ControllableDescriptor::Solo:
3016 c = r->solo_control();
3019 case ControllableDescriptor::Mute:
3020 c = r->mute_control();
3023 case ControllableDescriptor::Recenable:
3025 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3028 c = t->rec_enable_control ();
3033 case ControllableDescriptor::PanDirection:
3035 c = r->pannable()->pan_azimuth_control;
3039 case ControllableDescriptor::PanWidth:
3041 c = r->pannable()->pan_width_control;
3045 case ControllableDescriptor::PanElevation:
3047 c = r->pannable()->pan_elevation_control;
3051 case ControllableDescriptor::Balance:
3052 /* XXX simple pan control */
3055 case ControllableDescriptor::PluginParameter:
3057 uint32_t plugin = desc.target (0);
3058 uint32_t parameter_index = desc.target (1);
3060 /* revert to zero based counting */
3066 if (parameter_index > 0) {
3070 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3073 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3074 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3079 case ControllableDescriptor::SendGain:
3081 uint32_t send = desc.target (0);
3083 /* revert to zero-based counting */
3089 boost::shared_ptr<Processor> p = r->nth_send (send);
3092 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3093 boost::shared_ptr<Amp> a = s->amp();
3096 c = s->amp()->gain_control();
3103 /* relax and return a null pointer */
3111 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3114 Stateful::add_instant_xml (node, _path);
3117 if (write_to_config) {
3118 Config->add_instant_xml (node);
3123 Session::instant_xml (const string& node_name)
3125 return Stateful::instant_xml (node_name, _path);
3129 Session::save_history (string snapshot_name)
3137 if (snapshot_name.empty()) {
3138 snapshot_name = _current_snapshot_name;
3141 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3142 const string backup_filename = history_filename + backup_suffix;
3143 const sys::path xml_path = _session_dir->root_path() / history_filename;
3144 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3146 if (sys::exists (xml_path)) {
3149 sys::rename (xml_path, backup_path);
3151 catch (const sys::filesystem_error& err)
3153 error << _("could not backup old history file, current history not saved") << endmsg;
3158 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3162 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3164 if (!tree.write (xml_path.to_string()))
3166 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3170 sys::remove (xml_path);
3171 sys::rename (backup_path, xml_path);
3173 catch (const sys::filesystem_error& err)
3175 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3176 backup_path.to_string(), err.what()) << endmsg;
3186 Session::restore_history (string snapshot_name)
3190 if (snapshot_name.empty()) {
3191 snapshot_name = _current_snapshot_name;
3194 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3195 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3197 info << "Loading history from " << xml_path.to_string() << endmsg;
3199 if (!sys::exists (xml_path)) {
3200 info << string_compose (_("%1: no history file \"%2\" for this session."),
3201 _name, xml_path.to_string()) << endmsg;
3205 if (!tree.read (xml_path.to_string())) {
3206 error << string_compose (_("Could not understand session history file \"%1\""),
3207 xml_path.to_string()) << endmsg;
3214 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3217 UndoTransaction* ut = new UndoTransaction ();
3220 ut->set_name(t->property("name")->value());
3221 stringstream ss(t->property("tv-sec")->value());
3223 ss.str(t->property("tv-usec")->value());
3225 ut->set_timestamp(tv);
3227 for (XMLNodeConstIterator child_it = t->children().begin();
3228 child_it != t->children().end(); child_it++)
3230 XMLNode *n = *child_it;
3233 if (n->name() == "MementoCommand" ||
3234 n->name() == "MementoUndoCommand" ||
3235 n->name() == "MementoRedoCommand") {
3237 if ((c = memento_command_factory(n))) {
3241 } else if (n->name() == "NoteDiffCommand") {
3242 PBD::ID id (n->property("midi-source")->value());
3243 boost::shared_ptr<MidiSource> midi_source =
3244 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3246 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3248 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3251 } else if (n->name() == "SysExDiffCommand") {
3253 PBD::ID id (n->property("midi-source")->value());
3254 boost::shared_ptr<MidiSource> midi_source =
3255 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3257 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3259 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3262 } else if (n->name() == "PatchChangeDiffCommand") {
3264 PBD::ID id (n->property("midi-source")->value());
3265 boost::shared_ptr<MidiSource> midi_source =
3266 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3268 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3270 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3273 } else if (n->name() == "StatefulDiffCommand") {
3274 if ((c = stateful_diff_command_factory (n))) {
3275 ut->add_command (c);
3278 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3289 Session::config_changed (std::string p, bool ours)
3295 if (p == "seamless-loop") {
3297 } else if (p == "rf-speed") {
3299 } else if (p == "auto-loop") {
3301 } else if (p == "auto-input") {
3303 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3304 /* auto-input only makes a difference if we're rolling */
3305 set_track_monitor_input_status (!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;