2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "libardour-config.h"
33 #include <cstdio> /* snprintf(3) ... grrr */
47 #include <sys/param.h>
48 #include <sys/mount.h>
52 #include <glibmm/thread.h>
54 #include "midi++/mmc.h"
55 #include "midi++/port.h"
56 #include "midi++/manager.h"
58 #include "pbd/boost_debug.h"
59 #include "pbd/controllable_descriptor.h"
60 #include "pbd/enumwriter.h"
61 #include "pbd/error.h"
62 #include "pbd/pathscanner.h"
63 #include "pbd/pthread_utils.h"
64 #include "pbd/search_path.h"
65 #include "pbd/stacktrace.h"
66 #include "pbd/convert.h"
67 #include "pbd/clear_dir.h"
69 #include "ardour/amp.h"
70 #include "ardour/audio_diskstream.h"
71 #include "ardour/audio_track.h"
72 #include "ardour/audioengine.h"
73 #include "ardour/audiofilesource.h"
74 #include "ardour/audioplaylist.h"
75 #include "ardour/audioregion.h"
76 #include "ardour/auditioner.h"
77 #include "ardour/automation_control.h"
78 #include "ardour/buffer.h"
79 #include "ardour/butler.h"
80 #include "ardour/configuration.h"
81 #include "ardour/control_protocol_manager.h"
82 #include "ardour/crossfade.h"
83 #include "ardour/cycle_timer.h"
84 #include "ardour/directory_names.h"
85 #include "ardour/filename_extensions.h"
86 #include "ardour/io_processor.h"
87 #include "ardour/location.h"
88 #include "ardour/midi_diskstream.h"
89 #include "ardour/midi_patch_manager.h"
90 #include "ardour/midi_playlist.h"
91 #include "ardour/midi_region.h"
92 #include "ardour/midi_source.h"
93 #include "ardour/midi_track.h"
94 #include "ardour/named_selection.h"
95 #include "ardour/pannable.h"
96 #include "ardour/processor.h"
97 #include "ardour/port.h"
98 #include "ardour/proxy_controllable.h"
99 #include "ardour/region_factory.h"
100 #include "ardour/route_group.h"
101 #include "ardour/send.h"
102 #include "ardour/session.h"
103 #include "ardour/session_directory.h"
104 #include "ardour/session_metadata.h"
105 #include "ardour/session_state_utils.h"
106 #include "ardour/session_playlists.h"
107 #include "ardour/session_utils.h"
108 #include "ardour/silentfilesource.h"
109 #include "ardour/slave.h"
110 #include "ardour/smf_source.h"
111 #include "ardour/sndfile_helpers.h"
112 #include "ardour/sndfilesource.h"
113 #include "ardour/source_factory.h"
114 #include "ardour/template_utils.h"
115 #include "ardour/tempo.h"
116 #include "ardour/ticker.h"
117 #include "ardour/user_bundle.h"
118 #include "ardour/utils.h"
119 #include "ardour/utils.h"
120 #include "ardour/version.h"
121 #include "ardour/playlist_factory.h"
123 #include "control_protocol/control_protocol.h"
129 using namespace ARDOUR;
133 Session::first_stage_init (string fullpath, string snapshot_name)
135 if (fullpath.length() == 0) {
137 throw failed_constructor();
140 char buf[PATH_MAX+1];
141 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
142 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
144 throw failed_constructor();
149 if (_path[_path.length()-1] != '/') {
150 _path += G_DIR_SEPARATOR;
153 if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
159 /* these two are just provisional settings. set_state()
160 will likely override them.
163 _name = _current_snapshot_name = snapshot_name;
165 set_history_depth (Config->get_history_depth());
167 _current_frame_rate = _engine.frame_rate ();
168 _nominal_frame_rate = _current_frame_rate;
169 _base_frame_rate = _current_frame_rate;
171 _tempo_map = new TempoMap (_current_frame_rate);
172 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
175 _non_soloed_outs_muted = false;
177 _solo_isolated_cnt = 0;
178 g_atomic_int_set (&processing_prohibited, 0);
179 _transport_speed = 0;
180 _last_transport_speed = 0;
181 _target_transport_speed = 0;
182 auto_play_legal = false;
183 transport_sub_state = 0;
184 _transport_frame = 0;
185 _requested_return_frame = -1;
186 _session_range_location = 0;
187 g_atomic_int_set (&_record_status, Disabled);
188 loop_changing = false;
191 _last_roll_location = 0;
192 _last_roll_or_reversal_location = 0;
193 _last_record_location = 0;
194 pending_locate_frame = 0;
195 pending_locate_roll = false;
196 pending_locate_flush = false;
197 state_was_pending = false;
199 outbound_mtc_timecode_frame = 0;
200 next_quarter_frame_to_send = -1;
201 current_block_size = 0;
202 solo_update_disabled = false;
203 _have_captured = false;
204 _worst_output_latency = 0;
205 _worst_input_latency = 0;
206 _worst_track_latency = 0;
207 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
208 _was_seamless = Config->get_seamless_loop ();
210 _send_qf_mtc = false;
211 _pframes_since_last_mtc = 0;
212 g_atomic_int_set (&_playback_load, 100);
213 g_atomic_int_set (&_capture_load, 100);
216 pending_abort = false;
217 destructive_index = 0;
218 first_file_data_format_reset = true;
219 first_file_header_format_reset = true;
220 post_export_sync = false;
223 no_questions_about_missing_files = false;
224 _speakers.reset (new Speakers);
226 AudioDiskstream::allocate_working_buffers();
228 /* default short fade = 15ms */
230 Crossfade::set_short_xfade_length ((framecnt_t) floor (config.get_short_xfade_seconds() * frame_rate()));
231 SndFileSource::setup_standard_crossfades (*this, frame_rate());
233 last_mmc_step.tv_sec = 0;
234 last_mmc_step.tv_usec = 0;
237 /* click sounds are unset by default, which causes us to internal
238 waveforms for clicks.
242 click_emphasis_length = 0;
245 process_function = &Session::process_with_events;
247 if (config.get_use_video_sync()) {
248 waiting_for_sync_offset = true;
250 waiting_for_sync_offset = false;
253 last_timecode_when = 0;
254 last_timecode_valid = false;
258 last_rr_session_dir = session_dirs.begin();
259 refresh_disk_space ();
261 /* default: assume simple stereo speaker configuration */
263 _speakers->setup_default_speakers (2);
267 average_slave_delta = 1800; // !!! why 1800 ????
268 have_first_delta_accumulator = false;
269 delta_accumulator_cnt = 0;
270 _slave_state = Stopped;
272 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
273 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
274 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
275 add_controllable (_solo_cut_control);
277 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
279 /* These are all static "per-class" signals */
281 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
282 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
283 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
284 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
285 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
287 /* stop IO objects from doing stuff until we're ready for them */
289 Delivery::disable_panners ();
290 IO::disable_connecting ();
294 Session::second_stage_init ()
296 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
299 if (load_state (_current_snapshot_name)) {
304 if (_butler->start_thread()) {
308 if (start_midi_thread ()) {
312 setup_midi_machine_control ();
314 // set_state() will call setup_raid_path(), but if it's a new session we need
315 // to call setup_raid_path() here.
318 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
322 setup_raid_path(_path);
325 /* we can't save till after ::when_engine_running() is called,
326 because otherwise we save state with no connections made.
327 therefore, we reset _state_of_the_state because ::set_state()
328 will have cleared it.
330 we also have to include Loading so that any events that get
331 generated between here and the end of ::when_engine_running()
332 will be processed directly rather than queued.
335 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
337 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
338 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
339 setup_click_sounds (0);
340 setup_midi_control ();
342 /* Pay attention ... */
344 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
345 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
348 when_engine_running ();
351 /* handle this one in a different way than all others, so that its clear what happened */
353 catch (AudioEngine::PortRegistrationFailure& err) {
354 error << err.what() << endmsg;
362 BootMessage (_("Reset Remote Controls"));
364 send_full_time_code (0);
365 _engine.transport_locate (0);
367 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
368 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
370 MidiClockTicker::instance().set_session (this);
371 MIDI::Name::MidiPatchManager::instance().set_session (this);
373 /* initial program change will be delivered later; see ::config_changed() */
375 BootMessage (_("Reset Control Protocols"));
377 ControlProtocolManager::instance().set_session (this);
379 _state_of_the_state = Clean;
381 Port::set_connecting_blocked (false);
383 DirtyChanged (); /* EMIT SIGNAL */
385 if (state_was_pending) {
386 save_state (_current_snapshot_name);
387 remove_pending_capture_state ();
388 state_was_pending = false;
391 BootMessage (_("Session loading complete"));
397 Session::raid_path () const
399 SearchPath raid_search_path;
401 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
402 raid_search_path += sys::path((*i).path);
405 return raid_search_path.to_string ();
409 Session::setup_raid_path (string path)
418 session_dirs.clear ();
420 SearchPath search_path(path);
421 SearchPath sound_search_path;
422 SearchPath midi_search_path;
424 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
425 sp.path = (*i).to_string ();
426 sp.blocks = 0; // not needed
427 session_dirs.push_back (sp);
429 SessionDirectory sdir(sp.path);
431 sound_search_path += sdir.sound_path ();
432 midi_search_path += sdir.midi_path ();
435 // reset the round-robin soundfile path thingie
436 last_rr_session_dir = session_dirs.begin();
440 Session::path_is_within_session (const std::string& path)
442 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
443 if (path.find ((*i).path) == 0) {
451 Session::ensure_subdirs ()
455 dir = session_directory().peak_path().to_string();
457 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
458 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
462 dir = session_directory().sound_path().to_string();
464 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
465 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
469 dir = session_directory().sound_stub_path().to_string();
471 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
472 error << string_compose(_("Session: cannot create session stub sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
476 dir = session_directory().midi_path().to_string();
478 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
479 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
483 dir = session_directory().midi_stub_path().to_string();
485 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
486 error << string_compose(_("Session: cannot create session stub midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
490 dir = session_directory().dead_sound_path().to_string();
492 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
493 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
497 dir = session_directory().export_path().to_string();
499 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
500 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
504 dir = analysis_dir ();
506 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
507 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
511 dir = plugins_dir ();
513 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
514 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
521 /** Caller must not hold process lock */
523 Session::create (const string& mix_template, BusProfile* bus_profile)
525 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
526 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
530 if (ensure_subdirs ()) {
534 if (!mix_template.empty()) {
535 std::string in_path = mix_template;
537 ifstream in(in_path.c_str());
540 string out_path = _path;
542 out_path += statefile_suffix;
544 ofstream out(out_path.c_str());
552 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
558 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
565 /* Instantiate metadata */
567 _metadata = new SessionMetadata ();
569 /* set initial start + end point */
571 _state_of_the_state = Clean;
573 /* set up Master Out and Control Out if necessary */
579 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
581 if (bus_profile->master_out_channels) {
582 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
586 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
587 boost_debug_shared_ptr_mark_interesting (rt.get(), "Route");
590 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
591 r->input()->ensure_io (count, false, this);
592 r->output()->ensure_io (count, false, this);
594 r->set_remote_control_id (control_id++);
598 if (Config->get_use_monitor_bus()) {
599 boost::shared_ptr<Route> r (new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO));
603 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
604 boost_debug_shared_ptr_mark_interesting (rt, "Route");
607 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
608 r->input()->ensure_io (count, false, this);
609 r->output()->ensure_io (count, false, this);
611 r->set_remote_control_id (control_id);
617 /* prohibit auto-connect to master, because there isn't one */
618 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
622 add_routes (rl, false);
625 /* this allows the user to override settings with an environment variable.
628 if (no_auto_connect()) {
629 bus_profile->input_ac = AutoConnectOption (0);
630 bus_profile->output_ac = AutoConnectOption (0);
633 Config->set_input_auto_connect (bus_profile->input_ac);
634 Config->set_output_auto_connect (bus_profile->output_ac);
643 Session::maybe_write_autosave()
645 if (dirty() && record_status() != Recording) {
646 save_state("", true);
651 Session::remove_pending_capture_state ()
653 sys::path pending_state_file_path(_session_dir->root_path());
655 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
659 sys::remove (pending_state_file_path);
661 catch(sys::filesystem_error& ex)
663 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
664 pending_state_file_path.to_string(), ex.what()) << endmsg;
668 /** Rename a state file.
669 * @param snapshot_name Snapshot name.
672 Session::rename_state (string old_name, string new_name)
674 if (old_name == _current_snapshot_name || old_name == _name) {
675 /* refuse to rename the current snapshot or the "main" one */
679 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
680 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
682 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
683 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
687 sys::rename (old_xml_path, new_xml_path);
689 catch (const sys::filesystem_error& err)
691 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
692 old_name, new_name, err.what()) << endmsg;
696 /** Remove a state file.
697 * @param snapshot_name Snapshot name.
700 Session::remove_state (string snapshot_name)
702 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
703 // refuse to remove the current snapshot or the "main" one
707 sys::path xml_path(_session_dir->root_path());
709 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
711 if (!create_backup_file (xml_path)) {
712 // don't remove it if a backup can't be made
713 // create_backup_file will log the error.
718 sys::remove (xml_path);
721 #ifdef HAVE_JACK_SESSION
723 Session::jack_session_event (jack_session_event_t * event)
727 struct tm local_time;
730 localtime_r (&n, &local_time);
731 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
733 if (event->type == JackSessionSaveTemplate)
735 if (save_template( timebuf )) {
736 event->flags = JackSessionSaveError;
738 string cmd ("ardour3 -P -U ");
739 cmd += event->client_uuid;
743 event->command_line = strdup (cmd.c_str());
748 if (save_state (timebuf)) {
749 event->flags = JackSessionSaveError;
751 sys::path xml_path (_session_dir->root_path());
752 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
754 string cmd ("ardour3 -P -U ");
755 cmd += event->client_uuid;
757 cmd += xml_path.to_string();
760 event->command_line = strdup (cmd.c_str());
764 jack_session_reply (_engine.jack(), event);
766 if (event->type == JackSessionSaveAndQuit) {
767 Quit (); /* EMIT SIGNAL */
770 jack_session_event_free( event );
775 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
778 sys::path xml_path(_session_dir->root_path());
780 if (!_writable || (_state_of_the_state & CannotSave)) {
784 if (!_engine.connected ()) {
785 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
791 /* tell sources we're saving first, in case they write out to a new file
792 * which should be saved with the state rather than the old one */
793 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
794 i->second->session_saved();
797 tree.set_root (&get_state());
799 if (snapshot_name.empty()) {
800 snapshot_name = _current_snapshot_name;
801 } else if (switch_to_snapshot) {
802 _current_snapshot_name = snapshot_name;
807 /* proper save: use statefile_suffix (.ardour in English) */
809 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
811 /* make a backup copy of the old file */
813 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
814 // create_backup_file will log the error
820 /* pending save: use pending_suffix (.pending in English) */
821 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
824 sys::path tmp_path(_session_dir->root_path());
826 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
828 // cerr << "actually writing state to " << xml_path.to_string() << endl;
830 if (!tree.write (tmp_path.to_string())) {
831 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
832 sys::remove (tmp_path);
837 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
838 error << string_compose (_("could not rename temporary session file %1 to %2"),
839 tmp_path.to_string(), xml_path.to_string()) << endmsg;
840 sys::remove (tmp_path);
847 save_history (snapshot_name);
849 bool was_dirty = dirty();
851 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
854 DirtyChanged (); /* EMIT SIGNAL */
857 StateSaved (snapshot_name); /* EMIT SIGNAL */
864 Session::restore_state (string snapshot_name)
866 if (load_state (snapshot_name) == 0) {
867 set_state (*state_tree->root(), Stateful::loading_state_version);
874 Session::load_state (string snapshot_name)
879 state_was_pending = false;
881 /* check for leftover pending state from a crashed capture attempt */
883 sys::path xmlpath(_session_dir->root_path());
884 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
886 if (sys::exists (xmlpath)) {
888 /* there is pending state from a crashed capture attempt */
890 boost::optional<int> r = AskAboutPendingState();
891 if (r.get_value_or (1)) {
892 state_was_pending = true;
896 if (!state_was_pending) {
897 xmlpath = _session_dir->root_path();
898 xmlpath /= snapshot_name;
901 if (!sys::exists (xmlpath)) {
902 xmlpath = _session_dir->root_path();
903 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
904 if (!sys::exists (xmlpath)) {
905 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
910 state_tree = new XMLTree;
914 /* writable() really reflects the whole folder, but if for any
915 reason the session state file can't be written to, still
919 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
923 if (!state_tree->read (xmlpath.to_string())) {
924 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
930 XMLNode& root (*state_tree->root());
932 if (root.name() != X_("Session")) {
933 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
939 const XMLProperty* prop;
941 if ((prop = root.property ("version")) == 0) {
942 /* no version implies very old version of Ardour */
943 Stateful::loading_state_version = 1000;
949 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
950 Stateful::loading_state_version = (major * 1000) + minor;
953 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
955 sys::path backup_path(_session_dir->root_path());
957 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
959 // only create a backup once
960 if (sys::exists (backup_path)) {
964 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
965 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
970 sys::copy_file (xmlpath, backup_path);
972 catch(sys::filesystem_error& ex)
974 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
975 xmlpath.to_string(), ex.what())
985 Session::load_options (const XMLNode& node)
987 LocaleGuard lg (X_("POSIX"));
988 config.set_variables (node);
999 Session::get_template()
1001 /* if we don't disable rec-enable, diskstreams
1002 will believe they need to store their capture
1003 sources in their state node.
1006 disable_record (false);
1008 return state(false);
1012 Session::state(bool full_state)
1014 XMLNode* node = new XMLNode("Session");
1017 // store libardour version, just in case
1019 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
1020 node->add_property("version", string(buf));
1022 /* store configuration settings */
1026 node->add_property ("name", _name);
1027 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1028 node->add_property ("sample-rate", buf);
1030 if (session_dirs.size() > 1) {
1034 vector<space_and_path>::iterator i = session_dirs.begin();
1035 vector<space_and_path>::iterator next;
1037 ++i; /* skip the first one */
1041 while (i != session_dirs.end()) {
1045 if (next != session_dirs.end()) {
1055 child = node->add_child ("Path");
1056 child->add_content (p);
1060 /* save the ID counter */
1062 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1063 node->add_property ("id-counter", buf);
1065 /* save the event ID counter */
1067 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1068 node->add_property ("event-counter", buf);
1070 /* various options */
1072 node->add_child_nocopy (config.get_variables ());
1074 node->add_child_nocopy (_metadata->get_state());
1076 child = node->add_child ("Sources");
1079 Glib::Mutex::Lock sl (source_lock);
1081 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1083 /* Don't save information about non-destructive file sources that are empty
1084 and unused by any regions.
1087 boost::shared_ptr<FileSource> fs;
1088 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1089 if (!fs->destructive()) {
1090 if (fs->empty() && !fs->used()) {
1096 child->add_child_nocopy (siter->second->get_state());
1100 child = node->add_child ("Regions");
1103 Glib::Mutex::Lock rl (region_lock);
1104 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1105 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1106 boost::shared_ptr<Region> r = i->second;
1107 /* only store regions not attached to playlists */
1108 if (r->playlist() == 0) {
1109 child->add_child_nocopy (r->state ());
1115 node->add_child_nocopy (_locations->get_state());
1117 // for a template, just create a new Locations, populate it
1118 // with the default start and end, and get the state for that.
1119 Locations loc (*this);
1120 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1121 range->set (max_framepos, 0);
1123 node->add_child_nocopy (loc.get_state());
1126 child = node->add_child ("Bundles");
1128 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1129 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1130 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1132 child->add_child_nocopy (b->get_state());
1137 child = node->add_child ("Routes");
1139 boost::shared_ptr<RouteList> r = routes.reader ();
1141 RoutePublicOrderSorter cmp;
1142 RouteList public_order (*r);
1143 public_order.sort (cmp);
1145 /* the sort should have put control outs first */
1148 assert (_monitor_out == public_order.front());
1151 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1152 if (!(*i)->is_hidden()) {
1154 child->add_child_nocopy ((*i)->get_state());
1156 child->add_child_nocopy ((*i)->get_template());
1162 playlists->add_state (node, full_state);
1164 child = node->add_child ("RouteGroups");
1165 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1166 child->add_child_nocopy ((*i)->get_state());
1170 child = node->add_child ("Click");
1171 child->add_child_nocopy (_click_io->state (full_state));
1175 child = node->add_child ("NamedSelections");
1176 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1178 child->add_child_nocopy ((*i)->get_state());
1183 node->add_child_nocopy (_speakers->get_state());
1184 node->add_child_nocopy (_tempo_map->get_state());
1185 node->add_child_nocopy (get_control_protocol_state());
1188 node->add_child_copy (*_extra_xml);
1195 Session::get_control_protocol_state ()
1197 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1198 return cpm.get_state();
1202 Session::set_state (const XMLNode& node, int version)
1206 const XMLProperty* prop;
1209 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1211 if (node.name() != X_("Session")) {
1212 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1216 if ((prop = node.property ("version")) != 0) {
1217 version = atoi (prop->value ()) * 1000;
1220 if ((prop = node.property ("name")) != 0) {
1221 _name = prop->value ();
1224 if ((prop = node.property (X_("sample-rate"))) != 0) {
1226 _nominal_frame_rate = atoi (prop->value());
1228 if (_nominal_frame_rate != _current_frame_rate) {
1229 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1230 if (r.get_value_or (0)) {
1236 setup_raid_path(_session_dir->root_path().to_string());
1238 cleanup_stubfiles ();
1240 if ((prop = node.property (X_("id-counter"))) != 0) {
1242 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1243 ID::init_counter (x);
1245 /* old sessions used a timebased counter, so fake
1246 the startup ID counter based on a standard
1251 ID::init_counter (now);
1254 if ((prop = node.property (X_("event-counter"))) != 0) {
1255 Evoral::init_event_id_counter (atoi (prop->value()));
1258 IO::disable_connecting ();
1260 if ((child = find_named_node (node, "Extra")) != 0) {
1261 _extra_xml = new XMLNode (*child);
1264 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1265 load_options (*child);
1266 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1267 load_options (*child);
1269 error << _("Session: XML state has no options section") << endmsg;
1272 if (version >= 3000) {
1273 if ((child = find_named_node (node, "Metadata")) == 0) {
1274 warning << _("Session: XML state has no metadata section") << endmsg;
1275 } else if (_metadata->set_state (*child, version)) {
1280 if ((child = find_named_node (node, "Locations")) == 0) {
1281 error << _("Session: XML state has no locations section") << endmsg;
1283 } else if (_locations->set_state (*child, version)) {
1287 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1288 _speakers->set_state (*child, version);
1293 if ((location = _locations->auto_loop_location()) != 0) {
1294 set_auto_loop_location (location);
1297 if ((location = _locations->auto_punch_location()) != 0) {
1298 set_auto_punch_location (location);
1301 if ((location = _locations->session_range_location()) != 0) {
1302 delete _session_range_location;
1303 _session_range_location = location;
1306 if (_session_range_location) {
1307 AudioFileSource::set_header_position_offset (_session_range_location->start());
1310 if ((child = find_named_node (node, "Sources")) == 0) {
1311 error << _("Session: XML state has no sources section") << endmsg;
1313 } else if (load_sources (*child)) {
1317 if ((child = find_named_node (node, "TempoMap")) == 0) {
1318 error << _("Session: XML state has no Tempo Map section") << endmsg;
1320 } else if (_tempo_map->set_state (*child, version)) {
1324 if ((child = find_named_node (node, "Regions")) == 0) {
1325 error << _("Session: XML state has no Regions section") << endmsg;
1327 } else if (load_regions (*child)) {
1331 if ((child = find_named_node (node, "Playlists")) == 0) {
1332 error << _("Session: XML state has no playlists section") << endmsg;
1334 } else if (playlists->load (*this, *child)) {
1338 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1340 } else if (playlists->load_unused (*this, *child)) {
1344 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1345 if (load_named_selections (*child)) {
1350 if (version >= 3000) {
1351 if ((child = find_named_node (node, "Bundles")) == 0) {
1352 warning << _("Session: XML state has no bundles section") << endmsg;
1355 /* We can't load Bundles yet as they need to be able
1356 to convert from port names to Port objects, which can't happen until
1358 _bundle_xml_node = new XMLNode (*child);
1362 if (version < 3000) {
1363 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1364 error << _("Session: XML state has no diskstreams section") << endmsg;
1366 } else if (load_diskstreams_2X (*child, version)) {
1371 if ((child = find_named_node (node, "Routes")) == 0) {
1372 error << _("Session: XML state has no routes section") << endmsg;
1374 } else if (load_routes (*child, version)) {
1378 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1379 _diskstreams_2X.clear ();
1381 if (version >= 3000) {
1383 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1384 error << _("Session: XML state has no route groups section") << endmsg;
1386 } else if (load_route_groups (*child, version)) {
1390 } else if (version < 3000) {
1392 if ((child = find_named_node (node, "EditGroups")) == 0) {
1393 error << _("Session: XML state has no edit groups section") << endmsg;
1395 } else if (load_route_groups (*child, version)) {
1399 if ((child = find_named_node (node, "MixGroups")) == 0) {
1400 error << _("Session: XML state has no mix groups section") << endmsg;
1402 } else if (load_route_groups (*child, version)) {
1407 if ((child = find_named_node (node, "Click")) == 0) {
1408 warning << _("Session: XML state has no click section") << endmsg;
1409 } else if (_click_io) {
1410 _click_io->set_state (*child, version);
1413 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1414 ControlProtocolManager::instance().set_protocol_states (*child);
1417 /* here beginneth the second phase ... */
1419 StateReady (); /* EMIT SIGNAL */
1428 Session::load_routes (const XMLNode& node, int version)
1431 XMLNodeConstIterator niter;
1432 RouteList new_routes;
1434 nlist = node.children();
1438 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1440 boost::shared_ptr<Route> route;
1441 if (version < 3000) {
1442 route = XMLRouteFactory_2X (**niter, version);
1444 route = XMLRouteFactory (**niter, version);
1448 error << _("Session: cannot create Route from XML description.") << endmsg;
1452 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1454 new_routes.push_back (route);
1457 add_routes (new_routes, false);
1462 boost::shared_ptr<Route>
1463 Session::XMLRouteFactory (const XMLNode& node, int version)
1465 boost::shared_ptr<Route> ret;
1467 if (node.name() != "Route") {
1471 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1473 DataType type = DataType::AUDIO;
1474 const XMLProperty* prop = node.property("default-type");
1477 type = DataType (prop->value());
1480 assert (type != DataType::NIL);
1484 boost::shared_ptr<Track> track;
1486 if (type == DataType::AUDIO) {
1487 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1489 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1492 if (track->init()) {
1496 if (track->set_state (node, version)) {
1500 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1501 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1506 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1508 if (r->init () == 0 && r->set_state (node, version) == 0) {
1509 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1510 boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1519 boost::shared_ptr<Route>
1520 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1522 boost::shared_ptr<Route> ret;
1524 if (node.name() != "Route") {
1528 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1530 ds_prop = node.property (X_("diskstream"));
1533 DataType type = DataType::AUDIO;
1534 const XMLProperty* prop = node.property("default-type");
1537 type = DataType (prop->value());
1540 assert (type != DataType::NIL);
1544 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1545 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1549 if (i == _diskstreams_2X.end()) {
1550 error << _("Could not find diskstream for route") << endmsg;
1551 return boost::shared_ptr<Route> ();
1554 boost::shared_ptr<Track> track;
1556 if (type == DataType::AUDIO) {
1557 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1559 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1562 if (track->init()) {
1566 if (track->set_state (node, version)) {
1570 track->set_diskstream (*i);
1572 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1573 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1578 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1580 if (r->init () == 0 && r->set_state (node, version) == 0) {
1581 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1582 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1592 Session::load_regions (const XMLNode& node)
1595 XMLNodeConstIterator niter;
1596 boost::shared_ptr<Region> region;
1598 nlist = node.children();
1602 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1603 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1604 error << _("Session: cannot create Region from XML description.");
1605 const XMLProperty *name = (**niter).property("name");
1608 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1618 boost::shared_ptr<Region>
1619 Session::XMLRegionFactory (const XMLNode& node, bool full)
1621 const XMLProperty* type = node.property("type");
1625 if (!type || type->value() == "audio") {
1626 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1627 } else if (type->value() == "midi") {
1628 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1631 } catch (failed_constructor& err) {
1632 return boost::shared_ptr<Region> ();
1635 return boost::shared_ptr<Region> ();
1638 boost::shared_ptr<AudioRegion>
1639 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1641 const XMLProperty* prop;
1642 boost::shared_ptr<Source> source;
1643 boost::shared_ptr<AudioSource> as;
1645 SourceList master_sources;
1646 uint32_t nchans = 1;
1649 if (node.name() != X_("Region")) {
1650 return boost::shared_ptr<AudioRegion>();
1653 if ((prop = node.property (X_("channels"))) != 0) {
1654 nchans = atoi (prop->value().c_str());
1657 if ((prop = node.property ("name")) == 0) {
1658 cerr << "no name for this region\n";
1662 if ((prop = node.property (X_("source-0"))) == 0) {
1663 if ((prop = node.property ("source")) == 0) {
1664 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1665 return boost::shared_ptr<AudioRegion>();
1669 PBD::ID s_id (prop->value());
1671 if ((source = source_by_id (s_id)) == 0) {
1672 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1673 return boost::shared_ptr<AudioRegion>();
1676 as = boost::dynamic_pointer_cast<AudioSource>(source);
1678 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1679 return boost::shared_ptr<AudioRegion>();
1682 sources.push_back (as);
1684 /* pickup other channels */
1686 for (uint32_t n=1; n < nchans; ++n) {
1687 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1688 if ((prop = node.property (buf)) != 0) {
1690 PBD::ID id2 (prop->value());
1692 if ((source = source_by_id (id2)) == 0) {
1693 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1694 return boost::shared_ptr<AudioRegion>();
1697 as = boost::dynamic_pointer_cast<AudioSource>(source);
1699 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1700 return boost::shared_ptr<AudioRegion>();
1702 sources.push_back (as);
1706 for (uint32_t n = 0; n < nchans; ++n) {
1707 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1708 if ((prop = node.property (buf)) != 0) {
1710 PBD::ID id2 (prop->value());
1712 if ((source = source_by_id (id2)) == 0) {
1713 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1714 return boost::shared_ptr<AudioRegion>();
1717 as = boost::dynamic_pointer_cast<AudioSource>(source);
1719 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1720 return boost::shared_ptr<AudioRegion>();
1722 master_sources.push_back (as);
1727 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1729 /* a final detail: this is the one and only place that we know how long missing files are */
1731 if (region->whole_file()) {
1732 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1733 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1735 sfp->set_length (region->length());
1740 if (!master_sources.empty()) {
1741 if (master_sources.size() != nchans) {
1742 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1744 region->set_master_sources (master_sources);
1752 catch (failed_constructor& err) {
1753 return boost::shared_ptr<AudioRegion>();
1757 boost::shared_ptr<MidiRegion>
1758 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1760 const XMLProperty* prop;
1761 boost::shared_ptr<Source> source;
1762 boost::shared_ptr<MidiSource> ms;
1765 if (node.name() != X_("Region")) {
1766 return boost::shared_ptr<MidiRegion>();
1769 if ((prop = node.property ("name")) == 0) {
1770 cerr << "no name for this region\n";
1774 if ((prop = node.property (X_("source-0"))) == 0) {
1775 if ((prop = node.property ("source")) == 0) {
1776 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1777 return boost::shared_ptr<MidiRegion>();
1781 PBD::ID s_id (prop->value());
1783 if ((source = source_by_id (s_id)) == 0) {
1784 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1785 return boost::shared_ptr<MidiRegion>();
1788 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1790 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1791 return boost::shared_ptr<MidiRegion>();
1794 sources.push_back (ms);
1797 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1798 /* a final detail: this is the one and only place that we know how long missing files are */
1800 if (region->whole_file()) {
1801 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1802 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1804 sfp->set_length (region->length());
1812 catch (failed_constructor& err) {
1813 return boost::shared_ptr<MidiRegion>();
1818 Session::get_sources_as_xml ()
1821 XMLNode* node = new XMLNode (X_("Sources"));
1822 Glib::Mutex::Lock lm (source_lock);
1824 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1825 node->add_child_nocopy (i->second->get_state());
1832 Session::path_from_region_name (DataType type, string name, string identifier)
1834 char buf[PATH_MAX+1];
1836 SessionDirectory sdir(get_best_session_directory_for_new_source());
1837 sys::path source_dir = ((type == DataType::AUDIO)
1838 ? sdir.sound_path() : sdir.midi_path());
1840 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1842 for (n = 0; n < 999999; ++n) {
1843 if (identifier.length()) {
1844 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1845 identifier.c_str(), n, ext.c_str());
1847 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1851 sys::path source_path = source_dir / buf;
1853 if (!sys::exists (source_path)) {
1854 return source_path.to_string();
1858 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1867 Session::load_sources (const XMLNode& node)
1870 XMLNodeConstIterator niter;
1871 boost::shared_ptr<Source> source;
1873 nlist = node.children();
1877 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1880 if ((source = XMLSourceFactory (**niter)) == 0) {
1881 error << _("Session: cannot create Source from XML description.") << endmsg;
1884 } catch (MissingSource& err) {
1888 if (!no_questions_about_missing_files) {
1889 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1894 switch (user_choice) {
1896 /* user added a new search location, so try again */
1901 /* user asked to quit the entire session load
1906 no_questions_about_missing_files = true;
1910 no_questions_about_missing_files = true;
1915 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1916 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1925 boost::shared_ptr<Source>
1926 Session::XMLSourceFactory (const XMLNode& node)
1928 if (node.name() != "Source") {
1929 return boost::shared_ptr<Source>();
1933 /* note: do peak building in another thread when loading session state */
1934 return SourceFactory::create (*this, node, true);
1937 catch (failed_constructor& err) {
1938 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1939 return boost::shared_ptr<Source>();
1944 Session::save_template (string template_name)
1948 if (_state_of_the_state & CannotSave) {
1952 sys::path user_template_dir(user_template_directory());
1956 sys::create_directories (user_template_dir);
1958 catch(sys::filesystem_error& ex)
1960 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1961 user_template_dir.to_string(), ex.what()) << endmsg;
1965 tree.set_root (&get_template());
1967 sys::path template_file_path(user_template_dir);
1968 template_file_path /= template_name + template_suffix;
1970 if (sys::exists (template_file_path))
1972 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1973 template_file_path.to_string()) << endmsg;
1977 if (!tree.write (template_file_path.to_string())) {
1978 error << _("template not saved") << endmsg;
1986 Session::rename_template (string old_name, string new_name)
1988 sys::path old_path (user_template_directory());
1989 old_path /= old_name + template_suffix;
1991 sys::path new_path(user_template_directory());
1992 new_path /= new_name + template_suffix;
1994 if (sys::exists (new_path)) {
1995 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1996 new_path.to_string()) << endmsg;
2001 sys::rename (old_path, new_path);
2009 Session::delete_template (string name)
2011 sys::path path = user_template_directory();
2012 path /= name + template_suffix;
2023 Session::refresh_disk_space ()
2026 struct statfs statfsbuf;
2027 vector<space_and_path>::iterator i;
2028 Glib::Mutex::Lock lm (space_lock);
2031 /* get freespace on every FS that is part of the session path */
2033 _total_free_4k_blocks = 0;
2035 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2036 statfs ((*i).path.c_str(), &statfsbuf);
2038 scale = statfsbuf.f_bsize/4096.0;
2040 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2041 _total_free_4k_blocks += (*i).blocks;
2047 Session::get_best_session_directory_for_new_source ()
2049 vector<space_and_path>::iterator i;
2050 string result = _session_dir->root_path().to_string();
2052 /* handle common case without system calls */
2054 if (session_dirs.size() == 1) {
2058 /* OK, here's the algorithm we're following here:
2060 We want to select which directory to use for
2061 the next file source to be created. Ideally,
2062 we'd like to use a round-robin process so as to
2063 get maximum performance benefits from splitting
2064 the files across multiple disks.
2066 However, in situations without much diskspace, an
2067 RR approach may end up filling up a filesystem
2068 with new files while others still have space.
2069 Its therefore important to pay some attention to
2070 the freespace in the filesystem holding each
2071 directory as well. However, if we did that by
2072 itself, we'd keep creating new files in the file
2073 system with the most space until it was as full
2074 as all others, thus negating any performance
2075 benefits of this RAID-1 like approach.
2077 So, we use a user-configurable space threshold. If
2078 there are at least 2 filesystems with more than this
2079 much space available, we use RR selection between them.
2080 If not, then we pick the filesystem with the most space.
2082 This gets a good balance between the two
2086 refresh_disk_space ();
2088 int free_enough = 0;
2090 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2091 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2096 if (free_enough >= 2) {
2097 /* use RR selection process, ensuring that the one
2101 i = last_rr_session_dir;
2104 if (++i == session_dirs.end()) {
2105 i = session_dirs.begin();
2108 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2109 if (create_session_directory ((*i).path)) {
2111 last_rr_session_dir = i;
2116 } while (i != last_rr_session_dir);
2120 /* pick FS with the most freespace (and that
2121 seems to actually work ...)
2124 vector<space_and_path> sorted;
2125 space_and_path_ascending_cmp cmp;
2127 sorted = session_dirs;
2128 sort (sorted.begin(), sorted.end(), cmp);
2130 for (i = sorted.begin(); i != sorted.end(); ++i) {
2131 if (create_session_directory ((*i).path)) {
2133 last_rr_session_dir = i;
2143 Session::load_named_selections (const XMLNode& node)
2146 XMLNodeConstIterator niter;
2149 nlist = node.children();
2153 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2155 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2156 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2164 Session::XMLNamedSelectionFactory (const XMLNode& node)
2167 return new NamedSelection (*this, node);
2170 catch (failed_constructor& err) {
2176 Session::automation_dir () const
2178 return Glib::build_filename (_path, "automation");
2182 Session::analysis_dir () const
2184 return Glib::build_filename (_path, "analysis");
2188 Session::plugins_dir () const
2190 return Glib::build_filename (_path, "plugins");
2194 Session::load_bundles (XMLNode const & node)
2196 XMLNodeList nlist = node.children();
2197 XMLNodeConstIterator niter;
2201 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2202 if ((*niter)->name() == "InputBundle") {
2203 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2204 } else if ((*niter)->name() == "OutputBundle") {
2205 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2207 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2216 Session::load_route_groups (const XMLNode& node, int version)
2218 XMLNodeList nlist = node.children();
2219 XMLNodeConstIterator niter;
2223 if (version >= 3000) {
2225 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2226 if ((*niter)->name() == "RouteGroup") {
2227 RouteGroup* rg = new RouteGroup (*this, "");
2228 add_route_group (rg);
2229 rg->set_state (**niter, version);
2233 } else if (version < 3000) {
2235 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2236 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2237 RouteGroup* rg = new RouteGroup (*this, "");
2238 add_route_group (rg);
2239 rg->set_state (**niter, version);
2248 Session::auto_save()
2250 save_state (_current_snapshot_name);
2254 state_file_filter (const string &str, void */*arg*/)
2256 return (str.length() > strlen(statefile_suffix) &&
2257 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2261 bool operator()(const string* a, const string* b) {
2267 remove_end(string* state)
2269 string statename(*state);
2271 string::size_type start,end;
2272 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2273 statename = statename.substr (start+1);
2276 if ((end = statename.rfind(".ardour")) == string::npos) {
2277 end = statename.length();
2280 return new string(statename.substr (0, end));
2284 Session::possible_states (string path)
2286 PathScanner scanner;
2287 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2289 transform(states->begin(), states->end(), states->begin(), remove_end);
2292 sort (states->begin(), states->end(), cmp);
2298 Session::possible_states () const
2300 return possible_states(_path);
2304 Session::add_route_group (RouteGroup* g)
2306 _route_groups.push_back (g);
2307 route_group_added (g); /* EMIT SIGNAL */
2309 g->MembershipChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2310 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2316 Session::remove_route_group (RouteGroup& rg)
2318 list<RouteGroup*>::iterator i;
2320 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2321 _route_groups.erase (i);
2324 route_group_removed (); /* EMIT SIGNAL */
2330 Session::route_group_by_name (string name)
2332 list<RouteGroup *>::iterator i;
2334 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2335 if ((*i)->name() == name) {
2343 Session::all_route_group() const
2345 return *_all_route_group;
2349 Session::add_commands (vector<Command*> const & cmds)
2351 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2357 Session::begin_reversible_command (const string& name)
2359 begin_reversible_command (g_quark_from_string (name.c_str ()));
2362 /** Begin a reversible command using a GQuark to identify it.
2363 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2364 * but there must be as many begin...()s as there are commit...()s.
2367 Session::begin_reversible_command (GQuark q)
2369 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2370 to hold all the commands that are committed. This keeps the order of
2371 commands correct in the history.
2374 if (_current_trans == 0) {
2375 /* start a new transaction */
2376 assert (_current_trans_quarks.empty ());
2377 _current_trans = new UndoTransaction();
2378 _current_trans->set_name (g_quark_to_string (q));
2381 _current_trans_quarks.push_front (q);
2385 Session::commit_reversible_command (Command *cmd)
2387 assert (_current_trans);
2388 assert (!_current_trans_quarks.empty ());
2393 _current_trans->add_command (cmd);
2396 _current_trans_quarks.pop_front ();
2398 if (!_current_trans_quarks.empty ()) {
2399 /* the transaction we're committing is not the top-level one */
2403 if (_current_trans->empty()) {
2404 /* no commands were added to the transaction, so just get rid of it */
2405 delete _current_trans;
2410 gettimeofday (&now, 0);
2411 _current_trans->set_timestamp (now);
2413 _history.add (_current_trans);
2418 accept_all_non_peak_files (const string& path, void */*arg*/)
2420 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2424 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2428 accept_all_state_files (const string& path, void */*arg*/)
2430 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2434 Session::find_all_sources (string path, set<string>& result)
2439 if (!tree.read (path)) {
2443 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2448 XMLNodeConstIterator niter;
2450 nlist = node->children();
2454 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2458 if ((prop = (*niter)->property (X_("type"))) == 0) {
2462 DataType type (prop->value());
2464 if ((prop = (*niter)->property (X_("name"))) == 0) {
2468 if (Glib::path_is_absolute (prop->value())) {
2469 /* external file, ignore */
2477 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2478 result.insert (found_path);
2486 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2488 PathScanner scanner;
2489 vector<string*>* state_files;
2491 string this_snapshot_path;
2497 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2498 ripped = ripped.substr (0, ripped.length() - 1);
2501 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2503 if (state_files == 0) {
2508 this_snapshot_path = _path;
2509 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2510 this_snapshot_path += statefile_suffix;
2512 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2514 if (exclude_this_snapshot && **i == this_snapshot_path) {
2518 if (find_all_sources (**i, result) < 0) {
2526 struct RegionCounter {
2527 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2528 AudioSourceList::iterator iter;
2529 boost::shared_ptr<Region> region;
2532 RegionCounter() : count (0) {}
2536 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2538 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2539 return r.get_value_or (1);
2543 Session::cleanup_regions ()
2545 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2547 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2549 boost::shared_ptr<AudioRegion> audio_region = boost::dynamic_pointer_cast<AudioRegion>( i->second);
2551 if (!audio_region) {
2555 uint32_t used = playlists->region_use_count (audio_region);
2557 if (used == 0 && !audio_region->automatic()) {
2558 RegionFactory::map_remove(i->second);
2562 /* dump the history list */
2569 Session::cleanup_sources (CleanupReport& rep)
2571 // FIXME: needs adaptation to midi
2573 vector<boost::shared_ptr<Source> > dead_sources;
2574 PathScanner scanner;
2576 vector<space_and_path>::iterator i;
2577 vector<space_and_path>::iterator nexti;
2578 vector<string*>* soundfiles;
2579 vector<string> unused;
2580 set<string> all_sources;
2585 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2587 /* step 1: consider deleting all unused playlists */
2589 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2594 /* step 2: find all un-used sources */
2599 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2601 SourceMap::iterator tmp;
2606 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2610 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2611 dead_sources.push_back (i->second);
2612 i->second->drop_references ();
2618 /* build a list of all the possible sound directories for the session */
2620 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2625 SessionDirectory sdir ((*i).path);
2626 sound_path += sdir.sound_path().to_string();
2628 if (nexti != session_dirs.end()) {
2635 /* now do the same thing for the files that ended up in the sounds dir(s)
2636 but are not referenced as sources in any snapshot.
2639 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2641 if (soundfiles == 0) {
2645 /* find all sources, but don't use this snapshot because the
2646 state file on disk still references sources we may have already
2650 find_all_sources_across_snapshots (all_sources, true);
2652 /* add our current source list
2655 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2656 boost::shared_ptr<FileSource> fs;
2658 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2659 all_sources.insert (fs->path());
2663 char tmppath1[PATH_MAX+1];
2664 char tmppath2[PATH_MAX+1];
2666 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2671 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2673 if (realpath(spath.c_str(), tmppath1) == 0) {
2674 error << string_compose (_("Cannot expand path %1 (%2)"),
2675 spath, strerror (errno)) << endmsg;
2679 if (realpath((*i).c_str(), tmppath2) == 0) {
2680 error << string_compose (_("Cannot expand path %1 (%2)"),
2681 (*i), strerror (errno)) << endmsg;
2685 if (strcmp(tmppath1, tmppath2) == 0) {
2692 unused.push_back (spath);
2696 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2698 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2699 struct stat statbuf;
2701 rep.paths.push_back (*x);
2702 if (stat ((*x).c_str(), &statbuf) == 0) {
2703 rep.space += statbuf.st_size;
2708 /* don't move the file across filesystems, just
2709 stick it in the `dead_sound_dir_name' directory
2710 on whichever filesystem it was already on.
2713 if ((*x).find ("/sounds/") != string::npos) {
2715 /* old school, go up 1 level */
2717 newpath = Glib::path_get_dirname (*x); // "sounds"
2718 newpath = Glib::path_get_dirname (newpath); // "session-name"
2722 /* new school, go up 4 levels */
2724 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2725 newpath = Glib::path_get_dirname (newpath); // "session-name"
2726 newpath = Glib::path_get_dirname (newpath); // "interchange"
2727 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2730 newpath = Glib::build_filename (newpath, dead_sound_dir_name);
2732 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2733 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2737 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2739 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2741 /* the new path already exists, try versioning */
2743 char buf[PATH_MAX+1];
2747 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2750 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2751 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2755 if (version == 999) {
2756 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2760 newpath = newpath_v;
2765 /* it doesn't exist, or we can't read it or something */
2769 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2770 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2771 (*x), newpath, strerror (errno))
2776 /* see if there an easy to find peakfile for this file, and remove it.
2779 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2780 peakpath += peakfile_suffix;
2782 if (access (peakpath.c_str(), W_OK) == 0) {
2783 if (::unlink (peakpath.c_str()) != 0) {
2784 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2785 peakpath, _path, strerror (errno))
2787 /* try to back out */
2788 rename (newpath.c_str(), _path.c_str());
2796 /* dump the history list */
2800 /* save state so we don't end up a session file
2801 referring to non-existent sources.
2807 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2813 Session::cleanup_trash_sources (CleanupReport& rep)
2815 // FIXME: needs adaptation for MIDI
2817 vector<space_and_path>::iterator i;
2818 string dead_sound_dir;
2823 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2825 dead_sound_dir = (*i).path;
2826 dead_sound_dir += dead_sound_dir_name;
2828 clear_directory (dead_sound_dir, &rep.space, &rep.paths);
2835 Session::cleanup_stubfiles ()
2837 vector<space_and_path>::iterator i;
2839 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2842 string lname = legalize_for_path (_name);
2846 /* XXX this is a hack caused by semantic conflicts
2847 between space_and_path and the SessionDirectory concept.
2850 v.push_back ((*i).path);
2851 v.push_back ("interchange");
2852 v.push_back (lname);
2853 v.push_back ("audiofiles");
2854 v.push_back (stub_dir_name);
2856 dir = Glib::build_filename (v);
2858 clear_directory (dir);
2861 v.push_back ((*i).path);
2862 v.push_back ("interchange");
2863 v.push_back (lname);
2864 v.push_back ("midifiles");
2865 v.push_back (stub_dir_name);
2867 dir = Glib::build_filename (v);
2869 clear_directory (dir);
2874 Session::set_dirty ()
2876 bool was_dirty = dirty();
2878 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2882 DirtyChanged(); /* EMIT SIGNAL */
2888 Session::set_clean ()
2890 bool was_dirty = dirty();
2892 _state_of_the_state = Clean;
2896 DirtyChanged(); /* EMIT SIGNAL */
2901 Session::set_deletion_in_progress ()
2903 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2907 Session::clear_deletion_in_progress ()
2909 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2913 Session::add_controllable (boost::shared_ptr<Controllable> c)
2915 /* this adds a controllable to the list managed by the Session.
2916 this is a subset of those managed by the Controllable class
2917 itself, and represents the only ones whose state will be saved
2918 as part of the session.
2921 Glib::Mutex::Lock lm (controllables_lock);
2922 controllables.insert (c);
2925 struct null_deleter { void operator()(void const *) const {} };
2928 Session::remove_controllable (Controllable* c)
2930 if (_state_of_the_state | Deletion) {
2934 Glib::Mutex::Lock lm (controllables_lock);
2936 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2938 if (x != controllables.end()) {
2939 controllables.erase (x);
2943 boost::shared_ptr<Controllable>
2944 Session::controllable_by_id (const PBD::ID& id)
2946 Glib::Mutex::Lock lm (controllables_lock);
2948 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2949 if ((*i)->id() == id) {
2954 return boost::shared_ptr<Controllable>();
2957 boost::shared_ptr<Controllable>
2958 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2960 boost::shared_ptr<Controllable> c;
2961 boost::shared_ptr<Route> r;
2963 switch (desc.top_level_type()) {
2964 case ControllableDescriptor::NamedRoute:
2966 std::string str = desc.top_level_name();
2967 if (str == "master") {
2969 } else if (str == "control" || str == "listen") {
2972 r = route_by_name (desc.top_level_name());
2977 case ControllableDescriptor::RemoteControlID:
2978 r = route_by_remote_id (desc.rid());
2986 switch (desc.subtype()) {
2987 case ControllableDescriptor::Gain:
2988 c = r->gain_control ();
2991 case ControllableDescriptor::Solo:
2992 c = r->solo_control();
2995 case ControllableDescriptor::Mute:
2996 c = r->mute_control();
2999 case ControllableDescriptor::Recenable:
3001 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3004 c = t->rec_enable_control ();
3009 case ControllableDescriptor::PanDirection:
3011 c = r->pannable()->pan_azimuth_control;
3015 case ControllableDescriptor::PanWidth:
3017 c = r->pannable()->pan_width_control;
3021 case ControllableDescriptor::PanElevation:
3023 c = r->pannable()->pan_elevation_control;
3027 case ControllableDescriptor::Balance:
3028 /* XXX simple pan control */
3031 case ControllableDescriptor::PluginParameter:
3033 uint32_t plugin = desc.target (0);
3034 uint32_t parameter_index = desc.target (1);
3036 /* revert to zero based counting */
3042 if (parameter_index > 0) {
3046 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3049 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3050 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3055 case ControllableDescriptor::SendGain:
3057 uint32_t send = desc.target (0);
3059 /* revert to zero-based counting */
3065 boost::shared_ptr<Processor> p = r->nth_send (send);
3068 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3069 boost::shared_ptr<Amp> a = s->amp();
3072 c = s->amp()->gain_control();
3079 /* relax and return a null pointer */
3087 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3090 Stateful::add_instant_xml (node, _path);
3093 if (write_to_config) {
3094 Config->add_instant_xml (node);
3099 Session::instant_xml (const string& node_name)
3101 return Stateful::instant_xml (node_name, _path);
3105 Session::save_history (string snapshot_name)
3113 if (snapshot_name.empty()) {
3114 snapshot_name = _current_snapshot_name;
3117 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3118 const string backup_filename = history_filename + backup_suffix;
3119 const sys::path xml_path = _session_dir->root_path() / history_filename;
3120 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3122 if (sys::exists (xml_path)) {
3125 sys::rename (xml_path, backup_path);
3127 catch (const sys::filesystem_error& err)
3129 error << _("could not backup old history file, current history not saved") << endmsg;
3134 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3138 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3140 if (!tree.write (xml_path.to_string()))
3142 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3146 sys::remove (xml_path);
3147 sys::rename (backup_path, xml_path);
3149 catch (const sys::filesystem_error& err)
3151 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3152 backup_path.to_string(), err.what()) << endmsg;
3162 Session::restore_history (string snapshot_name)
3166 if (snapshot_name.empty()) {
3167 snapshot_name = _current_snapshot_name;
3170 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3171 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3173 info << "Loading history from " << xml_path.to_string() << endmsg;
3175 if (!sys::exists (xml_path)) {
3176 info << string_compose (_("%1: no history file \"%2\" for this session."),
3177 _name, xml_path.to_string()) << endmsg;
3181 if (!tree.read (xml_path.to_string())) {
3182 error << string_compose (_("Could not understand session history file \"%1\""),
3183 xml_path.to_string()) << endmsg;
3190 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3193 UndoTransaction* ut = new UndoTransaction ();
3196 ut->set_name(t->property("name")->value());
3197 stringstream ss(t->property("tv-sec")->value());
3199 ss.str(t->property("tv-usec")->value());
3201 ut->set_timestamp(tv);
3203 for (XMLNodeConstIterator child_it = t->children().begin();
3204 child_it != t->children().end(); child_it++)
3206 XMLNode *n = *child_it;
3209 if (n->name() == "MementoCommand" ||
3210 n->name() == "MementoUndoCommand" ||
3211 n->name() == "MementoRedoCommand") {
3213 if ((c = memento_command_factory(n))) {
3217 } else if (n->name() == "NoteDiffCommand") {
3218 PBD::ID id (n->property("midi-source")->value());
3219 boost::shared_ptr<MidiSource> midi_source =
3220 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3222 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3224 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3227 } else if (n->name() == "SysExDiffCommand") {
3229 PBD::ID id (n->property("midi-source")->value());
3230 boost::shared_ptr<MidiSource> midi_source =
3231 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3233 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3235 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3238 } else if (n->name() == "PatchChangeDiffCommand") {
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::PatchChangeDiffCommand (midi_source->model(), *n));
3246 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3249 } else if (n->name() == "StatefulDiffCommand") {
3250 if ((c = stateful_diff_command_factory (n))) {
3251 ut->add_command (c);
3254 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3265 Session::config_changed (std::string p, bool ours)
3271 if (p == "seamless-loop") {
3273 } else if (p == "rf-speed") {
3275 } else if (p == "auto-loop") {
3277 } else if (p == "auto-input") {
3279 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3280 /* auto-input only makes a difference if we're rolling */
3282 boost::shared_ptr<RouteList> rl = routes.reader ();
3283 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3284 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3285 if (tr && tr->record_enabled ()) {
3286 tr->monitor_input (!config.get_auto_input());
3291 } else if (p == "punch-in") {
3295 if ((location = _locations->auto_punch_location()) != 0) {
3297 if (config.get_punch_in ()) {
3298 replace_event (SessionEvent::PunchIn, location->start());
3300 remove_event (location->start(), SessionEvent::PunchIn);
3304 } else if (p == "punch-out") {
3308 if ((location = _locations->auto_punch_location()) != 0) {
3310 if (config.get_punch_out()) {
3311 replace_event (SessionEvent::PunchOut, location->end());
3313 clear_events (SessionEvent::PunchOut);
3317 } else if (p == "edit-mode") {
3319 Glib::Mutex::Lock lm (playlists->lock);
3321 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3322 (*i)->set_edit_mode (Config->get_edit_mode ());
3325 } else if (p == "use-video-sync") {
3327 waiting_for_sync_offset = config.get_use_video_sync();
3329 } else if (p == "mmc-control") {
3331 //poke_midi_thread ();
3333 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3335 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3337 } else if (p == "mmc-send-id") {
3339 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3341 } else if (p == "midi-control") {
3343 //poke_midi_thread ();
3345 } else if (p == "raid-path") {
3347 setup_raid_path (config.get_raid_path());
3349 } else if (p == "timecode-format") {
3353 } else if (p == "video-pullup") {
3357 } else if (p == "seamless-loop") {
3359 if (play_loop && transport_rolling()) {
3360 // to reset diskstreams etc
3361 request_play_loop (true);
3364 } else if (p == "rf-speed") {
3366 cumulative_rf_motion = 0;
3369 } else if (p == "click-sound") {
3371 setup_click_sounds (1);
3373 } else if (p == "click-emphasis-sound") {
3375 setup_click_sounds (-1);
3377 } else if (p == "clicking") {
3379 if (Config->get_clicking()) {
3380 if (_click_io && click_data) { // don't require emphasis data
3387 } else if (p == "send-mtc") {
3389 if (Config->get_send_mtc ()) {
3390 /* mark us ready to send */
3391 next_quarter_frame_to_send = 0;
3394 } else if (p == "send-mmc") {
3396 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3398 } else if (p == "midi-feedback") {
3400 session_midi_feedback = Config->get_midi_feedback();
3402 } else if (p == "jack-time-master") {
3404 engine().reset_timebase ();
3406 } else if (p == "native-file-header-format") {
3408 if (!first_file_header_format_reset) {
3409 reset_native_file_format ();
3412 first_file_header_format_reset = false;
3414 } else if (p == "native-file-data-format") {
3416 if (!first_file_data_format_reset) {
3417 reset_native_file_format ();
3420 first_file_data_format_reset = false;
3422 } else if (p == "external-sync") {
3423 if (!config.get_external_sync()) {
3424 drop_sync_source ();
3426 switch_to_sync_source (config.get_sync_source());
3428 } else if (p == "remote-model") {
3429 set_remote_control_ids ();
3430 } else if (p == "denormal-model") {
3432 } else if (p == "history-depth") {
3433 set_history_depth (Config->get_history_depth());
3434 } else if (p == "sync-all-route-ordering") {
3435 sync_order_keys ("session");
3436 } else if (p == "initial-program-change") {
3438 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3441 buf[0] = MIDI::program; // channel zero by default
3442 buf[1] = (Config->get_initial_program_change() & 0x7f);
3444 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3446 } else if (p == "solo-mute-override") {
3447 // catch_up_on_solo_mute_override ();
3448 } else if (p == "listen-position" || p == "pfl-position") {
3449 listen_position_changed ();
3450 } else if (p == "solo-control-is-listen-control") {
3451 solo_control_mode_changed ();
3452 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3453 last_timecode_valid = false;
3460 Session::set_history_depth (uint32_t d)
3462 _history.set_depth (d);
3466 Session::load_diskstreams_2X (XMLNode const & node, int)
3469 XMLNodeConstIterator citer;
3471 clist = node.children();
3473 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3476 /* diskstreams added automatically by DiskstreamCreated handler */
3477 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3478 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3479 _diskstreams_2X.push_back (dsp);
3481 error << _("Session: unknown diskstream type in XML") << endmsg;
3485 catch (failed_constructor& err) {
3486 error << _("Session: could not load diskstream via XML state") << endmsg;
3494 /** Connect things to the MMC object */
3496 Session::setup_midi_machine_control ()
3498 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3500 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3501 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3502 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3503 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3504 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3505 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3506 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3507 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3508 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3509 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3510 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3511 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3512 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3514 /* also handle MIDI SPP because its so common */
3516 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3517 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3518 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));
3521 boost::shared_ptr<Controllable>
3522 Session::solo_cut_control() const
3524 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3525 controls in Ardour that currently get presented to the user in the GUI that require
3526 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3528 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3529 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3533 return _solo_cut_control;