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_playlist_source.h"
73 #include "ardour/audio_track.h"
74 #include "ardour/audioengine.h"
75 #include "ardour/audiofilesource.h"
76 #include "ardour/audioplaylist.h"
77 #include "ardour/audioregion.h"
78 #include "ardour/auditioner.h"
79 #include "ardour/automation_control.h"
80 #include "ardour/buffer.h"
81 #include "ardour/butler.h"
82 #include "ardour/configuration.h"
83 #include "ardour/control_protocol_manager.h"
84 #include "ardour/crossfade.h"
85 #include "ardour/cycle_timer.h"
86 #include "ardour/directory_names.h"
87 #include "ardour/filename_extensions.h"
88 #include "ardour/io_processor.h"
89 #include "ardour/location.h"
90 #include "ardour/midi_diskstream.h"
91 #include "ardour/midi_patch_manager.h"
92 #include "ardour/midi_playlist.h"
93 #include "ardour/midi_region.h"
94 #include "ardour/midi_source.h"
95 #include "ardour/midi_track.h"
96 #include "ardour/named_selection.h"
97 #include "ardour/pannable.h"
98 #include "ardour/processor.h"
99 #include "ardour/port.h"
100 #include "ardour/proxy_controllable.h"
101 #include "ardour/region_factory.h"
102 #include "ardour/route_group.h"
103 #include "ardour/send.h"
104 #include "ardour/session.h"
105 #include "ardour/session_directory.h"
106 #include "ardour/session_metadata.h"
107 #include "ardour/session_state_utils.h"
108 #include "ardour/session_playlists.h"
109 #include "ardour/session_utils.h"
110 #include "ardour/silentfilesource.h"
111 #include "ardour/slave.h"
112 #include "ardour/smf_source.h"
113 #include "ardour/sndfile_helpers.h"
114 #include "ardour/sndfilesource.h"
115 #include "ardour/source_factory.h"
116 #include "ardour/template_utils.h"
117 #include "ardour/tempo.h"
118 #include "ardour/ticker.h"
119 #include "ardour/user_bundle.h"
120 #include "ardour/utils.h"
121 #include "ardour/utils.h"
122 #include "ardour/version.h"
123 #include "ardour/playlist_factory.h"
125 #include "control_protocol/control_protocol.h"
131 using namespace ARDOUR;
136 Session::first_stage_init (string fullpath, string snapshot_name)
138 if (fullpath.length() == 0) {
140 throw failed_constructor();
143 char buf[PATH_MAX+1];
144 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
145 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
147 throw failed_constructor();
152 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
153 _path += G_DIR_SEPARATOR;
156 /* these two are just provisional settings. set_state()
157 will likely override them.
160 _name = _current_snapshot_name = snapshot_name;
162 set_history_depth (Config->get_history_depth());
164 _current_frame_rate = _engine.frame_rate ();
165 _nominal_frame_rate = _current_frame_rate;
166 _base_frame_rate = _current_frame_rate;
168 _tempo_map = new TempoMap (_current_frame_rate);
169 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
172 _non_soloed_outs_muted = false;
174 _solo_isolated_cnt = 0;
175 g_atomic_int_set (&processing_prohibited, 0);
176 _transport_speed = 0;
177 _last_transport_speed = 0;
178 _target_transport_speed = 0;
179 auto_play_legal = false;
180 transport_sub_state = 0;
181 _transport_frame = 0;
182 _requested_return_frame = -1;
183 _session_range_location = 0;
184 g_atomic_int_set (&_record_status, Disabled);
185 loop_changing = false;
188 _last_roll_location = 0;
189 _last_roll_or_reversal_location = 0;
190 _last_record_location = 0;
191 pending_locate_frame = 0;
192 pending_locate_roll = false;
193 pending_locate_flush = false;
194 state_was_pending = false;
196 outbound_mtc_timecode_frame = 0;
197 next_quarter_frame_to_send = -1;
198 current_block_size = 0;
199 solo_update_disabled = false;
200 _have_captured = false;
201 _worst_output_latency = 0;
202 _worst_input_latency = 0;
203 _worst_track_latency = 0;
204 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
205 _was_seamless = Config->get_seamless_loop ();
207 _send_qf_mtc = false;
208 _pframes_since_last_mtc = 0;
209 g_atomic_int_set (&_playback_load, 100);
210 g_atomic_int_set (&_capture_load, 100);
213 pending_abort = false;
214 destructive_index = 0;
215 first_file_data_format_reset = true;
216 first_file_header_format_reset = true;
217 post_export_sync = false;
220 no_questions_about_missing_files = false;
221 _speakers.reset (new Speakers);
223 AudioDiskstream::allocate_working_buffers();
224 AudioSource::allocate_working_buffers ();
226 /* default short fade = 15ms */
228 Crossfade::set_short_xfade_length ((framecnt_t) floor (config.get_short_xfade_seconds() * frame_rate()));
229 SndFileSource::setup_standard_crossfades (*this, frame_rate());
231 last_mmc_step.tv_sec = 0;
232 last_mmc_step.tv_usec = 0;
235 /* click sounds are unset by default, which causes us to internal
236 waveforms for clicks.
240 click_emphasis_length = 0;
243 process_function = &Session::process_with_events;
245 if (config.get_use_video_sync()) {
246 waiting_for_sync_offset = true;
248 waiting_for_sync_offset = false;
251 last_timecode_when = 0;
252 last_timecode_valid = false;
256 last_rr_session_dir = session_dirs.begin();
257 refresh_disk_space ();
259 /* default: assume simple stereo speaker configuration */
261 _speakers->setup_default_speakers (2);
265 average_slave_delta = 1800; // !!! why 1800 ????
266 have_first_delta_accumulator = false;
267 delta_accumulator_cnt = 0;
268 _slave_state = Stopped;
270 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
271 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
272 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
273 add_controllable (_solo_cut_control);
275 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
277 /* These are all static "per-class" signals */
279 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
280 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
281 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
282 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
283 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
285 /* stop IO objects from doing stuff until we're ready for them */
287 Delivery::disable_panners ();
288 IO::disable_connecting ();
292 Session::second_stage_init ()
294 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
297 if (load_state (_current_snapshot_name)) {
302 if (_butler->start_thread()) {
306 if (start_midi_thread ()) {
310 setup_midi_machine_control ();
312 // set_state() will call setup_raid_path(), but if it's a new session we need
313 // to call setup_raid_path() here.
316 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
320 setup_raid_path(_path);
323 /* we can't save till after ::when_engine_running() is called,
324 because otherwise we save state with no connections made.
325 therefore, we reset _state_of_the_state because ::set_state()
326 will have cleared it.
328 we also have to include Loading so that any events that get
329 generated between here and the end of ::when_engine_running()
330 will be processed directly rather than queued.
333 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
335 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
336 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
337 setup_click_sounds (0);
338 setup_midi_control ();
340 /* Pay attention ... */
342 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
343 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
346 when_engine_running ();
349 /* handle this one in a different way than all others, so that its clear what happened */
351 catch (AudioEngine::PortRegistrationFailure& err) {
352 error << err.what() << endmsg;
360 BootMessage (_("Reset Remote Controls"));
362 send_full_time_code (0);
363 _engine.transport_locate (0);
365 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
366 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
368 MidiClockTicker::instance().set_session (this);
369 MIDI::Name::MidiPatchManager::instance().set_session (this);
371 /* initial program change will be delivered later; see ::config_changed() */
373 _state_of_the_state = Clean;
375 Port::set_connecting_blocked (false);
377 DirtyChanged (); /* EMIT SIGNAL */
379 if (state_was_pending) {
380 save_state (_current_snapshot_name);
381 remove_pending_capture_state ();
382 state_was_pending = false;
385 BootMessage (_("Session loading complete"));
391 Session::raid_path () const
393 SearchPath raid_search_path;
395 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
396 raid_search_path += sys::path((*i).path);
399 return raid_search_path.to_string ();
403 Session::setup_raid_path (string path)
412 session_dirs.clear ();
414 SearchPath search_path(path);
415 SearchPath sound_search_path;
416 SearchPath midi_search_path;
418 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
419 sp.path = (*i).to_string ();
420 sp.blocks = 0; // not needed
421 session_dirs.push_back (sp);
423 SessionDirectory sdir(sp.path);
425 sound_search_path += sdir.sound_path ();
426 midi_search_path += sdir.midi_path ();
429 // reset the round-robin soundfile path thingie
430 last_rr_session_dir = session_dirs.begin();
434 Session::path_is_within_session (const std::string& path)
436 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
437 if (path.find ((*i).path) == 0) {
445 Session::ensure_subdirs ()
449 dir = session_directory().peak_path().to_string();
451 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
452 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
456 dir = session_directory().sound_path().to_string();
458 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
459 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
463 dir = session_directory().midi_path().to_string();
465 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
466 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
470 dir = session_directory().dead_path().to_string();
472 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
473 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
477 dir = session_directory().export_path().to_string();
479 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
480 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
484 dir = analysis_dir ();
486 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
487 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
491 dir = plugins_dir ();
493 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
494 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
501 /** Caller must not hold process lock */
503 Session::create (const string& mix_template, BusProfile* bus_profile)
505 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
506 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
510 if (ensure_subdirs ()) {
514 _writable = exists_and_writable (sys::path (_path));
516 if (!mix_template.empty()) {
517 std::string in_path = mix_template;
519 ifstream in(in_path.c_str());
522 string out_path = _path;
524 out_path += statefile_suffix;
526 ofstream out(out_path.c_str());
534 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
540 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
547 /* Instantiate metadata */
549 _metadata = new SessionMetadata ();
551 /* set initial start + end point */
553 _state_of_the_state = Clean;
555 /* set up Master Out and Control Out if necessary */
561 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
563 if (bus_profile->master_out_channels) {
564 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
568 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
569 boost_debug_shared_ptr_mark_interesting (rt.get(), "Route");
572 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
573 r->input()->ensure_io (count, false, this);
574 r->output()->ensure_io (count, false, this);
576 r->set_remote_control_id (control_id++);
580 if (Config->get_use_monitor_bus()) {
581 boost::shared_ptr<Route> r (new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO));
585 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
586 boost_debug_shared_ptr_mark_interesting (rt, "Route");
589 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
590 r->input()->ensure_io (count, false, this);
591 r->output()->ensure_io (count, false, this);
593 r->set_remote_control_id (control_id);
599 /* prohibit auto-connect to master, because there isn't one */
600 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
604 add_routes (rl, false, false);
607 /* this allows the user to override settings with an environment variable.
610 if (no_auto_connect()) {
611 bus_profile->input_ac = AutoConnectOption (0);
612 bus_profile->output_ac = AutoConnectOption (0);
615 Config->set_input_auto_connect (bus_profile->input_ac);
616 Config->set_output_auto_connect (bus_profile->output_ac);
625 Session::maybe_write_autosave()
627 if (dirty() && record_status() != Recording) {
628 save_state("", true);
633 Session::remove_pending_capture_state ()
635 sys::path pending_state_file_path(_session_dir->root_path());
637 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
641 sys::remove (pending_state_file_path);
643 catch(sys::filesystem_error& ex)
645 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
646 pending_state_file_path.to_string(), ex.what()) << endmsg;
650 /** Rename a state file.
651 * @param snapshot_name Snapshot name.
654 Session::rename_state (string old_name, string new_name)
656 if (old_name == _current_snapshot_name || old_name == _name) {
657 /* refuse to rename the current snapshot or the "main" one */
661 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
662 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
664 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
665 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
669 sys::rename (old_xml_path, new_xml_path);
671 catch (const sys::filesystem_error& err)
673 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
674 old_name, new_name, err.what()) << endmsg;
678 /** Remove a state file.
679 * @param snapshot_name Snapshot name.
682 Session::remove_state (string snapshot_name)
684 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
685 // refuse to remove the current snapshot or the "main" one
689 sys::path xml_path(_session_dir->root_path());
691 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
693 if (!create_backup_file (xml_path)) {
694 // don't remove it if a backup can't be made
695 // create_backup_file will log the error.
700 sys::remove (xml_path);
703 #ifdef HAVE_JACK_SESSION
705 Session::jack_session_event (jack_session_event_t * event)
709 struct tm local_time;
712 localtime_r (&n, &local_time);
713 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
715 if (event->type == JackSessionSaveTemplate)
717 if (save_template( timebuf )) {
718 event->flags = JackSessionSaveError;
720 string cmd ("ardour3 -P -U ");
721 cmd += event->client_uuid;
725 event->command_line = strdup (cmd.c_str());
730 if (save_state (timebuf)) {
731 event->flags = JackSessionSaveError;
733 sys::path xml_path (_session_dir->root_path());
734 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
736 string cmd ("ardour3 -P -U ");
737 cmd += event->client_uuid;
739 cmd += xml_path.to_string();
742 event->command_line = strdup (cmd.c_str());
746 jack_session_reply (_engine.jack(), event);
748 if (event->type == JackSessionSaveAndQuit) {
749 Quit (); /* EMIT SIGNAL */
752 jack_session_event_free( event );
756 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
758 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
761 sys::path xml_path(_session_dir->root_path());
763 if (!_writable || (_state_of_the_state & CannotSave)) {
767 if (!_engine.connected ()) {
768 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
774 /* tell sources we're saving first, in case they write out to a new file
775 * which should be saved with the state rather than the old one */
776 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
777 i->second->session_saved();
780 tree.set_root (&get_state());
782 if (snapshot_name.empty()) {
783 snapshot_name = _current_snapshot_name;
784 } else if (switch_to_snapshot) {
785 _current_snapshot_name = snapshot_name;
790 /* proper save: use statefile_suffix (.ardour in English) */
792 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
794 /* make a backup copy of the old file */
796 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
797 // create_backup_file will log the error
803 /* pending save: use pending_suffix (.pending in English) */
804 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
807 sys::path tmp_path(_session_dir->root_path());
809 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
811 // cerr << "actually writing state to " << xml_path.to_string() << endl;
813 if (!tree.write (tmp_path.to_string())) {
814 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
815 sys::remove (tmp_path);
820 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
821 error << string_compose (_("could not rename temporary session file %1 to %2"),
822 tmp_path.to_string(), xml_path.to_string()) << endmsg;
823 sys::remove (tmp_path);
830 save_history (snapshot_name);
832 bool was_dirty = dirty();
834 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
837 DirtyChanged (); /* EMIT SIGNAL */
840 StateSaved (snapshot_name); /* EMIT SIGNAL */
847 Session::restore_state (string snapshot_name)
849 if (load_state (snapshot_name) == 0) {
850 set_state (*state_tree->root(), Stateful::loading_state_version);
857 Session::load_state (string snapshot_name)
862 state_was_pending = false;
864 /* check for leftover pending state from a crashed capture attempt */
866 sys::path xmlpath(_session_dir->root_path());
867 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
869 if (sys::exists (xmlpath)) {
871 /* there is pending state from a crashed capture attempt */
873 boost::optional<int> r = AskAboutPendingState();
874 if (r.get_value_or (1)) {
875 state_was_pending = true;
879 if (!state_was_pending) {
880 xmlpath = _session_dir->root_path();
881 xmlpath /= snapshot_name;
884 if (!sys::exists (xmlpath)) {
885 xmlpath = _session_dir->root_path();
886 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
887 if (!sys::exists (xmlpath)) {
888 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
893 state_tree = new XMLTree;
897 _writable = exists_and_writable (xmlpath);
899 if (!state_tree->read (xmlpath.to_string())) {
900 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
906 XMLNode& root (*state_tree->root());
908 if (root.name() != X_("Session")) {
909 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
915 const XMLProperty* prop;
917 if ((prop = root.property ("version")) == 0) {
918 /* no version implies very old version of Ardour */
919 Stateful::loading_state_version = 1000;
925 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
926 Stateful::loading_state_version = (major * 1000) + minor;
929 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
931 sys::path backup_path(_session_dir->root_path());
933 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
935 // only create a backup once
936 if (sys::exists (backup_path)) {
940 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
941 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
946 sys::copy_file (xmlpath, backup_path);
948 catch(sys::filesystem_error& ex)
950 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
951 xmlpath.to_string(), ex.what())
961 Session::load_options (const XMLNode& node)
963 LocaleGuard lg (X_("POSIX"));
964 config.set_variables (node);
975 Session::get_template()
977 /* if we don't disable rec-enable, diskstreams
978 will believe they need to store their capture
979 sources in their state node.
982 disable_record (false);
988 Session::state(bool full_state)
990 XMLNode* node = new XMLNode("Session");
993 // store libardour version, just in case
995 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
996 node->add_property("version", string(buf));
998 /* store configuration settings */
1002 node->add_property ("name", _name);
1003 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1004 node->add_property ("sample-rate", buf);
1006 if (session_dirs.size() > 1) {
1010 vector<space_and_path>::iterator i = session_dirs.begin();
1011 vector<space_and_path>::iterator next;
1013 ++i; /* skip the first one */
1017 while (i != session_dirs.end()) {
1021 if (next != session_dirs.end()) {
1031 child = node->add_child ("Path");
1032 child->add_content (p);
1036 /* save the ID counter */
1038 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1039 node->add_property ("id-counter", buf);
1041 /* save the event ID counter */
1043 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1044 node->add_property ("event-counter", buf);
1046 /* various options */
1048 node->add_child_nocopy (config.get_variables ());
1050 node->add_child_nocopy (_metadata->get_state());
1052 child = node->add_child ("Sources");
1055 Glib::Mutex::Lock sl (source_lock);
1057 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1059 /* Don't save information about non-destructive file sources that are empty
1060 and unused by any regions.
1063 boost::shared_ptr<FileSource> fs;
1064 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1065 if (!fs->destructive()) {
1066 if (fs->empty() && !fs->used()) {
1072 child->add_child_nocopy (siter->second->get_state());
1076 child = node->add_child ("Regions");
1079 Glib::Mutex::Lock rl (region_lock);
1080 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1081 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1082 boost::shared_ptr<Region> r = i->second;
1083 /* only store regions not attached to playlists */
1084 if (r->playlist() == 0) {
1085 child->add_child_nocopy (r->state ());
1091 node->add_child_nocopy (_locations->get_state());
1093 // for a template, just create a new Locations, populate it
1094 // with the default start and end, and get the state for that.
1095 Locations loc (*this);
1096 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1097 range->set (max_framepos, 0);
1099 node->add_child_nocopy (loc.get_state());
1102 child = node->add_child ("Bundles");
1104 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1105 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1106 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1108 child->add_child_nocopy (b->get_state());
1113 child = node->add_child ("Routes");
1115 boost::shared_ptr<RouteList> r = routes.reader ();
1117 RoutePublicOrderSorter cmp;
1118 RouteList public_order (*r);
1119 public_order.sort (cmp);
1121 /* the sort should have put control outs first */
1124 assert (_monitor_out == public_order.front());
1127 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1128 if (!(*i)->is_hidden()) {
1130 child->add_child_nocopy ((*i)->get_state());
1132 child->add_child_nocopy ((*i)->get_template());
1138 playlists->add_state (node, full_state);
1140 child = node->add_child ("RouteGroups");
1141 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1142 child->add_child_nocopy ((*i)->get_state());
1146 child = node->add_child ("Click");
1147 child->add_child_nocopy (_click_io->state (full_state));
1151 child = node->add_child ("NamedSelections");
1152 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1154 child->add_child_nocopy ((*i)->get_state());
1159 node->add_child_nocopy (_speakers->get_state());
1160 node->add_child_nocopy (_tempo_map->get_state());
1161 node->add_child_nocopy (get_control_protocol_state());
1164 node->add_child_copy (*_extra_xml);
1171 Session::get_control_protocol_state ()
1173 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1174 return cpm.get_state();
1178 Session::set_state (const XMLNode& node, int version)
1182 const XMLProperty* prop;
1185 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1187 if (node.name() != X_("Session")) {
1188 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1192 if ((prop = node.property ("version")) != 0) {
1193 version = atoi (prop->value ()) * 1000;
1196 if ((prop = node.property ("name")) != 0) {
1197 _name = prop->value ();
1200 if ((prop = node.property (X_("sample-rate"))) != 0) {
1202 _nominal_frame_rate = atoi (prop->value());
1204 if (_nominal_frame_rate != _current_frame_rate) {
1205 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1206 if (r.get_value_or (0)) {
1212 setup_raid_path(_session_dir->root_path().to_string());
1214 if ((prop = node.property (X_("id-counter"))) != 0) {
1216 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1217 ID::init_counter (x);
1219 /* old sessions used a timebased counter, so fake
1220 the startup ID counter based on a standard
1225 ID::init_counter (now);
1228 if ((prop = node.property (X_("event-counter"))) != 0) {
1229 Evoral::init_event_id_counter (atoi (prop->value()));
1232 IO::disable_connecting ();
1234 if ((child = find_named_node (node, "Extra")) != 0) {
1235 _extra_xml = new XMLNode (*child);
1238 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1239 load_options (*child);
1240 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1241 load_options (*child);
1243 error << _("Session: XML state has no options section") << endmsg;
1246 if (version >= 3000) {
1247 if ((child = find_named_node (node, "Metadata")) == 0) {
1248 warning << _("Session: XML state has no metadata section") << endmsg;
1249 } else if (_metadata->set_state (*child, version)) {
1254 if ((child = find_named_node (node, "Locations")) == 0) {
1255 error << _("Session: XML state has no locations section") << endmsg;
1257 } else if (_locations->set_state (*child, version)) {
1261 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1262 _speakers->set_state (*child, version);
1267 if ((location = _locations->auto_loop_location()) != 0) {
1268 set_auto_loop_location (location);
1271 if ((location = _locations->auto_punch_location()) != 0) {
1272 set_auto_punch_location (location);
1275 if ((location = _locations->session_range_location()) != 0) {
1276 delete _session_range_location;
1277 _session_range_location = location;
1280 if (_session_range_location) {
1281 AudioFileSource::set_header_position_offset (_session_range_location->start());
1284 if ((child = find_named_node (node, "Sources")) == 0) {
1285 error << _("Session: XML state has no sources section") << endmsg;
1287 } else if (load_sources (*child)) {
1291 if ((child = find_named_node (node, "TempoMap")) == 0) {
1292 error << _("Session: XML state has no Tempo Map section") << endmsg;
1294 } else if (_tempo_map->set_state (*child, version)) {
1298 if ((child = find_named_node (node, "Regions")) == 0) {
1299 error << _("Session: XML state has no Regions section") << endmsg;
1301 } else if (load_regions (*child)) {
1305 if ((child = find_named_node (node, "Playlists")) == 0) {
1306 error << _("Session: XML state has no playlists section") << endmsg;
1308 } else if (playlists->load (*this, *child)) {
1312 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1314 } else if (playlists->load_unused (*this, *child)) {
1318 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1319 if (load_named_selections (*child)) {
1324 if (version >= 3000) {
1325 if ((child = find_named_node (node, "Bundles")) == 0) {
1326 warning << _("Session: XML state has no bundles section") << endmsg;
1329 /* We can't load Bundles yet as they need to be able
1330 to convert from port names to Port objects, which can't happen until
1332 _bundle_xml_node = new XMLNode (*child);
1336 if (version < 3000) {
1337 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1338 error << _("Session: XML state has no diskstreams section") << endmsg;
1340 } else if (load_diskstreams_2X (*child, version)) {
1345 if ((child = find_named_node (node, "Routes")) == 0) {
1346 error << _("Session: XML state has no routes section") << endmsg;
1348 } else if (load_routes (*child, version)) {
1352 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1353 _diskstreams_2X.clear ();
1355 if (version >= 3000) {
1357 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1358 error << _("Session: XML state has no route groups section") << endmsg;
1360 } else if (load_route_groups (*child, version)) {
1364 } else if (version < 3000) {
1366 if ((child = find_named_node (node, "EditGroups")) == 0) {
1367 error << _("Session: XML state has no edit groups section") << endmsg;
1369 } else if (load_route_groups (*child, version)) {
1373 if ((child = find_named_node (node, "MixGroups")) == 0) {
1374 error << _("Session: XML state has no mix groups section") << endmsg;
1376 } else if (load_route_groups (*child, version)) {
1381 if ((child = find_named_node (node, "Click")) == 0) {
1382 warning << _("Session: XML state has no click section") << endmsg;
1383 } else if (_click_io) {
1384 _click_io->set_state (*child, version);
1387 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1388 ControlProtocolManager::instance().set_protocol_states (*child);
1391 /* here beginneth the second phase ... */
1393 StateReady (); /* EMIT SIGNAL */
1402 Session::load_routes (const XMLNode& node, int version)
1405 XMLNodeConstIterator niter;
1406 RouteList new_routes;
1408 nlist = node.children();
1412 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1414 boost::shared_ptr<Route> route;
1415 if (version < 3000) {
1416 route = XMLRouteFactory_2X (**niter, version);
1418 route = XMLRouteFactory (**niter, version);
1422 error << _("Session: cannot create Route from XML description.") << endmsg;
1426 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1428 new_routes.push_back (route);
1431 add_routes (new_routes, false, false);
1436 boost::shared_ptr<Route>
1437 Session::XMLRouteFactory (const XMLNode& node, int version)
1439 boost::shared_ptr<Route> ret;
1441 if (node.name() != "Route") {
1445 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1447 DataType type = DataType::AUDIO;
1448 const XMLProperty* prop = node.property("default-type");
1451 type = DataType (prop->value());
1454 assert (type != DataType::NIL);
1458 boost::shared_ptr<Track> track;
1460 if (type == DataType::AUDIO) {
1461 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1463 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1466 if (track->init()) {
1470 if (track->set_state (node, version)) {
1474 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1475 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1480 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1482 if (r->init () == 0 && r->set_state (node, version) == 0) {
1483 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1484 boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1493 boost::shared_ptr<Route>
1494 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1496 boost::shared_ptr<Route> ret;
1498 if (node.name() != "Route") {
1502 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1504 ds_prop = node.property (X_("diskstream"));
1507 DataType type = DataType::AUDIO;
1508 const XMLProperty* prop = node.property("default-type");
1511 type = DataType (prop->value());
1514 assert (type != DataType::NIL);
1518 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1519 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1523 if (i == _diskstreams_2X.end()) {
1524 error << _("Could not find diskstream for route") << endmsg;
1525 return boost::shared_ptr<Route> ();
1528 boost::shared_ptr<Track> track;
1530 if (type == DataType::AUDIO) {
1531 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1533 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1536 if (track->init()) {
1540 if (track->set_state (node, version)) {
1544 track->set_diskstream (*i);
1546 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1547 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1552 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1554 if (r->init () == 0 && r->set_state (node, version) == 0) {
1555 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1556 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1566 Session::load_regions (const XMLNode& node)
1569 XMLNodeConstIterator niter;
1570 boost::shared_ptr<Region> region;
1572 nlist = node.children();
1576 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1577 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1578 error << _("Session: cannot create Region from XML description.");
1579 const XMLProperty *name = (**niter).property("name");
1582 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1592 boost::shared_ptr<Region>
1593 Session::XMLRegionFactory (const XMLNode& node, bool full)
1595 const XMLProperty* type = node.property("type");
1599 if (!type || type->value() == "audio") {
1600 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1601 } else if (type->value() == "midi") {
1602 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1605 } catch (failed_constructor& err) {
1606 return boost::shared_ptr<Region> ();
1609 return boost::shared_ptr<Region> ();
1612 boost::shared_ptr<AudioRegion>
1613 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1615 const XMLProperty* prop;
1616 boost::shared_ptr<Source> source;
1617 boost::shared_ptr<AudioSource> as;
1619 SourceList master_sources;
1620 uint32_t nchans = 1;
1623 if (node.name() != X_("Region")) {
1624 return boost::shared_ptr<AudioRegion>();
1627 if ((prop = node.property (X_("channels"))) != 0) {
1628 nchans = atoi (prop->value().c_str());
1631 if ((prop = node.property ("name")) == 0) {
1632 cerr << "no name for this region\n";
1636 if ((prop = node.property (X_("source-0"))) == 0) {
1637 if ((prop = node.property ("source")) == 0) {
1638 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1639 return boost::shared_ptr<AudioRegion>();
1643 PBD::ID s_id (prop->value());
1645 if ((source = source_by_id (s_id)) == 0) {
1646 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1647 return boost::shared_ptr<AudioRegion>();
1650 as = boost::dynamic_pointer_cast<AudioSource>(source);
1652 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1653 return boost::shared_ptr<AudioRegion>();
1656 sources.push_back (as);
1658 /* pickup other channels */
1660 for (uint32_t n=1; n < nchans; ++n) {
1661 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1662 if ((prop = node.property (buf)) != 0) {
1664 PBD::ID id2 (prop->value());
1666 if ((source = source_by_id (id2)) == 0) {
1667 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1668 return boost::shared_ptr<AudioRegion>();
1671 as = boost::dynamic_pointer_cast<AudioSource>(source);
1673 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1674 return boost::shared_ptr<AudioRegion>();
1676 sources.push_back (as);
1680 for (uint32_t n = 0; n < nchans; ++n) {
1681 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1682 if ((prop = node.property (buf)) != 0) {
1684 PBD::ID id2 (prop->value());
1686 if ((source = source_by_id (id2)) == 0) {
1687 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1688 return boost::shared_ptr<AudioRegion>();
1691 as = boost::dynamic_pointer_cast<AudioSource>(source);
1693 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1694 return boost::shared_ptr<AudioRegion>();
1696 master_sources.push_back (as);
1701 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1703 /* a final detail: this is the one and only place that we know how long missing files are */
1705 if (region->whole_file()) {
1706 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1707 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1709 sfp->set_length (region->length());
1714 if (!master_sources.empty()) {
1715 if (master_sources.size() != nchans) {
1716 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1718 region->set_master_sources (master_sources);
1726 catch (failed_constructor& err) {
1727 return boost::shared_ptr<AudioRegion>();
1731 boost::shared_ptr<MidiRegion>
1732 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1734 const XMLProperty* prop;
1735 boost::shared_ptr<Source> source;
1736 boost::shared_ptr<MidiSource> ms;
1739 if (node.name() != X_("Region")) {
1740 return boost::shared_ptr<MidiRegion>();
1743 if ((prop = node.property ("name")) == 0) {
1744 cerr << "no name for this region\n";
1748 if ((prop = node.property (X_("source-0"))) == 0) {
1749 if ((prop = node.property ("source")) == 0) {
1750 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1751 return boost::shared_ptr<MidiRegion>();
1755 PBD::ID s_id (prop->value());
1757 if ((source = source_by_id (s_id)) == 0) {
1758 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1759 return boost::shared_ptr<MidiRegion>();
1762 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1764 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1765 return boost::shared_ptr<MidiRegion>();
1768 sources.push_back (ms);
1771 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1772 /* a final detail: this is the one and only place that we know how long missing files are */
1774 if (region->whole_file()) {
1775 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1776 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1778 sfp->set_length (region->length());
1786 catch (failed_constructor& err) {
1787 return boost::shared_ptr<MidiRegion>();
1792 Session::get_sources_as_xml ()
1795 XMLNode* node = new XMLNode (X_("Sources"));
1796 Glib::Mutex::Lock lm (source_lock);
1798 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1799 node->add_child_nocopy (i->second->get_state());
1806 Session::path_from_region_name (DataType type, string name, string identifier)
1808 char buf[PATH_MAX+1];
1810 SessionDirectory sdir(get_best_session_directory_for_new_source());
1811 sys::path source_dir = ((type == DataType::AUDIO)
1812 ? sdir.sound_path() : sdir.midi_path());
1814 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1816 for (n = 0; n < 999999; ++n) {
1817 if (identifier.length()) {
1818 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1819 identifier.c_str(), n, ext.c_str());
1821 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1825 sys::path source_path = source_dir / buf;
1827 if (!sys::exists (source_path)) {
1828 return source_path.to_string();
1832 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1841 Session::load_sources (const XMLNode& node)
1844 XMLNodeConstIterator niter;
1845 boost::shared_ptr<Source> source;
1847 nlist = node.children();
1851 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1854 if ((source = XMLSourceFactory (**niter)) == 0) {
1855 error << _("Session: cannot create Source from XML description.") << endmsg;
1858 } catch (MissingSource& err) {
1862 if (!no_questions_about_missing_files) {
1863 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1868 switch (user_choice) {
1870 /* user added a new search location, so try again */
1875 /* user asked to quit the entire session load
1880 no_questions_about_missing_files = true;
1884 no_questions_about_missing_files = true;
1889 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1890 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1899 boost::shared_ptr<Source>
1900 Session::XMLSourceFactory (const XMLNode& node)
1902 if (node.name() != "Source") {
1903 return boost::shared_ptr<Source>();
1907 /* note: do peak building in another thread when loading session state */
1908 return SourceFactory::create (*this, node, true);
1911 catch (failed_constructor& err) {
1912 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1913 return boost::shared_ptr<Source>();
1918 Session::save_template (string template_name)
1922 if (_state_of_the_state & CannotSave) {
1926 sys::path user_template_dir(user_template_directory());
1930 sys::create_directories (user_template_dir);
1932 catch(sys::filesystem_error& ex)
1934 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1935 user_template_dir.to_string(), ex.what()) << endmsg;
1939 tree.set_root (&get_template());
1941 sys::path template_file_path(user_template_dir);
1942 template_file_path /= template_name + template_suffix;
1944 if (sys::exists (template_file_path))
1946 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1947 template_file_path.to_string()) << endmsg;
1951 if (!tree.write (template_file_path.to_string())) {
1952 error << _("template not saved") << endmsg;
1960 Session::rename_template (string old_name, string new_name)
1962 sys::path old_path (user_template_directory());
1963 old_path /= old_name + template_suffix;
1965 sys::path new_path(user_template_directory());
1966 new_path /= new_name + template_suffix;
1968 if (sys::exists (new_path)) {
1969 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1970 new_path.to_string()) << endmsg;
1975 sys::rename (old_path, new_path);
1983 Session::delete_template (string name)
1985 sys::path path = user_template_directory();
1986 path /= name + template_suffix;
1997 Session::refresh_disk_space ()
2000 struct statfs statfsbuf;
2001 vector<space_and_path>::iterator i;
2002 Glib::Mutex::Lock lm (space_lock);
2005 /* get freespace on every FS that is part of the session path */
2007 _total_free_4k_blocks = 0;
2009 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2010 statfs ((*i).path.c_str(), &statfsbuf);
2012 scale = statfsbuf.f_bsize/4096.0;
2014 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2015 _total_free_4k_blocks += (*i).blocks;
2021 Session::get_best_session_directory_for_new_source ()
2023 vector<space_and_path>::iterator i;
2024 string result = _session_dir->root_path().to_string();
2026 /* handle common case without system calls */
2028 if (session_dirs.size() == 1) {
2032 /* OK, here's the algorithm we're following here:
2034 We want to select which directory to use for
2035 the next file source to be created. Ideally,
2036 we'd like to use a round-robin process so as to
2037 get maximum performance benefits from splitting
2038 the files across multiple disks.
2040 However, in situations without much diskspace, an
2041 RR approach may end up filling up a filesystem
2042 with new files while others still have space.
2043 Its therefore important to pay some attention to
2044 the freespace in the filesystem holding each
2045 directory as well. However, if we did that by
2046 itself, we'd keep creating new files in the file
2047 system with the most space until it was as full
2048 as all others, thus negating any performance
2049 benefits of this RAID-1 like approach.
2051 So, we use a user-configurable space threshold. If
2052 there are at least 2 filesystems with more than this
2053 much space available, we use RR selection between them.
2054 If not, then we pick the filesystem with the most space.
2056 This gets a good balance between the two
2060 refresh_disk_space ();
2062 int free_enough = 0;
2064 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2065 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2070 if (free_enough >= 2) {
2071 /* use RR selection process, ensuring that the one
2075 i = last_rr_session_dir;
2078 if (++i == session_dirs.end()) {
2079 i = session_dirs.begin();
2082 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2083 if (create_session_directory ((*i).path)) {
2085 last_rr_session_dir = i;
2090 } while (i != last_rr_session_dir);
2094 /* pick FS with the most freespace (and that
2095 seems to actually work ...)
2098 vector<space_and_path> sorted;
2099 space_and_path_ascending_cmp cmp;
2101 sorted = session_dirs;
2102 sort (sorted.begin(), sorted.end(), cmp);
2104 for (i = sorted.begin(); i != sorted.end(); ++i) {
2105 if (create_session_directory ((*i).path)) {
2107 last_rr_session_dir = i;
2117 Session::load_named_selections (const XMLNode& node)
2120 XMLNodeConstIterator niter;
2123 nlist = node.children();
2127 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2129 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2130 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2138 Session::XMLNamedSelectionFactory (const XMLNode& node)
2141 return new NamedSelection (*this, node);
2144 catch (failed_constructor& err) {
2150 Session::automation_dir () const
2152 return Glib::build_filename (_path, "automation");
2156 Session::analysis_dir () const
2158 return Glib::build_filename (_path, "analysis");
2162 Session::plugins_dir () const
2164 return Glib::build_filename (_path, "plugins");
2168 Session::load_bundles (XMLNode const & node)
2170 XMLNodeList nlist = node.children();
2171 XMLNodeConstIterator niter;
2175 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2176 if ((*niter)->name() == "InputBundle") {
2177 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2178 } else if ((*niter)->name() == "OutputBundle") {
2179 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2181 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2190 Session::load_route_groups (const XMLNode& node, int version)
2192 XMLNodeList nlist = node.children();
2193 XMLNodeConstIterator niter;
2197 if (version >= 3000) {
2199 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2200 if ((*niter)->name() == "RouteGroup") {
2201 RouteGroup* rg = new RouteGroup (*this, "");
2202 add_route_group (rg);
2203 rg->set_state (**niter, version);
2207 } else if (version < 3000) {
2209 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2210 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2211 RouteGroup* rg = new RouteGroup (*this, "");
2212 add_route_group (rg);
2213 rg->set_state (**niter, version);
2222 Session::auto_save()
2224 save_state (_current_snapshot_name);
2228 state_file_filter (const string &str, void */*arg*/)
2230 return (str.length() > strlen(statefile_suffix) &&
2231 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2235 bool operator()(const string* a, const string* b) {
2241 remove_end(string* state)
2243 string statename(*state);
2245 string::size_type start,end;
2246 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2247 statename = statename.substr (start+1);
2250 if ((end = statename.rfind(".ardour")) == string::npos) {
2251 end = statename.length();
2254 return new string(statename.substr (0, end));
2258 Session::possible_states (string path)
2260 PathScanner scanner;
2261 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2263 transform(states->begin(), states->end(), states->begin(), remove_end);
2266 sort (states->begin(), states->end(), cmp);
2272 Session::possible_states () const
2274 return possible_states(_path);
2278 Session::add_route_group (RouteGroup* g)
2280 _route_groups.push_back (g);
2281 route_group_added (g); /* EMIT SIGNAL */
2283 g->MembershipChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2284 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2290 Session::remove_route_group (RouteGroup& rg)
2292 list<RouteGroup*>::iterator i;
2294 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2295 _route_groups.erase (i);
2298 route_group_removed (); /* EMIT SIGNAL */
2302 /** Set a new order for our route groups, without adding or removing any.
2303 * @param groups Route group list in the new order.
2306 Session::reorder_route_groups (list<RouteGroup*> groups)
2308 _route_groups = groups;
2310 route_groups_reordered (); /* EMIT SIGNAL */
2316 Session::route_group_by_name (string name)
2318 list<RouteGroup *>::iterator i;
2320 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2321 if ((*i)->name() == name) {
2329 Session::all_route_group() const
2331 return *_all_route_group;
2335 Session::add_commands (vector<Command*> const & cmds)
2337 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2343 Session::begin_reversible_command (const string& name)
2345 begin_reversible_command (g_quark_from_string (name.c_str ()));
2348 /** Begin a reversible command using a GQuark to identify it.
2349 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2350 * but there must be as many begin...()s as there are commit...()s.
2353 Session::begin_reversible_command (GQuark q)
2355 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2356 to hold all the commands that are committed. This keeps the order of
2357 commands correct in the history.
2360 if (_current_trans == 0) {
2361 /* start a new transaction */
2362 assert (_current_trans_quarks.empty ());
2363 _current_trans = new UndoTransaction();
2364 _current_trans->set_name (g_quark_to_string (q));
2367 _current_trans_quarks.push_front (q);
2371 Session::commit_reversible_command (Command *cmd)
2373 assert (_current_trans);
2374 assert (!_current_trans_quarks.empty ());
2379 _current_trans->add_command (cmd);
2382 _current_trans_quarks.pop_front ();
2384 if (!_current_trans_quarks.empty ()) {
2385 /* the transaction we're committing is not the top-level one */
2389 if (_current_trans->empty()) {
2390 /* no commands were added to the transaction, so just get rid of it */
2391 delete _current_trans;
2396 gettimeofday (&now, 0);
2397 _current_trans->set_timestamp (now);
2399 _history.add (_current_trans);
2404 accept_all_audio_files (const string& path, void */*arg*/)
2406 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2410 if (!AudioFileSource::safe_audio_file_extension (path)) {
2418 accept_all_midi_files (const string& path, void */*arg*/)
2420 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2424 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2425 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2426 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2430 accept_all_state_files (const string& path, void */*arg*/)
2432 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2436 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2440 Session::find_all_sources (string path, set<string>& result)
2445 if (!tree.read (path)) {
2449 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2454 XMLNodeConstIterator niter;
2456 nlist = node->children();
2460 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2464 if ((prop = (*niter)->property (X_("type"))) == 0) {
2468 DataType type (prop->value());
2470 if ((prop = (*niter)->property (X_("name"))) == 0) {
2474 if (Glib::path_is_absolute (prop->value())) {
2475 /* external file, ignore */
2483 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2484 result.insert (found_path);
2492 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2494 PathScanner scanner;
2495 vector<string*>* state_files;
2497 string this_snapshot_path;
2503 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2504 ripped = ripped.substr (0, ripped.length() - 1);
2507 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2509 if (state_files == 0) {
2514 this_snapshot_path = _path;
2515 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2516 this_snapshot_path += statefile_suffix;
2518 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2520 if (exclude_this_snapshot && **i == this_snapshot_path) {
2524 if (find_all_sources (**i, result) < 0) {
2532 struct RegionCounter {
2533 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2534 AudioSourceList::iterator iter;
2535 boost::shared_ptr<Region> region;
2538 RegionCounter() : count (0) {}
2542 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2544 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2545 return r.get_value_or (1);
2549 Session::cleanup_regions ()
2551 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2553 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2555 boost::shared_ptr<AudioRegion> audio_region = boost::dynamic_pointer_cast<AudioRegion>( i->second);
2557 if (!audio_region) {
2561 uint32_t used = playlists->region_use_count (audio_region);
2563 if (used == 0 && !audio_region->automatic()) {
2564 RegionFactory::map_remove(i->second);
2568 /* dump the history list */
2575 Session::cleanup_sources (CleanupReport& rep)
2577 // FIXME: needs adaptation to midi
2579 vector<boost::shared_ptr<Source> > dead_sources;
2580 PathScanner scanner;
2583 vector<space_and_path>::iterator i;
2584 vector<space_and_path>::iterator nexti;
2585 vector<string*>* candidates;
2586 vector<string*>* candidates2;
2587 vector<string> unused;
2588 set<string> all_sources;
2593 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2595 /* consider deleting all unused playlists */
2597 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2602 /* sync the "all regions" property of each playlist with its current state
2605 playlists->sync_all_regions_with_regions ();
2607 /* find all un-used sources */
2612 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2614 SourceMap::iterator tmp;
2619 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2623 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2624 dead_sources.push_back (i->second);
2625 i->second->drop_references ();
2631 /* build a list of all the possible audio directories for the session */
2633 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2638 SessionDirectory sdir ((*i).path);
2639 audio_path += sdir.sound_path().to_string();
2641 if (nexti != session_dirs.end()) {
2649 /* build a list of all the possible midi directories for the session */
2651 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2656 SessionDirectory sdir ((*i).path);
2657 midi_path += sdir.midi_path().to_string();
2659 if (nexti != session_dirs.end()) {
2666 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2667 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2673 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2674 candidates->push_back (*i);
2679 candidates = candidates2; // might still be null
2682 /* find all sources, but don't use this snapshot because the
2683 state file on disk still references sources we may have already
2687 find_all_sources_across_snapshots (all_sources, true);
2689 /* add our current source list
2692 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2693 boost::shared_ptr<FileSource> fs;
2694 SourceMap::iterator tmp = i;
2697 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2698 if (playlists->source_use_count (fs) != 0) {
2699 all_sources.insert (fs->path());
2702 /* we might not remove this source from disk, because it may be used
2703 by other snapshots, but its not being used in this version
2704 so lets get rid of it now, along with any representative regions
2708 RegionFactory::remove_regions_using_source (i->second);
2716 char tmppath1[PATH_MAX+1];
2717 char tmppath2[PATH_MAX+1];
2720 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2725 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2727 if (realpath(spath.c_str(), tmppath1) == 0) {
2728 error << string_compose (_("Cannot expand path %1 (%2)"),
2729 spath, strerror (errno)) << endmsg;
2733 if (realpath((*i).c_str(), tmppath2) == 0) {
2734 error << string_compose (_("Cannot expand path %1 (%2)"),
2735 (*i), strerror (errno)) << endmsg;
2739 if (strcmp(tmppath1, tmppath2) == 0) {
2746 unused.push_back (spath);
2755 /* now try to move all unused files into the "dead" directory(ies) */
2757 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2758 struct stat statbuf;
2762 /* don't move the file across filesystems, just
2763 stick it in the `dead_dir_name' directory
2764 on whichever filesystem it was already on.
2767 if ((*x).find ("/sounds/") != string::npos) {
2769 /* old school, go up 1 level */
2771 newpath = Glib::path_get_dirname (*x); // "sounds"
2772 newpath = Glib::path_get_dirname (newpath); // "session-name"
2776 /* new school, go up 4 levels */
2778 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2779 newpath = Glib::path_get_dirname (newpath); // "session-name"
2780 newpath = Glib::path_get_dirname (newpath); // "interchange"
2781 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2784 newpath = Glib::build_filename (newpath, dead_dir_name);
2786 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2787 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2791 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2793 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2795 /* the new path already exists, try versioning */
2797 char buf[PATH_MAX+1];
2801 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2804 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2805 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2809 if (version == 999) {
2810 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2814 newpath = newpath_v;
2819 /* it doesn't exist, or we can't read it or something */
2823 stat ((*x).c_str(), &statbuf);
2825 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2826 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2827 (*x), newpath, strerror (errno))
2832 /* see if there an easy to find peakfile for this file, and remove it.
2835 string base = basename_nosuffix (*x);
2836 base += "%A"; /* this is what we add for the channel suffix of all native files,
2837 or for the first channel of embedded files. it will miss
2838 some peakfiles for other channels
2840 string peakpath = peak_path (base);
2842 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2843 if (::unlink (peakpath.c_str()) != 0) {
2844 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2845 peakpath, _path, strerror (errno))
2847 /* try to back out */
2848 rename (newpath.c_str(), _path.c_str());
2853 rep.paths.push_back (*x);
2854 rep.space += statbuf.st_size;
2857 /* dump the history list */
2861 /* save state so we don't end up a session file
2862 referring to non-existent sources.
2869 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2875 Session::cleanup_trash_sources (CleanupReport& rep)
2877 // FIXME: needs adaptation for MIDI
2879 vector<space_and_path>::iterator i;
2885 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2887 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2889 clear_directory (dead_dir, &rep.space, &rep.paths);
2896 Session::set_dirty ()
2898 bool was_dirty = dirty();
2900 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2904 DirtyChanged(); /* EMIT SIGNAL */
2910 Session::set_clean ()
2912 bool was_dirty = dirty();
2914 _state_of_the_state = Clean;
2918 DirtyChanged(); /* EMIT SIGNAL */
2923 Session::set_deletion_in_progress ()
2925 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2929 Session::clear_deletion_in_progress ()
2931 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2935 Session::add_controllable (boost::shared_ptr<Controllable> c)
2937 /* this adds a controllable to the list managed by the Session.
2938 this is a subset of those managed by the Controllable class
2939 itself, and represents the only ones whose state will be saved
2940 as part of the session.
2943 Glib::Mutex::Lock lm (controllables_lock);
2944 controllables.insert (c);
2947 struct null_deleter { void operator()(void const *) const {} };
2950 Session::remove_controllable (Controllable* c)
2952 if (_state_of_the_state | Deletion) {
2956 Glib::Mutex::Lock lm (controllables_lock);
2958 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2960 if (x != controllables.end()) {
2961 controllables.erase (x);
2965 boost::shared_ptr<Controllable>
2966 Session::controllable_by_id (const PBD::ID& id)
2968 Glib::Mutex::Lock lm (controllables_lock);
2970 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2971 if ((*i)->id() == id) {
2976 return boost::shared_ptr<Controllable>();
2979 boost::shared_ptr<Controllable>
2980 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2982 boost::shared_ptr<Controllable> c;
2983 boost::shared_ptr<Route> r;
2985 switch (desc.top_level_type()) {
2986 case ControllableDescriptor::NamedRoute:
2988 std::string str = desc.top_level_name();
2989 if (str == "master") {
2991 } else if (str == "control" || str == "listen") {
2994 r = route_by_name (desc.top_level_name());
2999 case ControllableDescriptor::RemoteControlID:
3000 r = route_by_remote_id (desc.rid());
3008 switch (desc.subtype()) {
3009 case ControllableDescriptor::Gain:
3010 c = r->gain_control ();
3013 case ControllableDescriptor::Solo:
3014 c = r->solo_control();
3017 case ControllableDescriptor::Mute:
3018 c = r->mute_control();
3021 case ControllableDescriptor::Recenable:
3023 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3026 c = t->rec_enable_control ();
3031 case ControllableDescriptor::PanDirection:
3033 c = r->pannable()->pan_azimuth_control;
3037 case ControllableDescriptor::PanWidth:
3039 c = r->pannable()->pan_width_control;
3043 case ControllableDescriptor::PanElevation:
3045 c = r->pannable()->pan_elevation_control;
3049 case ControllableDescriptor::Balance:
3050 /* XXX simple pan control */
3053 case ControllableDescriptor::PluginParameter:
3055 uint32_t plugin = desc.target (0);
3056 uint32_t parameter_index = desc.target (1);
3058 /* revert to zero based counting */
3064 if (parameter_index > 0) {
3068 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3071 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3072 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3077 case ControllableDescriptor::SendGain:
3079 uint32_t send = desc.target (0);
3081 /* revert to zero-based counting */
3087 boost::shared_ptr<Processor> p = r->nth_send (send);
3090 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3091 boost::shared_ptr<Amp> a = s->amp();
3094 c = s->amp()->gain_control();
3101 /* relax and return a null pointer */
3109 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3112 Stateful::add_instant_xml (node, _path);
3115 if (write_to_config) {
3116 Config->add_instant_xml (node);
3121 Session::instant_xml (const string& node_name)
3123 return Stateful::instant_xml (node_name, _path);
3127 Session::save_history (string snapshot_name)
3135 if (snapshot_name.empty()) {
3136 snapshot_name = _current_snapshot_name;
3139 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3140 const string backup_filename = history_filename + backup_suffix;
3141 const sys::path xml_path = _session_dir->root_path() / history_filename;
3142 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3144 if (sys::exists (xml_path)) {
3147 sys::rename (xml_path, backup_path);
3149 catch (const sys::filesystem_error& err)
3151 error << _("could not backup old history file, current history not saved") << endmsg;
3156 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3160 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3162 if (!tree.write (xml_path.to_string()))
3164 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3168 sys::remove (xml_path);
3169 sys::rename (backup_path, xml_path);
3171 catch (const sys::filesystem_error& err)
3173 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3174 backup_path.to_string(), err.what()) << endmsg;
3184 Session::restore_history (string snapshot_name)
3188 if (snapshot_name.empty()) {
3189 snapshot_name = _current_snapshot_name;
3192 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3193 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3195 info << "Loading history from " << xml_path.to_string() << endmsg;
3197 if (!sys::exists (xml_path)) {
3198 info << string_compose (_("%1: no history file \"%2\" for this session."),
3199 _name, xml_path.to_string()) << endmsg;
3203 if (!tree.read (xml_path.to_string())) {
3204 error << string_compose (_("Could not understand session history file \"%1\""),
3205 xml_path.to_string()) << endmsg;
3212 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3215 UndoTransaction* ut = new UndoTransaction ();
3218 ut->set_name(t->property("name")->value());
3219 stringstream ss(t->property("tv-sec")->value());
3221 ss.str(t->property("tv-usec")->value());
3223 ut->set_timestamp(tv);
3225 for (XMLNodeConstIterator child_it = t->children().begin();
3226 child_it != t->children().end(); child_it++)
3228 XMLNode *n = *child_it;
3231 if (n->name() == "MementoCommand" ||
3232 n->name() == "MementoUndoCommand" ||
3233 n->name() == "MementoRedoCommand") {
3235 if ((c = memento_command_factory(n))) {
3239 } else if (n->name() == "NoteDiffCommand") {
3240 PBD::ID id (n->property("midi-source")->value());
3241 boost::shared_ptr<MidiSource> midi_source =
3242 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3244 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3246 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3249 } else if (n->name() == "SysExDiffCommand") {
3251 PBD::ID id (n->property("midi-source")->value());
3252 boost::shared_ptr<MidiSource> midi_source =
3253 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3255 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3257 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3260 } else if (n->name() == "PatchChangeDiffCommand") {
3262 PBD::ID id (n->property("midi-source")->value());
3263 boost::shared_ptr<MidiSource> midi_source =
3264 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3266 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3268 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3271 } else if (n->name() == "StatefulDiffCommand") {
3272 if ((c = stateful_diff_command_factory (n))) {
3273 ut->add_command (c);
3276 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3287 Session::config_changed (std::string p, bool ours)
3293 if (p == "seamless-loop") {
3295 } else if (p == "rf-speed") {
3297 } else if (p == "auto-loop") {
3299 } else if (p == "auto-input") {
3301 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3302 /* auto-input only makes a difference if we're rolling */
3303 set_track_monitor_input_status (!config.get_auto_input());
3306 } else if (p == "punch-in") {
3310 if ((location = _locations->auto_punch_location()) != 0) {
3312 if (config.get_punch_in ()) {
3313 replace_event (SessionEvent::PunchIn, location->start());
3315 remove_event (location->start(), SessionEvent::PunchIn);
3319 } else if (p == "punch-out") {
3323 if ((location = _locations->auto_punch_location()) != 0) {
3325 if (config.get_punch_out()) {
3326 replace_event (SessionEvent::PunchOut, location->end());
3328 clear_events (SessionEvent::PunchOut);
3332 } else if (p == "edit-mode") {
3334 Glib::Mutex::Lock lm (playlists->lock);
3336 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3337 (*i)->set_edit_mode (Config->get_edit_mode ());
3340 } else if (p == "use-video-sync") {
3342 waiting_for_sync_offset = config.get_use_video_sync();
3344 } else if (p == "mmc-control") {
3346 //poke_midi_thread ();
3348 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3350 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3352 } else if (p == "mmc-send-id") {
3354 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3356 } else if (p == "midi-control") {
3358 //poke_midi_thread ();
3360 } else if (p == "raid-path") {
3362 setup_raid_path (config.get_raid_path());
3364 } else if (p == "timecode-format") {
3368 } else if (p == "video-pullup") {
3372 } else if (p == "seamless-loop") {
3374 if (play_loop && transport_rolling()) {
3375 // to reset diskstreams etc
3376 request_play_loop (true);
3379 } else if (p == "rf-speed") {
3381 cumulative_rf_motion = 0;
3384 } else if (p == "click-sound") {
3386 setup_click_sounds (1);
3388 } else if (p == "click-emphasis-sound") {
3390 setup_click_sounds (-1);
3392 } else if (p == "clicking") {
3394 if (Config->get_clicking()) {
3395 if (_click_io && click_data) { // don't require emphasis data
3402 } else if (p == "send-mtc") {
3404 if (Config->get_send_mtc ()) {
3405 /* mark us ready to send */
3406 next_quarter_frame_to_send = 0;
3409 } else if (p == "send-mmc") {
3411 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3413 } else if (p == "midi-feedback") {
3415 session_midi_feedback = Config->get_midi_feedback();
3417 } else if (p == "jack-time-master") {
3419 engine().reset_timebase ();
3421 } else if (p == "native-file-header-format") {
3423 if (!first_file_header_format_reset) {
3424 reset_native_file_format ();
3427 first_file_header_format_reset = false;
3429 } else if (p == "native-file-data-format") {
3431 if (!first_file_data_format_reset) {
3432 reset_native_file_format ();
3435 first_file_data_format_reset = false;
3437 } else if (p == "external-sync") {
3438 if (!config.get_external_sync()) {
3439 drop_sync_source ();
3441 switch_to_sync_source (config.get_sync_source());
3443 } else if (p == "remote-model") {
3444 set_remote_control_ids ();
3445 } else if (p == "denormal-model") {
3447 } else if (p == "history-depth") {
3448 set_history_depth (Config->get_history_depth());
3449 } else if (p == "sync-all-route-ordering") {
3450 sync_order_keys ("session");
3451 } else if (p == "initial-program-change") {
3453 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3456 buf[0] = MIDI::program; // channel zero by default
3457 buf[1] = (Config->get_initial_program_change() & 0x7f);
3459 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3461 } else if (p == "solo-mute-override") {
3462 // catch_up_on_solo_mute_override ();
3463 } else if (p == "listen-position" || p == "pfl-position") {
3464 listen_position_changed ();
3465 } else if (p == "solo-control-is-listen-control") {
3466 solo_control_mode_changed ();
3467 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3468 last_timecode_valid = false;
3475 Session::set_history_depth (uint32_t d)
3477 _history.set_depth (d);
3481 Session::load_diskstreams_2X (XMLNode const & node, int)
3484 XMLNodeConstIterator citer;
3486 clist = node.children();
3488 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3491 /* diskstreams added automatically by DiskstreamCreated handler */
3492 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3493 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3494 _diskstreams_2X.push_back (dsp);
3496 error << _("Session: unknown diskstream type in XML") << endmsg;
3500 catch (failed_constructor& err) {
3501 error << _("Session: could not load diskstream via XML state") << endmsg;
3509 /** Connect things to the MMC object */
3511 Session::setup_midi_machine_control ()
3513 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3515 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3516 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3517 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3518 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3519 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3520 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3521 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3522 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3523 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3524 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3525 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3526 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3527 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3529 /* also handle MIDI SPP because its so common */
3531 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3532 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3533 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));
3536 boost::shared_ptr<Controllable>
3537 Session::solo_cut_control() const
3539 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3540 controls in Ardour that currently get presented to the user in the GUI that require
3541 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3543 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3544 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3548 return _solo_cut_control;