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"
31 #include <cstdio> /* snprintf(3) ... grrr */
45 #include <sys/param.h>
46 #include <sys/mount.h>
52 #include <glibmm/thread.h>
54 #include <boost/algorithm/string.hpp>
56 #include "midi++/mmc.h"
57 #include "midi++/port.h"
58 #include "midi++/manager.h"
60 #include "pbd/boost_debug.h"
61 #include "pbd/basename.h"
62 #include "pbd/controllable_descriptor.h"
63 #include "pbd/enumwriter.h"
64 #include "pbd/error.h"
65 #include "pbd/pathscanner.h"
66 #include "pbd/pthread_utils.h"
67 #include "pbd/search_path.h"
68 #include "pbd/stacktrace.h"
69 #include "pbd/convert.h"
70 #include "pbd/clear_dir.h"
72 #include "ardour/amp.h"
73 #include "ardour/audio_diskstream.h"
74 #include "ardour/audio_playlist_source.h"
75 #include "ardour/audio_track.h"
76 #include "ardour/audioengine.h"
77 #include "ardour/audiofilesource.h"
78 #include "ardour/audioplaylist.h"
79 #include "ardour/audioregion.h"
80 #include "ardour/auditioner.h"
81 #include "ardour/automation_control.h"
82 #include "ardour/buffer.h"
83 #include "ardour/butler.h"
84 #include "ardour/configuration.h"
85 #include "ardour/control_protocol_manager.h"
86 #include "ardour/crossfade.h"
87 #include "ardour/cycle_timer.h"
88 #include "ardour/directory_names.h"
89 #include "ardour/filename_extensions.h"
90 #include "ardour/io_processor.h"
91 #include "ardour/location.h"
92 #include "ardour/midi_diskstream.h"
93 #include "ardour/midi_model.h"
94 #include "ardour/midi_patch_manager.h"
95 #include "ardour/midi_playlist.h"
96 #include "ardour/midi_region.h"
97 #include "ardour/midi_source.h"
98 #include "ardour/midi_track.h"
99 #include "ardour/named_selection.h"
100 #include "ardour/pannable.h"
101 #include "ardour/processor.h"
102 #include "ardour/port.h"
103 #include "ardour/proxy_controllable.h"
104 #include "ardour/recent_sessions.h"
105 #include "ardour/region_factory.h"
106 #include "ardour/route_group.h"
107 #include "ardour/send.h"
108 #include "ardour/session.h"
109 #include "ardour/session_directory.h"
110 #include "ardour/session_metadata.h"
111 #include "ardour/session_state_utils.h"
112 #include "ardour/session_playlists.h"
113 #include "ardour/session_utils.h"
114 #include "ardour/silentfilesource.h"
115 #include "ardour/slave.h"
116 #include "ardour/smf_source.h"
117 #include "ardour/sndfile_helpers.h"
118 #include "ardour/sndfilesource.h"
119 #include "ardour/source_factory.h"
120 #include "ardour/speakers.h"
121 #include "ardour/template_utils.h"
122 #include "ardour/tempo.h"
123 #include "ardour/ticker.h"
124 #include "ardour/user_bundle.h"
125 #include "ardour/utils.h"
126 #include "ardour/utils.h"
127 #include "ardour/version.h"
128 #include "ardour/playlist_factory.h"
130 #include "control_protocol/control_protocol.h"
136 using namespace ARDOUR;
139 /** @param snapshot_name Snapshot name, without the .ardour prefix */
141 Session::first_stage_init (string fullpath, string snapshot_name)
143 if (fullpath.length() == 0) {
145 throw failed_constructor();
148 char buf[PATH_MAX+1];
149 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
150 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
152 throw failed_constructor();
157 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
158 _path += G_DIR_SEPARATOR;
161 /* these two are just provisional settings. set_state()
162 will likely override them.
165 _name = _current_snapshot_name = snapshot_name;
167 set_history_depth (Config->get_history_depth());
169 _current_frame_rate = _engine.frame_rate ();
170 _nominal_frame_rate = _current_frame_rate;
171 _base_frame_rate = _current_frame_rate;
173 _tempo_map = new TempoMap (_current_frame_rate);
174 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
177 _non_soloed_outs_muted = false;
179 _solo_isolated_cnt = 0;
180 g_atomic_int_set (&processing_prohibited, 0);
181 _transport_speed = 0;
182 _last_transport_speed = 0;
183 _target_transport_speed = 0;
184 auto_play_legal = false;
185 transport_sub_state = 0;
186 _transport_frame = 0;
187 _requested_return_frame = -1;
188 _session_range_location = 0;
189 g_atomic_int_set (&_record_status, Disabled);
190 loop_changing = false;
193 _last_roll_location = 0;
194 _last_roll_or_reversal_location = 0;
195 _last_record_location = 0;
196 pending_locate_frame = 0;
197 pending_locate_roll = false;
198 pending_locate_flush = false;
199 state_was_pending = false;
201 outbound_mtc_timecode_frame = 0;
202 next_quarter_frame_to_send = -1;
203 current_block_size = 0;
204 solo_update_disabled = false;
205 _have_captured = false;
206 _worst_output_latency = 0;
207 _worst_input_latency = 0;
208 _worst_track_latency = 0;
209 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
210 _was_seamless = Config->get_seamless_loop ();
212 _send_qf_mtc = false;
213 _pframes_since_last_mtc = 0;
214 g_atomic_int_set (&_playback_load, 100);
215 g_atomic_int_set (&_capture_load, 100);
218 pending_abort = false;
219 destructive_index = 0;
220 first_file_data_format_reset = true;
221 first_file_header_format_reset = true;
222 post_export_sync = false;
225 no_questions_about_missing_files = false;
226 _speakers.reset (new Speakers);
228 ignore_route_processor_changes = false;
230 AudioDiskstream::allocate_working_buffers();
232 /* default short fade = 15ms */
234 Crossfade::set_short_xfade_length ((framecnt_t) floor (config.get_short_xfade_seconds() * frame_rate()));
235 SndFileSource::setup_standard_crossfades (*this, frame_rate());
237 last_mmc_step.tv_sec = 0;
238 last_mmc_step.tv_usec = 0;
241 /* click sounds are unset by default, which causes us to internal
242 waveforms for clicks.
246 click_emphasis_length = 0;
249 process_function = &Session::process_with_events;
251 if (config.get_use_video_sync()) {
252 waiting_for_sync_offset = true;
254 waiting_for_sync_offset = false;
257 last_timecode_when = 0;
258 last_timecode_valid = false;
262 last_rr_session_dir = session_dirs.begin();
263 refresh_disk_space ();
265 /* default: assume simple stereo speaker configuration */
267 _speakers->setup_default_speakers (2);
271 average_slave_delta = 1800; // !!! why 1800 ????
272 have_first_delta_accumulator = false;
273 delta_accumulator_cnt = 0;
274 _slave_state = Stopped;
276 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
277 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
278 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
279 add_controllable (_solo_cut_control);
281 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
283 /* These are all static "per-class" signals */
285 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
286 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
287 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
288 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
289 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
291 /* stop IO objects from doing stuff until we're ready for them */
293 Delivery::disable_panners ();
294 IO::disable_connecting ();
298 Session::second_stage_init ()
300 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
303 if (load_state (_current_snapshot_name)) {
308 if (_butler->start_thread()) {
312 if (start_midi_thread ()) {
316 setup_midi_machine_control ();
318 // set_state() will call setup_raid_path(), but if it's a new session we need
319 // to call setup_raid_path() here.
322 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
326 setup_raid_path(_path);
329 /* we can't save till after ::when_engine_running() is called,
330 because otherwise we save state with no connections made.
331 therefore, we reset _state_of_the_state because ::set_state()
332 will have cleared it.
334 we also have to include Loading so that any events that get
335 generated between here and the end of ::when_engine_running()
336 will be processed directly rather than queued.
339 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
341 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
342 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
343 setup_click_sounds (0);
344 setup_midi_control ();
346 /* Pay attention ... */
348 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
349 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
352 when_engine_running ();
355 /* handle this one in a different way than all others, so that its clear what happened */
357 catch (AudioEngine::PortRegistrationFailure& err) {
358 error << err.what() << endmsg;
366 BootMessage (_("Reset Remote Controls"));
368 send_full_time_code (0);
369 _engine.transport_locate (0);
371 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
372 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
374 MidiClockTicker::instance().set_session (this);
375 MIDI::Name::MidiPatchManager::instance().set_session (this);
377 /* initial program change will be delivered later; see ::config_changed() */
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().midi_path().to_string();
471 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
472 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
476 dir = session_directory().dead_path().to_string();
478 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
479 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
483 dir = session_directory().export_path().to_string();
485 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
486 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
490 dir = analysis_dir ();
492 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
493 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
497 dir = plugins_dir ();
499 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
500 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
507 /** @param session_template directory containing session template, or empty.
508 * Caller must not hold process lock.
511 Session::create (const string& session_template, BusProfile* bus_profile)
513 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
514 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
518 if (ensure_subdirs ()) {
522 _writable = exists_and_writable (sys::path (_path));
524 if (!session_template.empty()) {
525 std::string in_path = session_template_dir_to_file (session_template);
527 ifstream in(in_path.c_str());
530 string out_path = _path;
532 out_path += statefile_suffix;
534 ofstream out(out_path.c_str());
540 /* Copy plugin state files from template to new session */
541 sys::path template_plugins = session_template;
542 template_plugins /= X_("plugins");
543 sys::copy_files (template_plugins, plugins_dir ());
548 error << string_compose (_("Could not open %1 for writing session template"), out_path)
554 error << string_compose (_("Could not open session template %1 for reading"), in_path)
561 /* Instantiate metadata */
563 _metadata = new SessionMetadata ();
565 /* set initial start + end point */
567 _state_of_the_state = Clean;
569 /* set up Master Out and Control Out if necessary */
574 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
576 if (bus_profile->master_out_channels) {
577 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
581 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
582 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
585 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
586 r->input()->ensure_io (count, false, this);
587 r->output()->ensure_io (count, false, this);
593 /* prohibit auto-connect to master, because there isn't one */
594 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
598 add_routes (rl, false, false);
601 /* this allows the user to override settings with an environment variable.
604 if (no_auto_connect()) {
605 bus_profile->input_ac = AutoConnectOption (0);
606 bus_profile->output_ac = AutoConnectOption (0);
609 Config->set_input_auto_connect (bus_profile->input_ac);
610 Config->set_output_auto_connect (bus_profile->output_ac);
613 if (Config->get_use_monitor_bus() && bus_profile) {
614 add_monitor_section ();
623 Session::maybe_write_autosave()
625 if (dirty() && record_status() != Recording) {
626 save_state("", true);
631 Session::remove_pending_capture_state ()
633 sys::path pending_state_file_path(_session_dir->root_path());
635 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
639 sys::remove (pending_state_file_path);
641 catch(sys::filesystem_error& ex)
643 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
644 pending_state_file_path.to_string(), ex.what()) << endmsg;
648 /** Rename a state file.
649 * @param old_name Old snapshot name.
650 * @param new_name New snapshot name.
653 Session::rename_state (string old_name, string new_name)
655 if (old_name == _current_snapshot_name || old_name == _name) {
656 /* refuse to rename the current snapshot or the "main" one */
660 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
661 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
663 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
664 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
668 sys::rename (old_xml_path, new_xml_path);
670 catch (const sys::filesystem_error& err)
672 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
673 old_name, new_name, err.what()) << endmsg;
677 /** Remove a state file.
678 * @param snapshot_name Snapshot name.
681 Session::remove_state (string snapshot_name)
683 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
684 // refuse to remove the current snapshot or the "main" one
688 sys::path xml_path(_session_dir->root_path());
690 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
692 if (!create_backup_file (xml_path)) {
693 // don't remove it if a backup can't be made
694 // create_backup_file will log the error.
699 sys::remove (xml_path);
702 #ifdef HAVE_JACK_SESSION
704 Session::jack_session_event (jack_session_event_t * event)
708 struct tm local_time;
711 localtime_r (&n, &local_time);
712 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
714 if (event->type == JackSessionSaveTemplate)
716 if (save_template( timebuf )) {
717 event->flags = JackSessionSaveError;
719 string cmd ("ardour3 -P -U ");
720 cmd += event->client_uuid;
724 event->command_line = strdup (cmd.c_str());
729 if (save_state (timebuf)) {
730 event->flags = JackSessionSaveError;
732 sys::path xml_path (_session_dir->root_path());
733 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
735 string cmd ("ardour3 -P -U ");
736 cmd += event->client_uuid;
738 cmd += xml_path.to_string();
741 event->command_line = strdup (cmd.c_str());
745 jack_session_reply (_engine.jack(), event);
747 if (event->type == JackSessionSaveAndQuit) {
748 Quit (); /* EMIT SIGNAL */
751 jack_session_event_free( event );
755 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
757 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
760 sys::path xml_path(_session_dir->root_path());
762 if (!_writable || (_state_of_the_state & CannotSave)) {
766 if (!_engine.connected ()) {
767 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
773 /* tell sources we're saving first, in case they write out to a new file
774 * which should be saved with the state rather than the old one */
775 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
776 i->second->session_saved();
779 tree.set_root (&get_state());
781 if (snapshot_name.empty()) {
782 snapshot_name = _current_snapshot_name;
783 } else if (switch_to_snapshot) {
784 _current_snapshot_name = snapshot_name;
789 /* proper save: use statefile_suffix (.ardour in English) */
791 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
793 /* make a backup copy of the old file */
795 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
796 // create_backup_file will log the error
802 /* pending save: use pending_suffix (.pending in English) */
803 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
806 sys::path tmp_path(_session_dir->root_path());
808 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
810 // cerr << "actually writing state to " << xml_path.to_string() << endl;
812 if (!tree.write (tmp_path.to_string())) {
813 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
814 sys::remove (tmp_path);
819 if (::rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
820 error << string_compose (_("could not rename temporary session file %1 to %2"),
821 tmp_path.to_string(), xml_path.to_string()) << endmsg;
822 sys::remove (tmp_path);
829 save_history (snapshot_name);
831 bool was_dirty = dirty();
833 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
836 DirtyChanged (); /* EMIT SIGNAL */
839 StateSaved (snapshot_name); /* EMIT SIGNAL */
846 Session::restore_state (string snapshot_name)
848 if (load_state (snapshot_name) == 0) {
849 set_state (*state_tree->root(), Stateful::loading_state_version);
856 Session::load_state (string snapshot_name)
861 state_was_pending = false;
863 /* check for leftover pending state from a crashed capture attempt */
865 sys::path xmlpath(_session_dir->root_path());
866 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
868 if (sys::exists (xmlpath)) {
870 /* there is pending state from a crashed capture attempt */
872 boost::optional<int> r = AskAboutPendingState();
873 if (r.get_value_or (1)) {
874 state_was_pending = true;
878 if (!state_was_pending) {
879 xmlpath = _session_dir->root_path();
880 xmlpath /= snapshot_name;
883 if (!sys::exists (xmlpath)) {
884 xmlpath = _session_dir->root_path();
885 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
886 if (!sys::exists (xmlpath)) {
887 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
892 state_tree = new XMLTree;
896 _writable = exists_and_writable (xmlpath);
898 if (!state_tree->read (xmlpath.to_string())) {
899 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
905 XMLNode& root (*state_tree->root());
907 if (root.name() != X_("Session")) {
908 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
914 const XMLProperty* prop;
916 if ((prop = root.property ("version")) == 0) {
917 /* no version implies very old version of Ardour */
918 Stateful::loading_state_version = 1000;
924 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
925 Stateful::loading_state_version = (major * 1000) + minor;
928 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
930 sys::path backup_path(_session_dir->root_path());
932 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
934 // only create a backup once
935 if (sys::exists (backup_path)) {
939 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
940 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
945 sys::copy_file (xmlpath, backup_path);
947 catch(sys::filesystem_error& ex)
949 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
950 xmlpath.to_string(), ex.what())
960 Session::load_options (const XMLNode& node)
962 LocaleGuard lg (X_("POSIX"));
963 config.set_variables (node);
974 Session::get_template()
976 /* if we don't disable rec-enable, diskstreams
977 will believe they need to store their capture
978 sources in their state node.
981 disable_record (false);
987 Session::state(bool full_state)
989 XMLNode* node = new XMLNode("Session");
992 // store libardour version, just in case
994 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
995 node->add_property("version", string(buf));
997 /* store configuration settings */
1001 node->add_property ("name", _name);
1002 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1003 node->add_property ("sample-rate", buf);
1005 if (session_dirs.size() > 1) {
1009 vector<space_and_path>::iterator i = session_dirs.begin();
1010 vector<space_and_path>::iterator next;
1012 ++i; /* skip the first one */
1016 while (i != session_dirs.end()) {
1020 if (next != session_dirs.end()) {
1030 child = node->add_child ("Path");
1031 child->add_content (p);
1035 /* save the ID counter */
1037 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1038 node->add_property ("id-counter", buf);
1040 /* save the event ID counter */
1042 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1043 node->add_property ("event-counter", buf);
1045 /* various options */
1047 node->add_child_nocopy (config.get_variables ());
1049 node->add_child_nocopy (_metadata->get_state());
1051 child = node->add_child ("Sources");
1054 Glib::Mutex::Lock sl (source_lock);
1056 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1058 /* Don't save information about non-file Sources, or
1059 * about non-destructive file sources that are empty
1060 * and unused by any regions.
1063 boost::shared_ptr<FileSource> fs;
1065 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1067 if (!fs->destructive()) {
1068 if (fs->empty() && !fs->used()) {
1073 child->add_child_nocopy (siter->second->get_state());
1078 child = node->add_child ("Regions");
1081 Glib::Mutex::Lock rl (region_lock);
1082 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1083 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1084 boost::shared_ptr<Region> r = i->second;
1085 /* only store regions not attached to playlists */
1086 if (r->playlist() == 0) {
1087 child->add_child_nocopy (r->state ());
1091 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1093 if (!cassocs.empty()) {
1094 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1096 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1098 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1099 i->first->id().print (buf, sizeof (buf));
1100 can->add_property (X_("copy"), buf);
1101 i->second->id().print (buf, sizeof (buf));
1102 can->add_property (X_("original"), buf);
1103 ca->add_child_nocopy (*can);
1109 node->add_child_nocopy (_locations->get_state());
1111 // for a template, just create a new Locations, populate it
1112 // with the default start and end, and get the state for that.
1113 Locations loc (*this);
1114 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1115 range->set (max_framepos, 0);
1117 node->add_child_nocopy (loc.get_state());
1120 child = node->add_child ("Bundles");
1122 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1123 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1124 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1126 child->add_child_nocopy (b->get_state());
1131 child = node->add_child ("Routes");
1133 boost::shared_ptr<RouteList> r = routes.reader ();
1135 RoutePublicOrderSorter cmp;
1136 RouteList public_order (*r);
1137 public_order.sort (cmp);
1139 /* the sort should have put control outs first */
1142 assert (_monitor_out == public_order.front());
1145 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1146 if (!(*i)->is_hidden()) {
1148 child->add_child_nocopy ((*i)->get_state());
1150 child->add_child_nocopy ((*i)->get_template());
1156 playlists->add_state (node, full_state);
1158 child = node->add_child ("RouteGroups");
1159 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1160 child->add_child_nocopy ((*i)->get_state());
1164 child = node->add_child ("Click");
1165 child->add_child_nocopy (_click_io->state (full_state));
1169 child = node->add_child ("NamedSelections");
1170 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1172 child->add_child_nocopy ((*i)->get_state());
1177 node->add_child_nocopy (_speakers->get_state());
1178 node->add_child_nocopy (_tempo_map->get_state());
1179 node->add_child_nocopy (get_control_protocol_state());
1182 node->add_child_copy (*_extra_xml);
1189 Session::get_control_protocol_state ()
1191 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1192 return cpm.get_state();
1196 Session::set_state (const XMLNode& node, int version)
1200 const XMLProperty* prop;
1203 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1205 if (node.name() != X_("Session")) {
1206 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1210 if ((prop = node.property ("version")) != 0) {
1211 version = atoi (prop->value ()) * 1000;
1214 if ((prop = node.property ("name")) != 0) {
1215 _name = prop->value ();
1218 if ((prop = node.property (X_("sample-rate"))) != 0) {
1220 _nominal_frame_rate = atoi (prop->value());
1222 if (_nominal_frame_rate != _current_frame_rate) {
1223 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1224 if (r.get_value_or (0)) {
1230 setup_raid_path(_session_dir->root_path().to_string());
1232 if ((prop = node.property (X_("id-counter"))) != 0) {
1234 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1235 ID::init_counter (x);
1237 /* old sessions used a timebased counter, so fake
1238 the startup ID counter based on a standard
1243 ID::init_counter (now);
1246 if ((prop = node.property (X_("event-counter"))) != 0) {
1247 Evoral::init_event_id_counter (atoi (prop->value()));
1250 IO::disable_connecting ();
1252 Stateful::save_extra_xml (node);
1254 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1255 load_options (*child);
1256 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1257 load_options (*child);
1259 error << _("Session: XML state has no options section") << endmsg;
1262 if (version >= 3000) {
1263 if ((child = find_named_node (node, "Metadata")) == 0) {
1264 warning << _("Session: XML state has no metadata section") << endmsg;
1265 } else if (_metadata->set_state (*child, version)) {
1270 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1271 _speakers->set_state (*child, version);
1274 if ((child = find_named_node (node, "Sources")) == 0) {
1275 error << _("Session: XML state has no sources section") << endmsg;
1277 } else if (load_sources (*child)) {
1281 if ((child = find_named_node (node, "TempoMap")) == 0) {
1282 error << _("Session: XML state has no Tempo Map section") << endmsg;
1284 } else if (_tempo_map->set_state (*child, version)) {
1288 if ((child = find_named_node (node, "Locations")) == 0) {
1289 error << _("Session: XML state has no locations section") << endmsg;
1291 } else if (_locations->set_state (*child, version)) {
1297 if ((location = _locations->auto_loop_location()) != 0) {
1298 set_auto_loop_location (location);
1301 if ((location = _locations->auto_punch_location()) != 0) {
1302 set_auto_punch_location (location);
1305 if ((location = _locations->session_range_location()) != 0) {
1306 delete _session_range_location;
1307 _session_range_location = location;
1310 if (_session_range_location) {
1311 AudioFileSource::set_header_position_offset (_session_range_location->start());
1314 if ((child = find_named_node (node, "Regions")) == 0) {
1315 error << _("Session: XML state has no Regions section") << endmsg;
1317 } else if (load_regions (*child)) {
1321 if ((child = find_named_node (node, "Playlists")) == 0) {
1322 error << _("Session: XML state has no playlists section") << endmsg;
1324 } else if (playlists->load (*this, *child)) {
1328 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1330 } else if (playlists->load_unused (*this, *child)) {
1334 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1335 if (load_compounds (*child)) {
1340 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1341 if (load_named_selections (*child)) {
1346 if (version >= 3000) {
1347 if ((child = find_named_node (node, "Bundles")) == 0) {
1348 warning << _("Session: XML state has no bundles section") << endmsg;
1351 /* We can't load Bundles yet as they need to be able
1352 to convert from port names to Port objects, which can't happen until
1354 _bundle_xml_node = new XMLNode (*child);
1358 if (version < 3000) {
1359 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1360 error << _("Session: XML state has no diskstreams section") << endmsg;
1362 } else if (load_diskstreams_2X (*child, version)) {
1367 if ((child = find_named_node (node, "Routes")) == 0) {
1368 error << _("Session: XML state has no routes section") << endmsg;
1370 } else if (load_routes (*child, version)) {
1374 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1375 _diskstreams_2X.clear ();
1377 if (version >= 3000) {
1379 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1380 error << _("Session: XML state has no route groups section") << endmsg;
1382 } else if (load_route_groups (*child, version)) {
1386 } else if (version < 3000) {
1388 if ((child = find_named_node (node, "EditGroups")) == 0) {
1389 error << _("Session: XML state has no edit groups section") << endmsg;
1391 } else if (load_route_groups (*child, version)) {
1395 if ((child = find_named_node (node, "MixGroups")) == 0) {
1396 error << _("Session: XML state has no mix groups section") << endmsg;
1398 } else if (load_route_groups (*child, version)) {
1403 if ((child = find_named_node (node, "Click")) == 0) {
1404 warning << _("Session: XML state has no click section") << endmsg;
1405 } else if (_click_io) {
1406 _click_io->set_state (*child, version);
1409 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1410 ControlProtocolManager::instance().set_protocol_states (*child);
1413 /* here beginneth the second phase ... */
1415 StateReady (); /* EMIT SIGNAL */
1424 Session::load_routes (const XMLNode& node, int version)
1427 XMLNodeConstIterator niter;
1428 RouteList new_routes;
1430 nlist = node.children();
1434 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1436 boost::shared_ptr<Route> route;
1437 if (version < 3000) {
1438 route = XMLRouteFactory_2X (**niter, version);
1440 route = XMLRouteFactory (**niter, version);
1444 error << _("Session: cannot create Route from XML description.") << endmsg;
1448 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1450 new_routes.push_back (route);
1453 add_routes (new_routes, false, false);
1458 boost::shared_ptr<Route>
1459 Session::XMLRouteFactory (const XMLNode& node, int version)
1461 boost::shared_ptr<Route> ret;
1463 if (node.name() != "Route") {
1467 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1469 DataType type = DataType::AUDIO;
1470 const XMLProperty* prop = node.property("default-type");
1473 type = DataType (prop->value());
1476 assert (type != DataType::NIL);
1480 boost::shared_ptr<Track> track;
1482 if (type == DataType::AUDIO) {
1483 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1485 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1488 if (track->init()) {
1492 if (track->set_state (node, version)) {
1496 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1497 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1502 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1504 if (r->init () == 0 && r->set_state (node, version) == 0) {
1505 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1506 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1515 boost::shared_ptr<Route>
1516 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1518 boost::shared_ptr<Route> ret;
1520 if (node.name() != "Route") {
1524 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1526 ds_prop = node.property (X_("diskstream"));
1529 DataType type = DataType::AUDIO;
1530 const XMLProperty* prop = node.property("default-type");
1533 type = DataType (prop->value());
1536 assert (type != DataType::NIL);
1540 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1541 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1545 if (i == _diskstreams_2X.end()) {
1546 error << _("Could not find diskstream for route") << endmsg;
1547 return boost::shared_ptr<Route> ();
1550 boost::shared_ptr<Track> track;
1552 if (type == DataType::AUDIO) {
1553 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1555 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1558 if (track->init()) {
1562 if (track->set_state (node, version)) {
1566 track->set_diskstream (*i);
1568 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1569 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1574 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1576 if (r->init () == 0 && r->set_state (node, version) == 0) {
1577 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1578 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1588 Session::load_regions (const XMLNode& node)
1591 XMLNodeConstIterator niter;
1592 boost::shared_ptr<Region> region;
1594 nlist = node.children();
1598 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1599 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1600 error << _("Session: cannot create Region from XML description.");
1601 const XMLProperty *name = (**niter).property("name");
1604 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1615 Session::load_compounds (const XMLNode& node)
1617 XMLNodeList calist = node.children();
1618 XMLNodeConstIterator caiter;
1619 XMLProperty *caprop;
1621 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1622 XMLNode* ca = *caiter;
1626 if ((caprop = ca->property (X_("original"))) == 0) {
1629 orig_id = caprop->value();
1631 if ((caprop = ca->property (X_("copy"))) == 0) {
1634 copy_id = caprop->value();
1636 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1637 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1639 if (!orig || !copy) {
1640 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1646 RegionFactory::add_compound_association (orig, copy);
1653 Session::load_nested_sources (const XMLNode& node)
1656 XMLNodeConstIterator niter;
1658 nlist = node.children();
1660 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1661 if ((*niter)->name() == "Source") {
1663 /* it may already exist, so don't recreate it unnecessarily
1666 XMLProperty* prop = (*niter)->property (X_("id"));
1668 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1672 ID source_id (prop->value());
1674 if (!source_by_id (source_id)) {
1677 SourceFactory::create (*this, **niter, true);
1679 catch (failed_constructor& err) {
1680 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1687 boost::shared_ptr<Region>
1688 Session::XMLRegionFactory (const XMLNode& node, bool full)
1690 const XMLProperty* type = node.property("type");
1694 const XMLNodeList& nlist = node.children();
1696 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1697 XMLNode *child = (*niter);
1698 if (child->name() == "NestedSource") {
1699 load_nested_sources (*child);
1703 if (!type || type->value() == "audio") {
1704 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1705 } else if (type->value() == "midi") {
1706 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1709 } catch (failed_constructor& err) {
1710 return boost::shared_ptr<Region> ();
1713 return boost::shared_ptr<Region> ();
1716 boost::shared_ptr<AudioRegion>
1717 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1719 const XMLProperty* prop;
1720 boost::shared_ptr<Source> source;
1721 boost::shared_ptr<AudioSource> as;
1723 SourceList master_sources;
1724 uint32_t nchans = 1;
1727 if (node.name() != X_("Region")) {
1728 return boost::shared_ptr<AudioRegion>();
1731 if ((prop = node.property (X_("channels"))) != 0) {
1732 nchans = atoi (prop->value().c_str());
1735 if ((prop = node.property ("name")) == 0) {
1736 cerr << "no name for this region\n";
1740 if ((prop = node.property (X_("source-0"))) == 0) {
1741 if ((prop = node.property ("source")) == 0) {
1742 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1743 return boost::shared_ptr<AudioRegion>();
1747 PBD::ID s_id (prop->value());
1749 if ((source = source_by_id (s_id)) == 0) {
1750 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1751 return boost::shared_ptr<AudioRegion>();
1754 as = boost::dynamic_pointer_cast<AudioSource>(source);
1756 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1757 return boost::shared_ptr<AudioRegion>();
1760 sources.push_back (as);
1762 /* pickup other channels */
1764 for (uint32_t n=1; n < nchans; ++n) {
1765 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1766 if ((prop = node.property (buf)) != 0) {
1768 PBD::ID id2 (prop->value());
1770 if ((source = source_by_id (id2)) == 0) {
1771 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1772 return boost::shared_ptr<AudioRegion>();
1775 as = boost::dynamic_pointer_cast<AudioSource>(source);
1777 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1778 return boost::shared_ptr<AudioRegion>();
1780 sources.push_back (as);
1784 for (uint32_t n = 0; n < nchans; ++n) {
1785 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1786 if ((prop = node.property (buf)) != 0) {
1788 PBD::ID id2 (prop->value());
1790 if ((source = source_by_id (id2)) == 0) {
1791 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1792 return boost::shared_ptr<AudioRegion>();
1795 as = boost::dynamic_pointer_cast<AudioSource>(source);
1797 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1798 return boost::shared_ptr<AudioRegion>();
1800 master_sources.push_back (as);
1805 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1807 /* a final detail: this is the one and only place that we know how long missing files are */
1809 if (region->whole_file()) {
1810 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1811 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1813 sfp->set_length (region->length());
1818 if (!master_sources.empty()) {
1819 if (master_sources.size() != nchans) {
1820 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1822 region->set_master_sources (master_sources);
1830 catch (failed_constructor& err) {
1831 return boost::shared_ptr<AudioRegion>();
1835 boost::shared_ptr<MidiRegion>
1836 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1838 const XMLProperty* prop;
1839 boost::shared_ptr<Source> source;
1840 boost::shared_ptr<MidiSource> ms;
1843 if (node.name() != X_("Region")) {
1844 return boost::shared_ptr<MidiRegion>();
1847 if ((prop = node.property ("name")) == 0) {
1848 cerr << "no name for this region\n";
1852 if ((prop = node.property (X_("source-0"))) == 0) {
1853 if ((prop = node.property ("source")) == 0) {
1854 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1855 return boost::shared_ptr<MidiRegion>();
1859 PBD::ID s_id (prop->value());
1861 if ((source = source_by_id (s_id)) == 0) {
1862 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1863 return boost::shared_ptr<MidiRegion>();
1866 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1868 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1869 return boost::shared_ptr<MidiRegion>();
1872 sources.push_back (ms);
1875 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1876 /* a final detail: this is the one and only place that we know how long missing files are */
1878 if (region->whole_file()) {
1879 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1880 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1882 sfp->set_length (region->length());
1890 catch (failed_constructor& err) {
1891 return boost::shared_ptr<MidiRegion>();
1896 Session::get_sources_as_xml ()
1899 XMLNode* node = new XMLNode (X_("Sources"));
1900 Glib::Mutex::Lock lm (source_lock);
1902 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1903 node->add_child_nocopy (i->second->get_state());
1910 Session::path_from_region_name (DataType type, string name, string identifier)
1912 char buf[PATH_MAX+1];
1914 SessionDirectory sdir(get_best_session_directory_for_new_source());
1915 sys::path source_dir = ((type == DataType::AUDIO)
1916 ? sdir.sound_path() : sdir.midi_path());
1918 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1920 for (n = 0; n < 999999; ++n) {
1921 if (identifier.length()) {
1922 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1923 identifier.c_str(), n, ext.c_str());
1925 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1929 sys::path source_path = source_dir / buf;
1931 if (!sys::exists (source_path)) {
1932 return source_path.to_string();
1936 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1945 Session::load_sources (const XMLNode& node)
1948 XMLNodeConstIterator niter;
1949 boost::shared_ptr<Source> source;
1951 nlist = node.children();
1955 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1958 if ((source = XMLSourceFactory (**niter)) == 0) {
1959 error << _("Session: cannot create Source from XML description.") << endmsg;
1962 } catch (MissingSource& err) {
1966 if (!no_questions_about_missing_files) {
1967 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1972 switch (user_choice) {
1974 /* user added a new search location, so try again */
1979 /* user asked to quit the entire session load
1984 no_questions_about_missing_files = true;
1988 no_questions_about_missing_files = true;
1993 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1994 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2003 boost::shared_ptr<Source>
2004 Session::XMLSourceFactory (const XMLNode& node)
2006 if (node.name() != "Source") {
2007 return boost::shared_ptr<Source>();
2011 /* note: do peak building in another thread when loading session state */
2012 return SourceFactory::create (*this, node, true);
2015 catch (failed_constructor& err) {
2016 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2017 return boost::shared_ptr<Source>();
2022 Session::save_template (string template_name)
2026 if (_state_of_the_state & CannotSave) {
2030 sys::path user_template_dir(user_template_directory());
2034 sys::create_directories (user_template_dir);
2036 catch(sys::filesystem_error& ex)
2038 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2039 user_template_dir.to_string(), ex.what()) << endmsg;
2043 tree.set_root (&get_template());
2045 sys::path template_dir_path(user_template_dir);
2047 /* directory to put the template in */
2048 template_dir_path /= template_name;
2049 if (sys::exists (template_dir_path))
2051 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2052 template_dir_path.to_string()) << endmsg;
2056 sys::create_directories (template_dir_path);
2059 sys::path template_file_path = template_dir_path;
2060 template_file_path /= template_name + template_suffix;
2062 if (!tree.write (template_file_path.to_string())) {
2063 error << _("template not saved") << endmsg;
2067 /* copy plugin state directory */
2069 sys::path template_plugin_state_path = template_dir_path;
2070 template_plugin_state_path /= X_("plugins");
2071 sys::create_directories (template_plugin_state_path);
2072 sys::copy_files (plugins_dir(), template_plugin_state_path);
2078 Session::refresh_disk_space ()
2081 struct statfs statfsbuf;
2082 vector<space_and_path>::iterator i;
2083 Glib::Mutex::Lock lm (space_lock);
2086 /* get freespace on every FS that is part of the session path */
2088 _total_free_4k_blocks = 0;
2090 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2091 statfs ((*i).path.c_str(), &statfsbuf);
2093 scale = statfsbuf.f_bsize/4096.0;
2095 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2096 _total_free_4k_blocks += (*i).blocks;
2102 Session::get_best_session_directory_for_new_source ()
2104 vector<space_and_path>::iterator i;
2105 string result = _session_dir->root_path().to_string();
2107 /* handle common case without system calls */
2109 if (session_dirs.size() == 1) {
2113 /* OK, here's the algorithm we're following here:
2115 We want to select which directory to use for
2116 the next file source to be created. Ideally,
2117 we'd like to use a round-robin process so as to
2118 get maximum performance benefits from splitting
2119 the files across multiple disks.
2121 However, in situations without much diskspace, an
2122 RR approach may end up filling up a filesystem
2123 with new files while others still have space.
2124 Its therefore important to pay some attention to
2125 the freespace in the filesystem holding each
2126 directory as well. However, if we did that by
2127 itself, we'd keep creating new files in the file
2128 system with the most space until it was as full
2129 as all others, thus negating any performance
2130 benefits of this RAID-1 like approach.
2132 So, we use a user-configurable space threshold. If
2133 there are at least 2 filesystems with more than this
2134 much space available, we use RR selection between them.
2135 If not, then we pick the filesystem with the most space.
2137 This gets a good balance between the two
2141 refresh_disk_space ();
2143 int free_enough = 0;
2145 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2146 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2151 if (free_enough >= 2) {
2152 /* use RR selection process, ensuring that the one
2156 i = last_rr_session_dir;
2159 if (++i == session_dirs.end()) {
2160 i = session_dirs.begin();
2163 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2164 if (create_session_directory ((*i).path)) {
2166 last_rr_session_dir = i;
2171 } while (i != last_rr_session_dir);
2175 /* pick FS with the most freespace (and that
2176 seems to actually work ...)
2179 vector<space_and_path> sorted;
2180 space_and_path_ascending_cmp cmp;
2182 sorted = session_dirs;
2183 sort (sorted.begin(), sorted.end(), cmp);
2185 for (i = sorted.begin(); i != sorted.end(); ++i) {
2186 if (create_session_directory ((*i).path)) {
2188 last_rr_session_dir = i;
2198 Session::load_named_selections (const XMLNode& node)
2201 XMLNodeConstIterator niter;
2204 nlist = node.children();
2208 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2210 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2211 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2219 Session::XMLNamedSelectionFactory (const XMLNode& node)
2222 return new NamedSelection (*this, node);
2225 catch (failed_constructor& err) {
2231 Session::automation_dir () const
2233 return Glib::build_filename (_path, "automation");
2237 Session::analysis_dir () const
2239 return Glib::build_filename (_path, "analysis");
2243 Session::plugins_dir () const
2245 return Glib::build_filename (_path, "plugins");
2249 Session::load_bundles (XMLNode const & node)
2251 XMLNodeList nlist = node.children();
2252 XMLNodeConstIterator niter;
2256 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2257 if ((*niter)->name() == "InputBundle") {
2258 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2259 } else if ((*niter)->name() == "OutputBundle") {
2260 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2262 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2271 Session::load_route_groups (const XMLNode& node, int version)
2273 XMLNodeList nlist = node.children();
2274 XMLNodeConstIterator niter;
2278 if (version >= 3000) {
2280 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2281 if ((*niter)->name() == "RouteGroup") {
2282 RouteGroup* rg = new RouteGroup (*this, "");
2283 add_route_group (rg);
2284 rg->set_state (**niter, version);
2288 } else if (version < 3000) {
2290 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2291 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2292 RouteGroup* rg = new RouteGroup (*this, "");
2293 add_route_group (rg);
2294 rg->set_state (**niter, version);
2303 Session::auto_save()
2305 save_state (_current_snapshot_name);
2309 state_file_filter (const string &str, void */*arg*/)
2311 return (str.length() > strlen(statefile_suffix) &&
2312 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2316 bool operator()(const string* a, const string* b) {
2322 remove_end(string* state)
2324 string statename(*state);
2326 string::size_type start,end;
2327 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2328 statename = statename.substr (start+1);
2331 if ((end = statename.rfind(".ardour")) == string::npos) {
2332 end = statename.length();
2335 return new string(statename.substr (0, end));
2339 Session::possible_states (string path)
2341 PathScanner scanner;
2342 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2344 transform(states->begin(), states->end(), states->begin(), remove_end);
2347 sort (states->begin(), states->end(), cmp);
2353 Session::possible_states () const
2355 return possible_states(_path);
2359 Session::add_route_group (RouteGroup* g)
2361 _route_groups.push_back (g);
2362 route_group_added (g); /* EMIT SIGNAL */
2364 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2365 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2366 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2372 Session::remove_route_group (RouteGroup& rg)
2374 list<RouteGroup*>::iterator i;
2376 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2377 _route_groups.erase (i);
2380 route_group_removed (); /* EMIT SIGNAL */
2384 /** Set a new order for our route groups, without adding or removing any.
2385 * @param groups Route group list in the new order.
2388 Session::reorder_route_groups (list<RouteGroup*> groups)
2390 _route_groups = groups;
2392 route_groups_reordered (); /* EMIT SIGNAL */
2398 Session::route_group_by_name (string name)
2400 list<RouteGroup *>::iterator i;
2402 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2403 if ((*i)->name() == name) {
2411 Session::all_route_group() const
2413 return *_all_route_group;
2417 Session::add_commands (vector<Command*> const & cmds)
2419 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2425 Session::begin_reversible_command (const string& name)
2427 begin_reversible_command (g_quark_from_string (name.c_str ()));
2430 /** Begin a reversible command using a GQuark to identify it.
2431 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2432 * but there must be as many begin...()s as there are commit...()s.
2435 Session::begin_reversible_command (GQuark q)
2437 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2438 to hold all the commands that are committed. This keeps the order of
2439 commands correct in the history.
2442 if (_current_trans == 0) {
2443 /* start a new transaction */
2444 assert (_current_trans_quarks.empty ());
2445 _current_trans = new UndoTransaction();
2446 _current_trans->set_name (g_quark_to_string (q));
2449 _current_trans_quarks.push_front (q);
2453 Session::commit_reversible_command (Command *cmd)
2455 assert (_current_trans);
2456 assert (!_current_trans_quarks.empty ());
2461 _current_trans->add_command (cmd);
2464 _current_trans_quarks.pop_front ();
2466 if (!_current_trans_quarks.empty ()) {
2467 /* the transaction we're committing is not the top-level one */
2471 if (_current_trans->empty()) {
2472 /* no commands were added to the transaction, so just get rid of it */
2473 delete _current_trans;
2478 gettimeofday (&now, 0);
2479 _current_trans->set_timestamp (now);
2481 _history.add (_current_trans);
2486 accept_all_audio_files (const string& path, void */*arg*/)
2488 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2492 if (!AudioFileSource::safe_audio_file_extension (path)) {
2500 accept_all_midi_files (const string& path, void */*arg*/)
2502 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2506 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2507 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2508 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2512 accept_all_state_files (const string& path, void */*arg*/)
2514 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2518 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2522 Session::find_all_sources (string path, set<string>& result)
2527 if (!tree.read (path)) {
2531 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2536 XMLNodeConstIterator niter;
2538 nlist = node->children();
2542 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2546 if ((prop = (*niter)->property (X_("type"))) == 0) {
2550 DataType type (prop->value());
2552 if ((prop = (*niter)->property (X_("name"))) == 0) {
2556 if (Glib::path_is_absolute (prop->value())) {
2557 /* external file, ignore */
2565 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2566 result.insert (found_path);
2574 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2576 PathScanner scanner;
2577 vector<string*>* state_files;
2579 string this_snapshot_path;
2585 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2586 ripped = ripped.substr (0, ripped.length() - 1);
2589 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2591 if (state_files == 0) {
2596 this_snapshot_path = _path;
2597 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2598 this_snapshot_path += statefile_suffix;
2600 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2602 if (exclude_this_snapshot && **i == this_snapshot_path) {
2606 if (find_all_sources (**i, result) < 0) {
2614 struct RegionCounter {
2615 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2616 AudioSourceList::iterator iter;
2617 boost::shared_ptr<Region> region;
2620 RegionCounter() : count (0) {}
2624 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2626 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2627 return r.get_value_or (1);
2631 Session::cleanup_regions ()
2633 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2635 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2637 uint32_t used = playlists->region_use_count (i->second);
2639 if (used == 0 && !i->second->automatic ()) {
2640 RegionFactory::map_remove (i->second);
2644 /* dump the history list */
2651 Session::cleanup_sources (CleanupReport& rep)
2653 // FIXME: needs adaptation to midi
2655 vector<boost::shared_ptr<Source> > dead_sources;
2656 PathScanner scanner;
2659 vector<space_and_path>::iterator i;
2660 vector<space_and_path>::iterator nexti;
2661 vector<string*>* candidates;
2662 vector<string*>* candidates2;
2663 vector<string> unused;
2664 set<string> all_sources;
2669 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2671 /* consider deleting all unused playlists */
2673 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2678 /* sync the "all regions" property of each playlist with its current state
2681 playlists->sync_all_regions_with_regions ();
2683 /* find all un-used sources */
2688 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2690 SourceMap::iterator tmp;
2695 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2699 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2700 dead_sources.push_back (i->second);
2701 i->second->drop_references ();
2707 /* build a list of all the possible audio directories for the session */
2709 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2714 SessionDirectory sdir ((*i).path);
2715 audio_path += sdir.sound_path().to_string();
2717 if (nexti != session_dirs.end()) {
2725 /* build a list of all the possible midi directories for the session */
2727 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2732 SessionDirectory sdir ((*i).path);
2733 midi_path += sdir.midi_path().to_string();
2735 if (nexti != session_dirs.end()) {
2742 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2743 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2749 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2750 candidates->push_back (*i);
2755 candidates = candidates2; // might still be null
2758 /* find all sources, but don't use this snapshot because the
2759 state file on disk still references sources we may have already
2763 find_all_sources_across_snapshots (all_sources, true);
2765 /* add our current source list
2768 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2769 boost::shared_ptr<FileSource> fs;
2770 SourceMap::iterator tmp = i;
2773 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2774 if (playlists->source_use_count (fs) != 0) {
2775 all_sources.insert (fs->path());
2778 /* we might not remove this source from disk, because it may be used
2779 by other snapshots, but its not being used in this version
2780 so lets get rid of it now, along with any representative regions
2784 RegionFactory::remove_regions_using_source (i->second);
2792 char tmppath1[PATH_MAX+1];
2793 char tmppath2[PATH_MAX+1];
2796 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2801 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2803 if (realpath(spath.c_str(), tmppath1) == 0) {
2804 error << string_compose (_("Cannot expand path %1 (%2)"),
2805 spath, strerror (errno)) << endmsg;
2809 if (realpath((*i).c_str(), tmppath2) == 0) {
2810 error << string_compose (_("Cannot expand path %1 (%2)"),
2811 (*i), strerror (errno)) << endmsg;
2815 if (strcmp(tmppath1, tmppath2) == 0) {
2822 unused.push_back (spath);
2831 /* now try to move all unused files into the "dead" directory(ies) */
2833 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2834 struct stat statbuf;
2838 /* don't move the file across filesystems, just
2839 stick it in the `dead_dir_name' directory
2840 on whichever filesystem it was already on.
2843 if ((*x).find ("/sounds/") != string::npos) {
2845 /* old school, go up 1 level */
2847 newpath = Glib::path_get_dirname (*x); // "sounds"
2848 newpath = Glib::path_get_dirname (newpath); // "session-name"
2852 /* new school, go up 4 levels */
2854 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2855 newpath = Glib::path_get_dirname (newpath); // "session-name"
2856 newpath = Glib::path_get_dirname (newpath); // "interchange"
2857 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2860 newpath = Glib::build_filename (newpath, dead_dir_name);
2862 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2863 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2867 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2869 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2871 /* the new path already exists, try versioning */
2873 char buf[PATH_MAX+1];
2877 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2880 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2881 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2885 if (version == 999) {
2886 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2890 newpath = newpath_v;
2895 /* it doesn't exist, or we can't read it or something */
2899 stat ((*x).c_str(), &statbuf);
2901 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2902 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2903 (*x), newpath, strerror (errno))
2908 /* see if there an easy to find peakfile for this file, and remove it.
2911 string base = basename_nosuffix (*x);
2912 base += "%A"; /* this is what we add for the channel suffix of all native files,
2913 or for the first channel of embedded files. it will miss
2914 some peakfiles for other channels
2916 string peakpath = peak_path (base);
2918 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2919 if (::unlink (peakpath.c_str()) != 0) {
2920 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2921 peakpath, _path, strerror (errno))
2923 /* try to back out */
2924 ::rename (newpath.c_str(), _path.c_str());
2929 rep.paths.push_back (*x);
2930 rep.space += statbuf.st_size;
2933 /* dump the history list */
2937 /* save state so we don't end up a session file
2938 referring to non-existent sources.
2945 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2951 Session::cleanup_trash_sources (CleanupReport& rep)
2953 // FIXME: needs adaptation for MIDI
2955 vector<space_and_path>::iterator i;
2961 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2963 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2965 clear_directory (dead_dir, &rep.space, &rep.paths);
2972 Session::set_dirty ()
2974 bool was_dirty = dirty();
2976 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2980 DirtyChanged(); /* EMIT SIGNAL */
2986 Session::set_clean ()
2988 bool was_dirty = dirty();
2990 _state_of_the_state = Clean;
2994 DirtyChanged(); /* EMIT SIGNAL */
2999 Session::set_deletion_in_progress ()
3001 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3005 Session::clear_deletion_in_progress ()
3007 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3011 Session::add_controllable (boost::shared_ptr<Controllable> c)
3013 /* this adds a controllable to the list managed by the Session.
3014 this is a subset of those managed by the Controllable class
3015 itself, and represents the only ones whose state will be saved
3016 as part of the session.
3019 Glib::Mutex::Lock lm (controllables_lock);
3020 controllables.insert (c);
3023 struct null_deleter { void operator()(void const *) const {} };
3026 Session::remove_controllable (Controllable* c)
3028 if (_state_of_the_state | Deletion) {
3032 Glib::Mutex::Lock lm (controllables_lock);
3034 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3036 if (x != controllables.end()) {
3037 controllables.erase (x);
3041 boost::shared_ptr<Controllable>
3042 Session::controllable_by_id (const PBD::ID& id)
3044 Glib::Mutex::Lock lm (controllables_lock);
3046 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3047 if ((*i)->id() == id) {
3052 return boost::shared_ptr<Controllable>();
3055 boost::shared_ptr<Controllable>
3056 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3058 boost::shared_ptr<Controllable> c;
3059 boost::shared_ptr<Route> r;
3061 switch (desc.top_level_type()) {
3062 case ControllableDescriptor::NamedRoute:
3064 std::string str = desc.top_level_name();
3065 if (str == "master") {
3067 } else if (str == "control" || str == "listen") {
3070 r = route_by_name (desc.top_level_name());
3075 case ControllableDescriptor::RemoteControlID:
3076 r = route_by_remote_id (desc.rid());
3084 switch (desc.subtype()) {
3085 case ControllableDescriptor::Gain:
3086 c = r->gain_control ();
3089 case ControllableDescriptor::Solo:
3090 c = r->solo_control();
3093 case ControllableDescriptor::Mute:
3094 c = r->mute_control();
3097 case ControllableDescriptor::Recenable:
3099 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3102 c = t->rec_enable_control ();
3107 case ControllableDescriptor::PanDirection:
3109 c = r->pannable()->pan_azimuth_control;
3113 case ControllableDescriptor::PanWidth:
3115 c = r->pannable()->pan_width_control;
3119 case ControllableDescriptor::PanElevation:
3121 c = r->pannable()->pan_elevation_control;
3125 case ControllableDescriptor::Balance:
3126 /* XXX simple pan control */
3129 case ControllableDescriptor::PluginParameter:
3131 uint32_t plugin = desc.target (0);
3132 uint32_t parameter_index = desc.target (1);
3134 /* revert to zero based counting */
3140 if (parameter_index > 0) {
3144 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3147 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3148 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3153 case ControllableDescriptor::SendGain:
3155 uint32_t send = desc.target (0);
3157 /* revert to zero-based counting */
3163 boost::shared_ptr<Processor> p = r->nth_send (send);
3166 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3167 boost::shared_ptr<Amp> a = s->amp();
3170 c = s->amp()->gain_control();
3177 /* relax and return a null pointer */
3185 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3188 Stateful::add_instant_xml (node, _path);
3191 if (write_to_config) {
3192 Config->add_instant_xml (node);
3197 Session::instant_xml (const string& node_name)
3199 return Stateful::instant_xml (node_name, _path);
3203 Session::save_history (string snapshot_name)
3211 if (snapshot_name.empty()) {
3212 snapshot_name = _current_snapshot_name;
3215 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3216 const string backup_filename = history_filename + backup_suffix;
3217 const sys::path xml_path = _session_dir->root_path() / history_filename;
3218 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3220 if (sys::exists (xml_path)) {
3223 sys::rename (xml_path, backup_path);
3225 catch (const sys::filesystem_error& err)
3227 error << _("could not backup old history file, current history not saved") << endmsg;
3232 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3236 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3238 if (!tree.write (xml_path.to_string()))
3240 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3244 sys::remove (xml_path);
3245 sys::rename (backup_path, xml_path);
3247 catch (const sys::filesystem_error& err)
3249 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3250 backup_path.to_string(), err.what()) << endmsg;
3260 Session::restore_history (string snapshot_name)
3264 if (snapshot_name.empty()) {
3265 snapshot_name = _current_snapshot_name;
3268 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3269 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3271 info << "Loading history from " << xml_path.to_string() << endmsg;
3273 if (!sys::exists (xml_path)) {
3274 info << string_compose (_("%1: no history file \"%2\" for this session."),
3275 _name, xml_path.to_string()) << endmsg;
3279 if (!tree.read (xml_path.to_string())) {
3280 error << string_compose (_("Could not understand session history file \"%1\""),
3281 xml_path.to_string()) << endmsg;
3288 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3291 UndoTransaction* ut = new UndoTransaction ();
3294 ut->set_name(t->property("name")->value());
3295 stringstream ss(t->property("tv-sec")->value());
3297 ss.str(t->property("tv-usec")->value());
3299 ut->set_timestamp(tv);
3301 for (XMLNodeConstIterator child_it = t->children().begin();
3302 child_it != t->children().end(); child_it++)
3304 XMLNode *n = *child_it;
3307 if (n->name() == "MementoCommand" ||
3308 n->name() == "MementoUndoCommand" ||
3309 n->name() == "MementoRedoCommand") {
3311 if ((c = memento_command_factory(n))) {
3315 } else if (n->name() == "NoteDiffCommand") {
3316 PBD::ID id (n->property("midi-source")->value());
3317 boost::shared_ptr<MidiSource> midi_source =
3318 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3320 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3322 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3325 } else if (n->name() == "SysExDiffCommand") {
3327 PBD::ID id (n->property("midi-source")->value());
3328 boost::shared_ptr<MidiSource> midi_source =
3329 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3331 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3333 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3336 } else if (n->name() == "PatchChangeDiffCommand") {
3338 PBD::ID id (n->property("midi-source")->value());
3339 boost::shared_ptr<MidiSource> midi_source =
3340 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3342 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3344 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3347 } else if (n->name() == "StatefulDiffCommand") {
3348 if ((c = stateful_diff_command_factory (n))) {
3349 ut->add_command (c);
3352 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3363 Session::config_changed (std::string p, bool ours)
3369 if (p == "seamless-loop") {
3371 } else if (p == "rf-speed") {
3373 } else if (p == "auto-loop") {
3375 } else if (p == "auto-input") {
3377 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3378 /* auto-input only makes a difference if we're rolling */
3379 set_track_monitor_input_status (!config.get_auto_input());
3382 } else if (p == "punch-in") {
3386 if ((location = _locations->auto_punch_location()) != 0) {
3388 if (config.get_punch_in ()) {
3389 replace_event (SessionEvent::PunchIn, location->start());
3391 remove_event (location->start(), SessionEvent::PunchIn);
3395 } else if (p == "punch-out") {
3399 if ((location = _locations->auto_punch_location()) != 0) {
3401 if (config.get_punch_out()) {
3402 replace_event (SessionEvent::PunchOut, location->end());
3404 clear_events (SessionEvent::PunchOut);
3408 } else if (p == "edit-mode") {
3410 Glib::Mutex::Lock lm (playlists->lock);
3412 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3413 (*i)->set_edit_mode (Config->get_edit_mode ());
3416 } else if (p == "use-video-sync") {
3418 waiting_for_sync_offset = config.get_use_video_sync();
3420 } else if (p == "mmc-control") {
3422 //poke_midi_thread ();
3424 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3426 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3428 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3430 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3432 } else if (p == "midi-control") {
3434 //poke_midi_thread ();
3436 } else if (p == "raid-path") {
3438 setup_raid_path (config.get_raid_path());
3440 } else if (p == "timecode-format") {
3444 } else if (p == "video-pullup") {
3448 } else if (p == "seamless-loop") {
3450 if (play_loop && transport_rolling()) {
3451 // to reset diskstreams etc
3452 request_play_loop (true);
3455 } else if (p == "rf-speed") {
3457 cumulative_rf_motion = 0;
3460 } else if (p == "click-sound") {
3462 setup_click_sounds (1);
3464 } else if (p == "click-emphasis-sound") {
3466 setup_click_sounds (-1);
3468 } else if (p == "clicking") {
3470 if (Config->get_clicking()) {
3471 if (_click_io && click_data) { // don't require emphasis data
3478 } else if (p == "send-mtc") {
3480 if (Config->get_send_mtc ()) {
3481 /* mark us ready to send */
3482 next_quarter_frame_to_send = 0;
3485 } else if (p == "send-mmc") {
3487 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3489 } else if (p == "midi-feedback") {
3491 session_midi_feedback = Config->get_midi_feedback();
3493 } else if (p == "jack-time-master") {
3495 engine().reset_timebase ();
3497 } else if (p == "native-file-header-format") {
3499 if (!first_file_header_format_reset) {
3500 reset_native_file_format ();
3503 first_file_header_format_reset = false;
3505 } else if (p == "native-file-data-format") {
3507 if (!first_file_data_format_reset) {
3508 reset_native_file_format ();
3511 first_file_data_format_reset = false;
3513 } else if (p == "external-sync") {
3514 if (!config.get_external_sync()) {
3515 drop_sync_source ();
3517 switch_to_sync_source (config.get_sync_source());
3519 } else if (p == "remote-model") {
3520 set_remote_control_ids ();
3521 } else if (p == "denormal-model") {
3523 } else if (p == "history-depth") {
3524 set_history_depth (Config->get_history_depth());
3525 } else if (p == "sync-all-route-ordering") {
3526 sync_order_keys ("session");
3527 } else if (p == "initial-program-change") {
3529 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3532 buf[0] = MIDI::program; // channel zero by default
3533 buf[1] = (Config->get_initial_program_change() & 0x7f);
3535 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3537 } else if (p == "solo-mute-override") {
3538 // catch_up_on_solo_mute_override ();
3539 } else if (p == "listen-position" || p == "pfl-position") {
3540 listen_position_changed ();
3541 } else if (p == "solo-control-is-listen-control") {
3542 solo_control_mode_changed ();
3543 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3544 last_timecode_valid = false;
3545 } else if (p == "playback-buffer-seconds") {
3546 AudioSource::allocate_working_buffers (frame_rate());
3553 Session::set_history_depth (uint32_t d)
3555 _history.set_depth (d);
3559 Session::load_diskstreams_2X (XMLNode const & node, int)
3562 XMLNodeConstIterator citer;
3564 clist = node.children();
3566 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3569 /* diskstreams added automatically by DiskstreamCreated handler */
3570 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3571 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3572 _diskstreams_2X.push_back (dsp);
3574 error << _("Session: unknown diskstream type in XML") << endmsg;
3578 catch (failed_constructor& err) {
3579 error << _("Session: could not load diskstream via XML state") << endmsg;
3587 /** Connect things to the MMC object */
3589 Session::setup_midi_machine_control ()
3591 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3593 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3594 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3595 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3596 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3597 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3598 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3599 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3600 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3601 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3602 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3603 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3604 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3605 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3607 /* also handle MIDI SPP because its so common */
3609 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3610 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3611 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));
3614 boost::shared_ptr<Controllable>
3615 Session::solo_cut_control() const
3617 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3618 controls in Ardour that currently get presented to the user in the GUI that require
3619 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3621 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3622 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3626 return _solo_cut_control;
3630 Session::rename (const std::string& new_name)
3632 string legal_name = legalize_for_path (new_name);
3638 string const old_sources_root = _session_dir->sources_root().to_string ();
3640 #define RENAME ::rename
3645 * interchange subdirectory
3649 * Backup files are left unchanged and not renamed.
3652 /* pass one: not 100% safe check that the new directory names don't
3656 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3661 /* this is a stupid hack because Glib::path_get_dirname() is
3662 * lexical-only, and so passing it /a/b/c/ gives a different
3663 * result than passing it /a/b/c ...
3666 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3667 oldstr = oldstr.substr (0, oldstr.length() - 1);
3670 string base = Glib::path_get_dirname (oldstr);
3671 string p = Glib::path_get_basename (oldstr);
3673 newstr = Glib::build_filename (base, legal_name);
3675 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3682 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3687 /* this is a stupid hack because Glib::path_get_dirname() is
3688 * lexical-only, and so passing it /a/b/c/ gives a different
3689 * result than passing it /a/b/c ...
3692 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3693 oldstr = oldstr.substr (0, oldstr.length() - 1);
3696 string base = Glib::path_get_dirname (oldstr);
3697 string p = Glib::path_get_basename (oldstr);
3699 newstr = Glib::build_filename (base, legal_name);
3701 cerr << "Rename " << oldstr << " => " << newstr << endl;
3703 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3708 (*_session_dir) = newstr;
3713 /* directory below interchange */
3715 v.push_back (newstr);
3716 v.push_back (interchange_dir_name);
3719 oldstr = Glib::build_filename (v);
3722 v.push_back (newstr);
3723 v.push_back (interchange_dir_name);
3724 v.push_back (legal_name);
3726 newstr = Glib::build_filename (v);
3728 cerr << "Rename " << oldstr << " => " << newstr << endl;
3730 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3737 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3738 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3740 cerr << "Rename " << oldstr << " => " << newstr << endl;
3742 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3749 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3751 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3752 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3754 cerr << "Rename " << oldstr << " => " << newstr << endl;
3756 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3761 /* update file source paths */
3763 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3764 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3766 string p = fs->path ();
3767 boost::replace_all (p, old_sources_root, _session_dir->sources_root().to_string ());
3772 /* remove old name from recent sessions */
3774 remove_recent_sessions (_path);
3777 _current_snapshot_name = new_name;
3782 /* save state again to get everything just right */
3784 save_state (_current_snapshot_name);
3787 /* add to recent sessions */
3789 store_recent_sessions (new_name, _path);