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 "evoral/SMF.hpp"
62 #include "pbd/boost_debug.h"
63 #include "pbd/basename.h"
64 #include "pbd/controllable_descriptor.h"
65 #include "pbd/enumwriter.h"
66 #include "pbd/error.h"
67 #include "pbd/pathscanner.h"
68 #include "pbd/pthread_utils.h"
69 #include "pbd/search_path.h"
70 #include "pbd/stacktrace.h"
71 #include "pbd/convert.h"
72 #include "pbd/clear_dir.h"
74 #include "ardour/amp.h"
75 #include "ardour/audio_diskstream.h"
76 #include "ardour/audio_track.h"
77 #include "ardour/audioengine.h"
78 #include "ardour/audiofilesource.h"
79 #include "ardour/audioregion.h"
80 #include "ardour/automation_control.h"
81 #include "ardour/butler.h"
82 #include "ardour/control_protocol_manager.h"
83 #include "ardour/directory_names.h"
84 #include "ardour/filename_extensions.h"
85 #include "ardour/location.h"
86 #include "ardour/midi_model.h"
87 #include "ardour/midi_patch_manager.h"
88 #include "ardour/midi_region.h"
89 #include "ardour/midi_source.h"
90 #include "ardour/midi_track.h"
91 #include "ardour/named_selection.h"
92 #include "ardour/pannable.h"
93 #include "ardour/playlist_factory.h"
94 #include "ardour/port.h"
95 #include "ardour/processor.h"
96 #include "ardour/proxy_controllable.h"
97 #include "ardour/recent_sessions.h"
98 #include "ardour/region_factory.h"
99 #include "ardour/route_group.h"
100 #include "ardour/send.h"
101 #include "ardour/session.h"
102 #include "ardour/session_directory.h"
103 #include "ardour/session_metadata.h"
104 #include "ardour/session_playlists.h"
105 #include "ardour/session_state_utils.h"
106 #include "ardour/session_utils.h"
107 #include "ardour/silentfilesource.h"
108 #include "ardour/sndfilesource.h"
109 #include "ardour/source_factory.h"
110 #include "ardour/speakers.h"
111 #include "ardour/template_utils.h"
112 #include "ardour/tempo.h"
113 #include "ardour/ticker.h"
114 #include "ardour/user_bundle.h"
116 #include "control_protocol/control_protocol.h"
122 using namespace ARDOUR;
125 /** @param snapshot_name Snapshot name, without the .ardour prefix */
127 Session::first_stage_init (string fullpath, string snapshot_name)
129 if (fullpath.length() == 0) {
131 throw failed_constructor();
134 char buf[PATH_MAX+1];
135 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
136 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
138 throw failed_constructor();
143 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
144 _path += G_DIR_SEPARATOR;
147 /* these two are just provisional settings. set_state()
148 will likely override them.
151 _name = _current_snapshot_name = snapshot_name;
153 set_history_depth (Config->get_history_depth());
155 _current_frame_rate = _engine.frame_rate ();
156 _nominal_frame_rate = _current_frame_rate;
157 _base_frame_rate = _current_frame_rate;
159 _tempo_map = new TempoMap (_current_frame_rate);
160 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
163 _non_soloed_outs_muted = false;
165 _solo_isolated_cnt = 0;
166 g_atomic_int_set (&processing_prohibited, 0);
167 _transport_speed = 0;
168 _last_transport_speed = 0;
169 _target_transport_speed = 0;
170 auto_play_legal = false;
171 transport_sub_state = 0;
172 _transport_frame = 0;
173 _requested_return_frame = -1;
174 _session_range_location = 0;
175 g_atomic_int_set (&_record_status, Disabled);
176 loop_changing = false;
179 _last_roll_location = 0;
180 _last_roll_or_reversal_location = 0;
181 _last_record_location = 0;
182 pending_locate_frame = 0;
183 pending_locate_roll = false;
184 pending_locate_flush = false;
185 state_was_pending = false;
187 outbound_mtc_timecode_frame = 0;
188 next_quarter_frame_to_send = -1;
189 current_block_size = 0;
190 solo_update_disabled = false;
191 _have_captured = false;
192 _worst_output_latency = 0;
193 _worst_input_latency = 0;
194 _worst_track_latency = 0;
195 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
196 _was_seamless = Config->get_seamless_loop ();
198 _send_qf_mtc = false;
199 _pframes_since_last_mtc = 0;
200 g_atomic_int_set (&_playback_load, 100);
201 g_atomic_int_set (&_capture_load, 100);
204 pending_abort = false;
205 destructive_index = 0;
206 first_file_data_format_reset = true;
207 first_file_header_format_reset = true;
208 post_export_sync = false;
211 no_questions_about_missing_files = false;
212 _speakers.reset (new Speakers);
214 ignore_route_processor_changes = false;
215 _pre_export_mmc_enabled = false;
217 AudioDiskstream::allocate_working_buffers();
219 /* default short fade = 15ms */
221 SndFileSource::setup_standard_crossfades (*this, frame_rate());
223 last_mmc_step.tv_sec = 0;
224 last_mmc_step.tv_usec = 0;
227 /* click sounds are unset by default, which causes us to internal
228 waveforms for clicks.
232 click_emphasis_length = 0;
235 process_function = &Session::process_with_events;
237 if (config.get_use_video_sync()) {
238 waiting_for_sync_offset = true;
240 waiting_for_sync_offset = false;
243 last_timecode_when = 0;
244 last_timecode_valid = false;
248 last_rr_session_dir = session_dirs.begin();
249 refresh_disk_space ();
251 /* default: assume simple stereo speaker configuration */
253 _speakers->setup_default_speakers (2);
257 average_slave_delta = 1800; // !!! why 1800 ????
258 have_first_delta_accumulator = false;
259 delta_accumulator_cnt = 0;
260 _slave_state = Stopped;
262 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
263 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
264 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
265 add_controllable (_solo_cut_control);
267 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
269 /* These are all static "per-class" signals */
271 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
272 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
273 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
274 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
275 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
277 /* stop IO objects from doing stuff until we're ready for them */
279 Delivery::disable_panners ();
280 IO::disable_connecting ();
284 Session::second_stage_init ()
286 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
289 if (load_state (_current_snapshot_name)) {
294 if (_butler->start_thread()) {
298 if (start_midi_thread ()) {
302 setup_midi_machine_control ();
304 // set_state() will call setup_raid_path(), but if it's a new session we need
305 // to call setup_raid_path() here.
308 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
312 setup_raid_path(_path);
315 /* we can't save till after ::when_engine_running() is called,
316 because otherwise we save state with no connections made.
317 therefore, we reset _state_of_the_state because ::set_state()
318 will have cleared it.
320 we also have to include Loading so that any events that get
321 generated between here and the end of ::when_engine_running()
322 will be processed directly rather than queued.
325 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
327 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
328 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
329 setup_click_sounds (0);
330 setup_midi_control ();
332 /* Pay attention ... */
334 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
335 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
337 midi_clock = new MidiClockTicker ();
338 midi_clock->set_session (this);
341 when_engine_running ();
344 /* handle this one in a different way than all others, so that its clear what happened */
346 catch (AudioEngine::PortRegistrationFailure& err) {
347 error << err.what() << endmsg;
355 BootMessage (_("Reset Remote Controls"));
357 send_full_time_code (0);
358 _engine.transport_locate (0);
360 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
361 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
363 MIDI::Name::MidiPatchManager::instance().set_session (this);
365 /* initial program change will be delivered later; see ::config_changed() */
367 _state_of_the_state = Clean;
369 Port::set_connecting_blocked (false);
371 DirtyChanged (); /* EMIT SIGNAL */
373 if (state_was_pending) {
374 save_state (_current_snapshot_name);
375 remove_pending_capture_state ();
376 state_was_pending = false;
379 BootMessage (_("Session loading complete"));
385 Session::raid_path () const
387 SearchPath raid_search_path;
389 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
390 raid_search_path += sys::path((*i).path);
393 return raid_search_path.to_string ();
397 Session::setup_raid_path (string path)
406 session_dirs.clear ();
408 SearchPath search_path(path);
409 SearchPath sound_search_path;
410 SearchPath midi_search_path;
412 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
413 sp.path = (*i).to_string ();
414 sp.blocks = 0; // not needed
415 session_dirs.push_back (sp);
417 SessionDirectory sdir(sp.path);
419 sound_search_path += sdir.sound_path ();
420 midi_search_path += sdir.midi_path ();
423 // reset the round-robin soundfile path thingie
424 last_rr_session_dir = session_dirs.begin();
428 Session::path_is_within_session (const std::string& path)
430 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
431 if (PBD::sys::path_is_within (i->path, path)) {
439 Session::ensure_subdirs ()
443 dir = session_directory().peak_path().to_string();
445 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
446 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
450 dir = session_directory().sound_path().to_string();
452 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
453 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
457 dir = session_directory().midi_path().to_string();
459 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
460 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
464 dir = session_directory().dead_path().to_string();
466 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
467 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
471 dir = session_directory().export_path().to_string();
473 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
474 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
478 dir = analysis_dir ();
480 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
481 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
485 dir = plugins_dir ();
487 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
488 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
492 dir = externals_dir ();
494 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
495 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
502 /** @param session_template directory containing session template, or empty.
503 * Caller must not hold process lock.
506 Session::create (const string& session_template, BusProfile* bus_profile)
508 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
509 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
513 if (ensure_subdirs ()) {
517 _writable = exists_and_writable (sys::path (_path));
519 if (!session_template.empty()) {
520 std::string in_path = session_template_dir_to_file (session_template);
522 ifstream in(in_path.c_str());
525 string out_path = _path;
527 out_path += statefile_suffix;
529 ofstream out(out_path.c_str());
535 /* Copy plugin state files from template to new session */
536 sys::path template_plugins = session_template;
537 template_plugins /= X_("plugins");
538 sys::copy_files (template_plugins, plugins_dir ());
543 error << string_compose (_("Could not open %1 for writing session template"), out_path)
549 error << string_compose (_("Could not open session template %1 for reading"), in_path)
556 /* set initial start + end point */
558 _state_of_the_state = Clean;
560 /* set up Master Out and Control Out if necessary */
565 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
567 if (bus_profile->master_out_channels) {
568 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
572 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
573 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
576 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
577 r->input()->ensure_io (count, false, this);
578 r->output()->ensure_io (count, false, this);
584 /* prohibit auto-connect to master, because there isn't one */
585 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
589 add_routes (rl, false, false, false);
592 /* this allows the user to override settings with an environment variable.
595 if (no_auto_connect()) {
596 bus_profile->input_ac = AutoConnectOption (0);
597 bus_profile->output_ac = AutoConnectOption (0);
600 Config->set_input_auto_connect (bus_profile->input_ac);
601 Config->set_output_auto_connect (bus_profile->output_ac);
604 if (Config->get_use_monitor_bus() && bus_profile) {
605 add_monitor_section ();
614 Session::maybe_write_autosave()
616 if (dirty() && record_status() != Recording) {
617 save_state("", true);
622 Session::remove_pending_capture_state ()
624 sys::path pending_state_file_path(_session_dir->root_path());
626 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
630 sys::remove (pending_state_file_path);
632 catch(sys::filesystem_error& ex)
634 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
635 pending_state_file_path.to_string(), ex.what()) << endmsg;
639 /** Rename a state file.
640 * @param old_name Old snapshot name.
641 * @param new_name New snapshot name.
644 Session::rename_state (string old_name, string new_name)
646 if (old_name == _current_snapshot_name || old_name == _name) {
647 /* refuse to rename the current snapshot or the "main" one */
651 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
652 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
654 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
655 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
659 sys::rename (old_xml_path, new_xml_path);
661 catch (const sys::filesystem_error& err)
663 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
664 old_name, new_name, err.what()) << endmsg;
668 /** Remove a state file.
669 * @param snapshot_name Snapshot name.
672 Session::remove_state (string snapshot_name)
674 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
675 // refuse to remove the current snapshot or the "main" one
679 sys::path xml_path(_session_dir->root_path());
681 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
683 if (!create_backup_file (xml_path)) {
684 // don't remove it if a backup can't be made
685 // create_backup_file will log the error.
690 sys::remove (xml_path);
693 #ifdef HAVE_JACK_SESSION
695 Session::jack_session_event (jack_session_event_t * event)
699 struct tm local_time;
702 localtime_r (&n, &local_time);
703 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
705 if (event->type == JackSessionSaveTemplate)
707 if (save_template( timebuf )) {
708 event->flags = JackSessionSaveError;
710 string cmd ("ardour3 -P -U ");
711 cmd += event->client_uuid;
715 event->command_line = strdup (cmd.c_str());
720 if (save_state (timebuf)) {
721 event->flags = JackSessionSaveError;
723 sys::path xml_path (_session_dir->root_path());
724 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
726 string cmd ("ardour3 -P -U ");
727 cmd += event->client_uuid;
729 cmd += xml_path.to_string();
732 event->command_line = strdup (cmd.c_str());
736 jack_session_reply (_engine.jack(), event);
738 if (event->type == JackSessionSaveAndQuit) {
739 Quit (); /* EMIT SIGNAL */
742 jack_session_event_free( event );
746 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
748 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
751 sys::path xml_path(_session_dir->root_path());
753 if (!_writable || (_state_of_the_state & CannotSave)) {
757 if (!_engine.connected ()) {
758 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
764 /* tell sources we're saving first, in case they write out to a new file
765 * which should be saved with the state rather than the old one */
766 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
768 i->second->session_saved();
769 } catch (Evoral::SMF::FileError& e) {
770 error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
774 tree.set_root (&get_state());
776 if (snapshot_name.empty()) {
777 snapshot_name = _current_snapshot_name;
778 } else if (switch_to_snapshot) {
779 _current_snapshot_name = snapshot_name;
784 /* proper save: use statefile_suffix (.ardour in English) */
786 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
788 /* make a backup copy of the old file */
790 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
791 // create_backup_file will log the error
797 /* pending save: use pending_suffix (.pending in English) */
798 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
801 sys::path tmp_path(_session_dir->root_path());
803 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
805 // cerr << "actually writing state to " << xml_path.to_string() << endl;
807 if (!tree.write (tmp_path.to_string())) {
808 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
809 sys::remove (tmp_path);
814 if (::rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
815 error << string_compose (_("could not rename temporary session file %1 to %2"),
816 tmp_path.to_string(), xml_path.to_string()) << endmsg;
817 sys::remove (tmp_path);
824 save_history (snapshot_name);
826 bool was_dirty = dirty();
828 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
831 DirtyChanged (); /* EMIT SIGNAL */
834 StateSaved (snapshot_name); /* EMIT SIGNAL */
841 Session::restore_state (string snapshot_name)
843 if (load_state (snapshot_name) == 0) {
844 set_state (*state_tree->root(), Stateful::loading_state_version);
851 Session::load_state (string snapshot_name)
856 state_was_pending = false;
858 /* check for leftover pending state from a crashed capture attempt */
860 sys::path xmlpath(_session_dir->root_path());
861 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
863 if (sys::exists (xmlpath)) {
865 /* there is pending state from a crashed capture attempt */
867 boost::optional<int> r = AskAboutPendingState();
868 if (r.get_value_or (1)) {
869 state_was_pending = true;
873 if (!state_was_pending) {
874 xmlpath = _session_dir->root_path();
875 xmlpath /= snapshot_name;
878 if (!sys::exists (xmlpath)) {
879 xmlpath = _session_dir->root_path();
880 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
881 if (!sys::exists (xmlpath)) {
882 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
887 state_tree = new XMLTree;
891 _writable = exists_and_writable (xmlpath);
893 if (!state_tree->read (xmlpath.to_string())) {
894 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
900 XMLNode& root (*state_tree->root());
902 if (root.name() != X_("Session")) {
903 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
909 const XMLProperty* prop;
911 if ((prop = root.property ("version")) == 0) {
912 /* no version implies very old version of Ardour */
913 Stateful::loading_state_version = 1000;
915 if (prop->value().find ('.') != string::npos) {
916 /* old school version format */
917 if (prop->value()[0] == '2') {
918 Stateful::loading_state_version = 2000;
920 Stateful::loading_state_version = 3000;
923 Stateful::loading_state_version = atoi (prop->value());
927 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
929 sys::path backup_path(_session_dir->root_path());
931 backup_path /= string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
933 // only create a backup for a given statefile version once
935 if (!sys::exists (backup_path)) {
937 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
938 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
942 sys::copy_file (xmlpath, backup_path);
944 } catch (sys::filesystem_error& ex) {
946 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
947 xmlpath.to_string(), ex.what())
958 Session::load_options (const XMLNode& node)
960 LocaleGuard lg (X_("POSIX"));
961 config.set_variables (node);
972 Session::get_template()
974 /* if we don't disable rec-enable, diskstreams
975 will believe they need to store their capture
976 sources in their state node.
979 disable_record (false);
985 Session::state (bool full_state)
987 XMLNode* node = new XMLNode("Session");
991 snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
992 node->add_property("version", buf);
994 /* store configuration settings */
998 node->add_property ("name", _name);
999 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1000 node->add_property ("sample-rate", buf);
1002 if (session_dirs.size() > 1) {
1006 vector<space_and_path>::iterator i = session_dirs.begin();
1007 vector<space_and_path>::iterator next;
1009 ++i; /* skip the first one */
1013 while (i != session_dirs.end()) {
1017 if (next != session_dirs.end()) {
1027 child = node->add_child ("Path");
1028 child->add_content (p);
1032 /* save the ID counter */
1034 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1035 node->add_property ("id-counter", buf);
1037 /* save the event ID counter */
1039 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1040 node->add_property ("event-counter", buf);
1042 /* various options */
1044 node->add_child_nocopy (config.get_variables ());
1046 node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
1048 child = node->add_child ("Sources");
1051 Glib::Mutex::Lock sl (source_lock);
1053 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1055 /* Don't save information about non-file Sources, or
1056 * about non-destructive file sources that are empty
1057 * and unused by any regions.
1060 boost::shared_ptr<FileSource> fs;
1062 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1064 if (!fs->destructive()) {
1065 if (fs->empty() && !fs->used()) {
1070 child->add_child_nocopy (siter->second->get_state());
1075 child = node->add_child ("Regions");
1078 Glib::Mutex::Lock rl (region_lock);
1079 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1080 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1081 boost::shared_ptr<Region> r = i->second;
1082 /* only store regions not attached to playlists */
1083 if (r->playlist() == 0) {
1084 child->add_child_nocopy (r->state ());
1088 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1090 if (!cassocs.empty()) {
1091 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1093 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1095 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1096 i->first->id().print (buf, sizeof (buf));
1097 can->add_property (X_("copy"), buf);
1098 i->second->id().print (buf, sizeof (buf));
1099 can->add_property (X_("original"), buf);
1100 ca->add_child_nocopy (*can);
1106 node->add_child_nocopy (_locations->get_state());
1108 // for a template, just create a new Locations, populate it
1109 // with the default start and end, and get the state for that.
1110 Locations loc (*this);
1111 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1112 range->set (max_framepos, 0);
1114 node->add_child_nocopy (loc.get_state());
1117 child = node->add_child ("Bundles");
1119 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1120 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1121 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1123 child->add_child_nocopy (b->get_state());
1128 child = node->add_child ("Routes");
1130 boost::shared_ptr<RouteList> r = routes.reader ();
1132 RoutePublicOrderSorter cmp;
1133 RouteList public_order (*r);
1134 public_order.sort (cmp);
1136 /* the sort should have put control outs first */
1139 assert (_monitor_out == public_order.front());
1142 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1143 if (!(*i)->is_hidden()) {
1145 child->add_child_nocopy ((*i)->get_state());
1147 child->add_child_nocopy ((*i)->get_template());
1153 playlists->add_state (node, full_state);
1155 child = node->add_child ("RouteGroups");
1156 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1157 child->add_child_nocopy ((*i)->get_state());
1161 XMLNode* gain_child = node->add_child ("Click");
1162 gain_child->add_child_nocopy (_click_io->state (full_state));
1163 gain_child->add_child_nocopy (_click_gain->state (full_state));
1167 XMLNode* ns_child = node->add_child ("NamedSelections");
1168 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1170 ns_child->add_child_nocopy ((*i)->get_state());
1175 node->add_child_nocopy (_speakers->get_state());
1176 node->add_child_nocopy (_tempo_map->get_state());
1177 node->add_child_nocopy (get_control_protocol_state());
1180 node->add_child_copy (*_extra_xml);
1187 Session::get_control_protocol_state ()
1189 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1190 return cpm.get_state();
1194 Session::set_state (const XMLNode& node, int version)
1198 const XMLProperty* prop;
1201 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1203 if (node.name() != X_("Session")) {
1204 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1208 if ((prop = node.property ("name")) != 0) {
1209 _name = prop->value ();
1212 if ((prop = node.property (X_("sample-rate"))) != 0) {
1214 _nominal_frame_rate = atoi (prop->value());
1216 if (_nominal_frame_rate != _current_frame_rate) {
1217 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1218 if (r.get_value_or (0)) {
1224 setup_raid_path(_session_dir->root_path().to_string());
1226 if ((prop = node.property (X_("id-counter"))) != 0) {
1228 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1229 ID::init_counter (x);
1231 /* old sessions used a timebased counter, so fake
1232 the startup ID counter based on a standard
1237 ID::init_counter (now);
1240 if ((prop = node.property (X_("event-counter"))) != 0) {
1241 Evoral::init_event_id_counter (atoi (prop->value()));
1244 IO::disable_connecting ();
1246 Stateful::save_extra_xml (node);
1248 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1249 load_options (*child);
1250 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1251 load_options (*child);
1253 error << _("Session: XML state has no options section") << endmsg;
1256 if (version >= 3000) {
1257 if ((child = find_named_node (node, "Metadata")) == 0) {
1258 warning << _("Session: XML state has no metadata section") << endmsg;
1259 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1264 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1265 _speakers->set_state (*child, version);
1268 if ((child = find_named_node (node, "Sources")) == 0) {
1269 error << _("Session: XML state has no sources section") << endmsg;
1271 } else if (load_sources (*child)) {
1275 if ((child = find_named_node (node, "TempoMap")) == 0) {
1276 error << _("Session: XML state has no Tempo Map section") << endmsg;
1278 } else if (_tempo_map->set_state (*child, version)) {
1282 if ((child = find_named_node (node, "Locations")) == 0) {
1283 error << _("Session: XML state has no locations section") << endmsg;
1285 } else if (_locations->set_state (*child, version)) {
1291 if ((location = _locations->auto_loop_location()) != 0) {
1292 set_auto_loop_location (location);
1295 if ((location = _locations->auto_punch_location()) != 0) {
1296 set_auto_punch_location (location);
1299 if ((location = _locations->session_range_location()) != 0) {
1300 delete _session_range_location;
1301 _session_range_location = location;
1304 if (_session_range_location) {
1305 AudioFileSource::set_header_position_offset (_session_range_location->start());
1308 if ((child = find_named_node (node, "Regions")) == 0) {
1309 error << _("Session: XML state has no Regions section") << endmsg;
1311 } else if (load_regions (*child)) {
1315 if ((child = find_named_node (node, "Playlists")) == 0) {
1316 error << _("Session: XML state has no playlists section") << endmsg;
1318 } else if (playlists->load (*this, *child)) {
1322 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1324 } else if (playlists->load_unused (*this, *child)) {
1328 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1329 if (load_compounds (*child)) {
1334 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1335 if (load_named_selections (*child)) {
1340 if (version >= 3000) {
1341 if ((child = find_named_node (node, "Bundles")) == 0) {
1342 warning << _("Session: XML state has no bundles section") << endmsg;
1345 /* We can't load Bundles yet as they need to be able
1346 to convert from port names to Port objects, which can't happen until
1348 _bundle_xml_node = new XMLNode (*child);
1352 if (version < 3000) {
1353 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1354 error << _("Session: XML state has no diskstreams section") << endmsg;
1356 } else if (load_diskstreams_2X (*child, version)) {
1361 if ((child = find_named_node (node, "Routes")) == 0) {
1362 error << _("Session: XML state has no routes section") << endmsg;
1364 } else if (load_routes (*child, version)) {
1368 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1369 _diskstreams_2X.clear ();
1371 if (version >= 3000) {
1373 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1374 error << _("Session: XML state has no route groups section") << endmsg;
1376 } else if (load_route_groups (*child, version)) {
1380 } else if (version < 3000) {
1382 if ((child = find_named_node (node, "EditGroups")) == 0) {
1383 error << _("Session: XML state has no edit groups section") << endmsg;
1385 } else if (load_route_groups (*child, version)) {
1389 if ((child = find_named_node (node, "MixGroups")) == 0) {
1390 error << _("Session: XML state has no mix groups section") << endmsg;
1392 } else if (load_route_groups (*child, version)) {
1397 if ((child = find_named_node (node, "Click")) == 0) {
1398 warning << _("Session: XML state has no click section") << endmsg;
1399 } else if (_click_io) {
1400 const XMLNodeList& children (child->children());
1401 XMLNodeList::const_iterator i = children.begin();
1402 _click_io->set_state (**i, version);
1404 if (i != children.end()) {
1405 _click_gain->set_state (**i, version);
1409 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1410 ControlProtocolManager::instance().set_protocol_states (*child);
1413 update_have_rec_enabled_track ();
1415 /* here beginneth the second phase ... */
1417 StateReady (); /* EMIT SIGNAL */
1426 Session::load_routes (const XMLNode& node, int version)
1429 XMLNodeConstIterator niter;
1430 RouteList new_routes;
1432 nlist = node.children();
1436 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1438 boost::shared_ptr<Route> route;
1439 if (version < 3000) {
1440 route = XMLRouteFactory_2X (**niter, version);
1442 route = XMLRouteFactory (**niter, version);
1446 error << _("Session: cannot create Route from XML description.") << endmsg;
1450 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1452 new_routes.push_back (route);
1455 add_routes (new_routes, false, false, false);
1460 boost::shared_ptr<Route>
1461 Session::XMLRouteFactory (const XMLNode& node, int version)
1463 boost::shared_ptr<Route> ret;
1465 if (node.name() != "Route") {
1469 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1471 DataType type = DataType::AUDIO;
1472 const XMLProperty* prop = node.property("default-type");
1475 type = DataType (prop->value());
1478 assert (type != DataType::NIL);
1482 boost::shared_ptr<Track> track;
1484 if (type == DataType::AUDIO) {
1485 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1487 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1490 if (track->init()) {
1494 if (track->set_state (node, version)) {
1498 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1499 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1504 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1506 if (r->init () == 0 && r->set_state (node, version) == 0) {
1507 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1508 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1517 boost::shared_ptr<Route>
1518 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1520 boost::shared_ptr<Route> ret;
1522 if (node.name() != "Route") {
1526 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1528 ds_prop = node.property (X_("diskstream"));
1531 DataType type = DataType::AUDIO;
1532 const XMLProperty* prop = node.property("default-type");
1535 type = DataType (prop->value());
1538 assert (type != DataType::NIL);
1542 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1543 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1547 if (i == _diskstreams_2X.end()) {
1548 error << _("Could not find diskstream for route") << endmsg;
1549 return boost::shared_ptr<Route> ();
1552 boost::shared_ptr<Track> track;
1554 if (type == DataType::AUDIO) {
1555 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1557 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1560 if (track->init()) {
1564 if (track->set_state (node, version)) {
1568 track->set_diskstream (*i);
1570 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1571 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1576 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1578 if (r->init () == 0 && r->set_state (node, version) == 0) {
1579 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1580 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1590 Session::load_regions (const XMLNode& node)
1593 XMLNodeConstIterator niter;
1594 boost::shared_ptr<Region> region;
1596 nlist = node.children();
1600 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1601 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1602 error << _("Session: cannot create Region from XML description.");
1603 const XMLProperty *name = (**niter).property("name");
1606 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1617 Session::load_compounds (const XMLNode& node)
1619 XMLNodeList calist = node.children();
1620 XMLNodeConstIterator caiter;
1621 XMLProperty *caprop;
1623 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1624 XMLNode* ca = *caiter;
1628 if ((caprop = ca->property (X_("original"))) == 0) {
1631 orig_id = caprop->value();
1633 if ((caprop = ca->property (X_("copy"))) == 0) {
1636 copy_id = caprop->value();
1638 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1639 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1641 if (!orig || !copy) {
1642 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1648 RegionFactory::add_compound_association (orig, copy);
1655 Session::load_nested_sources (const XMLNode& node)
1658 XMLNodeConstIterator niter;
1660 nlist = node.children();
1662 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1663 if ((*niter)->name() == "Source") {
1665 /* it may already exist, so don't recreate it unnecessarily
1668 XMLProperty* prop = (*niter)->property (X_("id"));
1670 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1674 ID source_id (prop->value());
1676 if (!source_by_id (source_id)) {
1679 SourceFactory::create (*this, **niter, true);
1681 catch (failed_constructor& err) {
1682 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1689 boost::shared_ptr<Region>
1690 Session::XMLRegionFactory (const XMLNode& node, bool full)
1692 const XMLProperty* type = node.property("type");
1696 const XMLNodeList& nlist = node.children();
1698 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1699 XMLNode *child = (*niter);
1700 if (child->name() == "NestedSource") {
1701 load_nested_sources (*child);
1705 if (!type || type->value() == "audio") {
1706 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1707 } else if (type->value() == "midi") {
1708 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1711 } catch (failed_constructor& err) {
1712 return boost::shared_ptr<Region> ();
1715 return boost::shared_ptr<Region> ();
1718 boost::shared_ptr<AudioRegion>
1719 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1721 const XMLProperty* prop;
1722 boost::shared_ptr<Source> source;
1723 boost::shared_ptr<AudioSource> as;
1725 SourceList master_sources;
1726 uint32_t nchans = 1;
1729 if (node.name() != X_("Region")) {
1730 return boost::shared_ptr<AudioRegion>();
1733 if ((prop = node.property (X_("channels"))) != 0) {
1734 nchans = atoi (prop->value().c_str());
1737 if ((prop = node.property ("name")) == 0) {
1738 cerr << "no name for this region\n";
1742 if ((prop = node.property (X_("source-0"))) == 0) {
1743 if ((prop = node.property ("source")) == 0) {
1744 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1745 return boost::shared_ptr<AudioRegion>();
1749 PBD::ID s_id (prop->value());
1751 if ((source = source_by_id (s_id)) == 0) {
1752 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1753 return boost::shared_ptr<AudioRegion>();
1756 as = boost::dynamic_pointer_cast<AudioSource>(source);
1758 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1759 return boost::shared_ptr<AudioRegion>();
1762 sources.push_back (as);
1764 /* pickup other channels */
1766 for (uint32_t n=1; n < nchans; ++n) {
1767 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1768 if ((prop = node.property (buf)) != 0) {
1770 PBD::ID id2 (prop->value());
1772 if ((source = source_by_id (id2)) == 0) {
1773 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1774 return boost::shared_ptr<AudioRegion>();
1777 as = boost::dynamic_pointer_cast<AudioSource>(source);
1779 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1780 return boost::shared_ptr<AudioRegion>();
1782 sources.push_back (as);
1786 for (uint32_t n = 0; n < nchans; ++n) {
1787 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1788 if ((prop = node.property (buf)) != 0) {
1790 PBD::ID id2 (prop->value());
1792 if ((source = source_by_id (id2)) == 0) {
1793 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1794 return boost::shared_ptr<AudioRegion>();
1797 as = boost::dynamic_pointer_cast<AudioSource>(source);
1799 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1800 return boost::shared_ptr<AudioRegion>();
1802 master_sources.push_back (as);
1807 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1809 /* a final detail: this is the one and only place that we know how long missing files are */
1811 if (region->whole_file()) {
1812 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1813 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1815 sfp->set_length (region->length());
1820 if (!master_sources.empty()) {
1821 if (master_sources.size() != nchans) {
1822 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1824 region->set_master_sources (master_sources);
1832 catch (failed_constructor& err) {
1833 return boost::shared_ptr<AudioRegion>();
1837 boost::shared_ptr<MidiRegion>
1838 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1840 const XMLProperty* prop;
1841 boost::shared_ptr<Source> source;
1842 boost::shared_ptr<MidiSource> ms;
1845 if (node.name() != X_("Region")) {
1846 return boost::shared_ptr<MidiRegion>();
1849 if ((prop = node.property ("name")) == 0) {
1850 cerr << "no name for this region\n";
1854 if ((prop = node.property (X_("source-0"))) == 0) {
1855 if ((prop = node.property ("source")) == 0) {
1856 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1857 return boost::shared_ptr<MidiRegion>();
1861 PBD::ID s_id (prop->value());
1863 if ((source = source_by_id (s_id)) == 0) {
1864 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1865 return boost::shared_ptr<MidiRegion>();
1868 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1870 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1871 return boost::shared_ptr<MidiRegion>();
1874 sources.push_back (ms);
1877 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1878 /* a final detail: this is the one and only place that we know how long missing files are */
1880 if (region->whole_file()) {
1881 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1882 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1884 sfp->set_length (region->length());
1892 catch (failed_constructor& err) {
1893 return boost::shared_ptr<MidiRegion>();
1898 Session::get_sources_as_xml ()
1901 XMLNode* node = new XMLNode (X_("Sources"));
1902 Glib::Mutex::Lock lm (source_lock);
1904 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1905 node->add_child_nocopy (i->second->get_state());
1912 Session::path_from_region_name (DataType type, string name, string identifier)
1914 char buf[PATH_MAX+1];
1916 SessionDirectory sdir(get_best_session_directory_for_new_source());
1917 sys::path source_dir = ((type == DataType::AUDIO)
1918 ? sdir.sound_path() : sdir.midi_path());
1920 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1922 for (n = 0; n < 999999; ++n) {
1923 if (identifier.length()) {
1924 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1925 identifier.c_str(), n, ext.c_str());
1927 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1931 sys::path source_path = source_dir / buf;
1933 if (!sys::exists (source_path)) {
1934 return source_path.to_string();
1938 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1947 Session::load_sources (const XMLNode& node)
1950 XMLNodeConstIterator niter;
1951 boost::shared_ptr<Source> source;
1953 nlist = node.children();
1957 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1960 if ((source = XMLSourceFactory (**niter)) == 0) {
1961 error << _("Session: cannot create Source from XML description.") << endmsg;
1964 } catch (MissingSource& err) {
1968 if (!no_questions_about_missing_files) {
1969 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1974 switch (user_choice) {
1976 /* user added a new search location, so try again */
1981 /* user asked to quit the entire session load
1986 no_questions_about_missing_files = true;
1990 no_questions_about_missing_files = true;
1995 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1996 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2005 boost::shared_ptr<Source>
2006 Session::XMLSourceFactory (const XMLNode& node)
2008 if (node.name() != "Source") {
2009 return boost::shared_ptr<Source>();
2013 /* note: do peak building in another thread when loading session state */
2014 return SourceFactory::create (*this, node, true);
2017 catch (failed_constructor& err) {
2018 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2019 return boost::shared_ptr<Source>();
2024 Session::save_template (string template_name)
2028 if (_state_of_the_state & CannotSave) {
2032 sys::path user_template_dir(user_template_directory());
2036 sys::create_directories (user_template_dir);
2038 catch(sys::filesystem_error& ex)
2040 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2041 user_template_dir.to_string(), ex.what()) << endmsg;
2045 tree.set_root (&get_template());
2047 sys::path template_dir_path(user_template_dir);
2049 /* directory to put the template in */
2050 template_dir_path /= template_name;
2051 if (sys::exists (template_dir_path))
2053 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2054 template_dir_path.to_string()) << endmsg;
2058 sys::create_directories (template_dir_path);
2061 sys::path template_file_path = template_dir_path;
2062 template_file_path /= template_name + template_suffix;
2064 if (!tree.write (template_file_path.to_string())) {
2065 error << _("template not saved") << endmsg;
2069 /* copy plugin state directory */
2071 sys::path template_plugin_state_path = template_dir_path;
2072 template_plugin_state_path /= X_("plugins");
2073 sys::create_directories (template_plugin_state_path);
2074 sys::copy_files (plugins_dir(), template_plugin_state_path);
2080 Session::refresh_disk_space ()
2083 struct statfs statfsbuf;
2084 vector<space_and_path>::iterator i;
2085 Glib::Mutex::Lock lm (space_lock);
2088 /* get freespace on every FS that is part of the session path */
2090 _total_free_4k_blocks = 0;
2092 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2093 statfs ((*i).path.c_str(), &statfsbuf);
2095 scale = statfsbuf.f_bsize/4096.0;
2097 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2098 _total_free_4k_blocks += (*i).blocks;
2104 Session::get_best_session_directory_for_new_source ()
2106 vector<space_and_path>::iterator i;
2107 string result = _session_dir->root_path().to_string();
2109 /* handle common case without system calls */
2111 if (session_dirs.size() == 1) {
2115 /* OK, here's the algorithm we're following here:
2117 We want to select which directory to use for
2118 the next file source to be created. Ideally,
2119 we'd like to use a round-robin process so as to
2120 get maximum performance benefits from splitting
2121 the files across multiple disks.
2123 However, in situations without much diskspace, an
2124 RR approach may end up filling up a filesystem
2125 with new files while others still have space.
2126 Its therefore important to pay some attention to
2127 the freespace in the filesystem holding each
2128 directory as well. However, if we did that by
2129 itself, we'd keep creating new files in the file
2130 system with the most space until it was as full
2131 as all others, thus negating any performance
2132 benefits of this RAID-1 like approach.
2134 So, we use a user-configurable space threshold. If
2135 there are at least 2 filesystems with more than this
2136 much space available, we use RR selection between them.
2137 If not, then we pick the filesystem with the most space.
2139 This gets a good balance between the two
2143 refresh_disk_space ();
2145 int free_enough = 0;
2147 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2148 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2153 if (free_enough >= 2) {
2154 /* use RR selection process, ensuring that the one
2158 i = last_rr_session_dir;
2161 if (++i == session_dirs.end()) {
2162 i = session_dirs.begin();
2165 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2166 if (create_session_directory ((*i).path)) {
2168 last_rr_session_dir = i;
2173 } while (i != last_rr_session_dir);
2177 /* pick FS with the most freespace (and that
2178 seems to actually work ...)
2181 vector<space_and_path> sorted;
2182 space_and_path_ascending_cmp cmp;
2184 sorted = session_dirs;
2185 sort (sorted.begin(), sorted.end(), cmp);
2187 for (i = sorted.begin(); i != sorted.end(); ++i) {
2188 if (create_session_directory ((*i).path)) {
2190 last_rr_session_dir = i;
2200 Session::load_named_selections (const XMLNode& node)
2203 XMLNodeConstIterator niter;
2206 nlist = node.children();
2210 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2212 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2213 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2221 Session::XMLNamedSelectionFactory (const XMLNode& node)
2224 return new NamedSelection (*this, node);
2227 catch (failed_constructor& err) {
2233 Session::automation_dir () const
2235 return Glib::build_filename (_path, "automation");
2239 Session::analysis_dir () const
2241 return Glib::build_filename (_path, "analysis");
2245 Session::plugins_dir () const
2247 return Glib::build_filename (_path, "plugins");
2251 Session::externals_dir () const
2253 return Glib::build_filename (_path, "externals");
2257 Session::load_bundles (XMLNode const & node)
2259 XMLNodeList nlist = node.children();
2260 XMLNodeConstIterator niter;
2264 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2265 if ((*niter)->name() == "InputBundle") {
2266 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2267 } else if ((*niter)->name() == "OutputBundle") {
2268 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2270 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2279 Session::load_route_groups (const XMLNode& node, int version)
2281 XMLNodeList nlist = node.children();
2282 XMLNodeConstIterator niter;
2286 if (version >= 3000) {
2288 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2289 if ((*niter)->name() == "RouteGroup") {
2290 RouteGroup* rg = new RouteGroup (*this, "");
2291 add_route_group (rg);
2292 rg->set_state (**niter, version);
2296 } else if (version < 3000) {
2298 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2299 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2300 RouteGroup* rg = new RouteGroup (*this, "");
2301 add_route_group (rg);
2302 rg->set_state (**niter, version);
2311 Session::auto_save()
2313 save_state (_current_snapshot_name);
2317 state_file_filter (const string &str, void */*arg*/)
2319 return (str.length() > strlen(statefile_suffix) &&
2320 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2324 bool operator()(const string* a, const string* b) {
2330 remove_end(string* state)
2332 string statename(*state);
2334 string::size_type start,end;
2335 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2336 statename = statename.substr (start+1);
2339 if ((end = statename.rfind(".ardour")) == string::npos) {
2340 end = statename.length();
2343 return new string(statename.substr (0, end));
2347 Session::possible_states (string path)
2349 PathScanner scanner;
2350 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2352 transform(states->begin(), states->end(), states->begin(), remove_end);
2355 sort (states->begin(), states->end(), cmp);
2361 Session::possible_states () const
2363 return possible_states(_path);
2367 Session::add_route_group (RouteGroup* g)
2369 _route_groups.push_back (g);
2370 route_group_added (g); /* EMIT SIGNAL */
2372 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2373 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2374 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2380 Session::remove_route_group (RouteGroup& rg)
2382 list<RouteGroup*>::iterator i;
2384 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2385 _route_groups.erase (i);
2388 route_group_removed (); /* EMIT SIGNAL */
2392 /** Set a new order for our route groups, without adding or removing any.
2393 * @param groups Route group list in the new order.
2396 Session::reorder_route_groups (list<RouteGroup*> groups)
2398 _route_groups = groups;
2400 route_groups_reordered (); /* EMIT SIGNAL */
2406 Session::route_group_by_name (string name)
2408 list<RouteGroup *>::iterator i;
2410 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2411 if ((*i)->name() == name) {
2419 Session::all_route_group() const
2421 return *_all_route_group;
2425 Session::add_commands (vector<Command*> const & cmds)
2427 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2433 Session::begin_reversible_command (const string& name)
2435 begin_reversible_command (g_quark_from_string (name.c_str ()));
2438 /** Begin a reversible command using a GQuark to identify it.
2439 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2440 * but there must be as many begin...()s as there are commit...()s.
2443 Session::begin_reversible_command (GQuark q)
2445 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2446 to hold all the commands that are committed. This keeps the order of
2447 commands correct in the history.
2450 if (_current_trans == 0) {
2451 /* start a new transaction */
2452 assert (_current_trans_quarks.empty ());
2453 _current_trans = new UndoTransaction();
2454 _current_trans->set_name (g_quark_to_string (q));
2457 _current_trans_quarks.push_front (q);
2461 Session::commit_reversible_command (Command *cmd)
2463 assert (_current_trans);
2464 assert (!_current_trans_quarks.empty ());
2469 _current_trans->add_command (cmd);
2472 _current_trans_quarks.pop_front ();
2474 if (!_current_trans_quarks.empty ()) {
2475 /* the transaction we're committing is not the top-level one */
2479 if (_current_trans->empty()) {
2480 /* no commands were added to the transaction, so just get rid of it */
2481 delete _current_trans;
2486 gettimeofday (&now, 0);
2487 _current_trans->set_timestamp (now);
2489 _history.add (_current_trans);
2494 accept_all_audio_files (const string& path, void */*arg*/)
2496 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2500 if (!AudioFileSource::safe_audio_file_extension (path)) {
2508 accept_all_midi_files (const string& path, void */*arg*/)
2510 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2514 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2515 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2516 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2520 accept_all_state_files (const string& path, void */*arg*/)
2522 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2526 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2530 Session::find_all_sources (string path, set<string>& result)
2535 if (!tree.read (path)) {
2539 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2544 XMLNodeConstIterator niter;
2546 nlist = node->children();
2550 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2554 if ((prop = (*niter)->property (X_("type"))) == 0) {
2558 DataType type (prop->value());
2560 if ((prop = (*niter)->property (X_("name"))) == 0) {
2564 if (Glib::path_is_absolute (prop->value())) {
2565 /* external file, ignore */
2573 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2574 result.insert (found_path);
2582 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2584 PathScanner scanner;
2585 vector<string*>* state_files;
2587 string this_snapshot_path;
2593 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2594 ripped = ripped.substr (0, ripped.length() - 1);
2597 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2599 if (state_files == 0) {
2604 this_snapshot_path = _path;
2605 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2606 this_snapshot_path += statefile_suffix;
2608 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2610 if (exclude_this_snapshot && **i == this_snapshot_path) {
2614 if (find_all_sources (**i, result) < 0) {
2622 struct RegionCounter {
2623 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2624 AudioSourceList::iterator iter;
2625 boost::shared_ptr<Region> region;
2628 RegionCounter() : count (0) {}
2632 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2634 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2635 return r.get_value_or (1);
2639 Session::cleanup_regions ()
2641 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2643 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2645 uint32_t used = playlists->region_use_count (i->second);
2647 if (used == 0 && !i->second->automatic ()) {
2648 RegionFactory::map_remove (i->second);
2652 /* dump the history list */
2659 Session::cleanup_sources (CleanupReport& rep)
2661 // FIXME: needs adaptation to midi
2663 vector<boost::shared_ptr<Source> > dead_sources;
2664 PathScanner scanner;
2667 vector<space_and_path>::iterator i;
2668 vector<space_and_path>::iterator nexti;
2669 vector<string*>* candidates;
2670 vector<string*>* candidates2;
2671 vector<string> unused;
2672 set<string> all_sources;
2677 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2679 /* consider deleting all unused playlists */
2681 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2686 /* sync the "all regions" property of each playlist with its current state
2689 playlists->sync_all_regions_with_regions ();
2691 /* find all un-used sources */
2696 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2698 SourceMap::iterator tmp;
2703 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2707 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2708 dead_sources.push_back (i->second);
2709 i->second->drop_references ();
2715 /* build a list of all the possible audio directories for the session */
2717 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2722 SessionDirectory sdir ((*i).path);
2723 audio_path += sdir.sound_path().to_string();
2725 if (nexti != session_dirs.end()) {
2733 /* build a list of all the possible midi directories for the session */
2735 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2740 SessionDirectory sdir ((*i).path);
2741 midi_path += sdir.midi_path().to_string();
2743 if (nexti != session_dirs.end()) {
2750 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2751 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2757 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2758 candidates->push_back (*i);
2763 candidates = candidates2; // might still be null
2766 /* find all sources, but don't use this snapshot because the
2767 state file on disk still references sources we may have already
2771 find_all_sources_across_snapshots (all_sources, true);
2773 /* add our current source list
2776 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2777 boost::shared_ptr<FileSource> fs;
2778 SourceMap::iterator tmp = i;
2781 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2782 if (playlists->source_use_count (fs) != 0) {
2783 all_sources.insert (fs->path());
2786 /* we might not remove this source from disk, because it may be used
2787 by other snapshots, but its not being used in this version
2788 so lets get rid of it now, along with any representative regions
2792 RegionFactory::remove_regions_using_source (i->second);
2800 char tmppath1[PATH_MAX+1];
2801 char tmppath2[PATH_MAX+1];
2804 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2809 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2811 if (realpath(spath.c_str(), tmppath1) == 0) {
2812 error << string_compose (_("Cannot expand path %1 (%2)"),
2813 spath, strerror (errno)) << endmsg;
2817 if (realpath((*i).c_str(), tmppath2) == 0) {
2818 error << string_compose (_("Cannot expand path %1 (%2)"),
2819 (*i), strerror (errno)) << endmsg;
2823 if (strcmp(tmppath1, tmppath2) == 0) {
2830 unused.push_back (spath);
2839 /* now try to move all unused files into the "dead" directory(ies) */
2841 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2842 struct stat statbuf;
2846 /* don't move the file across filesystems, just
2847 stick it in the `dead_dir_name' directory
2848 on whichever filesystem it was already on.
2851 if ((*x).find ("/sounds/") != string::npos) {
2853 /* old school, go up 1 level */
2855 newpath = Glib::path_get_dirname (*x); // "sounds"
2856 newpath = Glib::path_get_dirname (newpath); // "session-name"
2860 /* new school, go up 4 levels */
2862 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2863 newpath = Glib::path_get_dirname (newpath); // "session-name"
2864 newpath = Glib::path_get_dirname (newpath); // "interchange"
2865 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2868 newpath = Glib::build_filename (newpath, dead_dir_name);
2870 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2871 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2875 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2877 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2879 /* the new path already exists, try versioning */
2881 char buf[PATH_MAX+1];
2885 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2888 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2889 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2893 if (version == 999) {
2894 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2898 newpath = newpath_v;
2903 /* it doesn't exist, or we can't read it or something */
2907 stat ((*x).c_str(), &statbuf);
2909 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2910 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2911 (*x), newpath, strerror (errno))
2916 /* see if there an easy to find peakfile for this file, and remove it.
2919 string base = basename_nosuffix (*x);
2920 base += "%A"; /* this is what we add for the channel suffix of all native files,
2921 or for the first channel of embedded files. it will miss
2922 some peakfiles for other channels
2924 string peakpath = peak_path (base);
2926 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2927 if (::unlink (peakpath.c_str()) != 0) {
2928 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2929 peakpath, _path, strerror (errno))
2931 /* try to back out */
2932 ::rename (newpath.c_str(), _path.c_str());
2937 rep.paths.push_back (*x);
2938 rep.space += statbuf.st_size;
2941 /* dump the history list */
2945 /* save state so we don't end up a session file
2946 referring to non-existent sources.
2953 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2959 Session::cleanup_trash_sources (CleanupReport& rep)
2961 // FIXME: needs adaptation for MIDI
2963 vector<space_and_path>::iterator i;
2969 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2971 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2973 clear_directory (dead_dir, &rep.space, &rep.paths);
2980 Session::set_dirty ()
2982 bool was_dirty = dirty();
2984 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2988 DirtyChanged(); /* EMIT SIGNAL */
2994 Session::set_clean ()
2996 bool was_dirty = dirty();
2998 _state_of_the_state = Clean;
3002 DirtyChanged(); /* EMIT SIGNAL */
3007 Session::set_deletion_in_progress ()
3009 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3013 Session::clear_deletion_in_progress ()
3015 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3019 Session::add_controllable (boost::shared_ptr<Controllable> c)
3021 /* this adds a controllable to the list managed by the Session.
3022 this is a subset of those managed by the Controllable class
3023 itself, and represents the only ones whose state will be saved
3024 as part of the session.
3027 Glib::Mutex::Lock lm (controllables_lock);
3028 controllables.insert (c);
3031 struct null_deleter { void operator()(void const *) const {} };
3034 Session::remove_controllable (Controllable* c)
3036 if (_state_of_the_state & Deletion) {
3040 Glib::Mutex::Lock lm (controllables_lock);
3042 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3044 if (x != controllables.end()) {
3045 controllables.erase (x);
3049 boost::shared_ptr<Controllable>
3050 Session::controllable_by_id (const PBD::ID& id)
3052 Glib::Mutex::Lock lm (controllables_lock);
3054 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3055 if ((*i)->id() == id) {
3060 return boost::shared_ptr<Controllable>();
3063 boost::shared_ptr<Controllable>
3064 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3066 boost::shared_ptr<Controllable> c;
3067 boost::shared_ptr<Route> r;
3069 switch (desc.top_level_type()) {
3070 case ControllableDescriptor::NamedRoute:
3072 std::string str = desc.top_level_name();
3073 if (str == "master") {
3075 } else if (str == "control" || str == "listen") {
3078 r = route_by_name (desc.top_level_name());
3083 case ControllableDescriptor::RemoteControlID:
3084 r = route_by_remote_id (desc.rid());
3092 switch (desc.subtype()) {
3093 case ControllableDescriptor::Gain:
3094 c = r->gain_control ();
3097 case ControllableDescriptor::Solo:
3098 c = r->solo_control();
3101 case ControllableDescriptor::Mute:
3102 c = r->mute_control();
3105 case ControllableDescriptor::Recenable:
3107 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3110 c = t->rec_enable_control ();
3115 case ControllableDescriptor::PanDirection:
3117 c = r->pannable()->pan_azimuth_control;
3121 case ControllableDescriptor::PanWidth:
3123 c = r->pannable()->pan_width_control;
3127 case ControllableDescriptor::PanElevation:
3129 c = r->pannable()->pan_elevation_control;
3133 case ControllableDescriptor::Balance:
3134 /* XXX simple pan control */
3137 case ControllableDescriptor::PluginParameter:
3139 uint32_t plugin = desc.target (0);
3140 uint32_t parameter_index = desc.target (1);
3142 /* revert to zero based counting */
3148 if (parameter_index > 0) {
3152 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3155 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3156 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3161 case ControllableDescriptor::SendGain:
3163 uint32_t send = desc.target (0);
3165 /* revert to zero-based counting */
3171 boost::shared_ptr<Processor> p = r->nth_send (send);
3174 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3175 boost::shared_ptr<Amp> a = s->amp();
3178 c = s->amp()->gain_control();
3185 /* relax and return a null pointer */
3193 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3196 Stateful::add_instant_xml (node, _path);
3199 if (write_to_config) {
3200 Config->add_instant_xml (node);
3205 Session::instant_xml (const string& node_name)
3207 return Stateful::instant_xml (node_name, _path);
3211 Session::save_history (string snapshot_name)
3219 if (snapshot_name.empty()) {
3220 snapshot_name = _current_snapshot_name;
3223 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3224 const string backup_filename = history_filename + backup_suffix;
3225 const sys::path xml_path = _session_dir->root_path() / history_filename;
3226 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3228 if (sys::exists (xml_path)) {
3231 sys::rename (xml_path, backup_path);
3233 catch (const sys::filesystem_error& err)
3235 error << _("could not backup old history file, current history not saved") << endmsg;
3240 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3244 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3246 if (!tree.write (xml_path.to_string()))
3248 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3252 sys::remove (xml_path);
3253 sys::rename (backup_path, xml_path);
3255 catch (const sys::filesystem_error& err)
3257 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3258 backup_path.to_string(), err.what()) << endmsg;
3268 Session::restore_history (string snapshot_name)
3272 if (snapshot_name.empty()) {
3273 snapshot_name = _current_snapshot_name;
3276 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3277 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3279 info << "Loading history from " << xml_path.to_string() << endmsg;
3281 if (!sys::exists (xml_path)) {
3282 info << string_compose (_("%1: no history file \"%2\" for this session."),
3283 _name, xml_path.to_string()) << endmsg;
3287 if (!tree.read (xml_path.to_string())) {
3288 error << string_compose (_("Could not understand session history file \"%1\""),
3289 xml_path.to_string()) << endmsg;
3296 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3299 UndoTransaction* ut = new UndoTransaction ();
3302 ut->set_name(t->property("name")->value());
3303 stringstream ss(t->property("tv-sec")->value());
3305 ss.str(t->property("tv-usec")->value());
3307 ut->set_timestamp(tv);
3309 for (XMLNodeConstIterator child_it = t->children().begin();
3310 child_it != t->children().end(); child_it++)
3312 XMLNode *n = *child_it;
3315 if (n->name() == "MementoCommand" ||
3316 n->name() == "MementoUndoCommand" ||
3317 n->name() == "MementoRedoCommand") {
3319 if ((c = memento_command_factory(n))) {
3323 } else if (n->name() == "NoteDiffCommand") {
3324 PBD::ID id (n->property("midi-source")->value());
3325 boost::shared_ptr<MidiSource> midi_source =
3326 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3328 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3330 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3333 } else if (n->name() == "SysExDiffCommand") {
3335 PBD::ID id (n->property("midi-source")->value());
3336 boost::shared_ptr<MidiSource> midi_source =
3337 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3339 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3341 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3344 } else if (n->name() == "PatchChangeDiffCommand") {
3346 PBD::ID id (n->property("midi-source")->value());
3347 boost::shared_ptr<MidiSource> midi_source =
3348 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3350 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3352 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3355 } else if (n->name() == "StatefulDiffCommand") {
3356 if ((c = stateful_diff_command_factory (n))) {
3357 ut->add_command (c);
3360 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3371 Session::config_changed (std::string p, bool ours)
3377 if (p == "seamless-loop") {
3379 } else if (p == "rf-speed") {
3381 } else if (p == "auto-loop") {
3383 } else if (p == "auto-input") {
3385 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3386 /* auto-input only makes a difference if we're rolling */
3387 set_track_monitor_input_status (!config.get_auto_input());
3390 } else if (p == "punch-in") {
3394 if ((location = _locations->auto_punch_location()) != 0) {
3396 if (config.get_punch_in ()) {
3397 replace_event (SessionEvent::PunchIn, location->start());
3399 remove_event (location->start(), SessionEvent::PunchIn);
3403 } else if (p == "punch-out") {
3407 if ((location = _locations->auto_punch_location()) != 0) {
3409 if (config.get_punch_out()) {
3410 replace_event (SessionEvent::PunchOut, location->end());
3412 clear_events (SessionEvent::PunchOut);
3416 } else if (p == "edit-mode") {
3418 Glib::Mutex::Lock lm (playlists->lock);
3420 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3421 (*i)->set_edit_mode (Config->get_edit_mode ());
3424 } else if (p == "use-video-sync") {
3426 waiting_for_sync_offset = config.get_use_video_sync();
3428 } else if (p == "mmc-control") {
3430 //poke_midi_thread ();
3432 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3434 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3436 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3438 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3440 } else if (p == "midi-control") {
3442 //poke_midi_thread ();
3444 } else if (p == "raid-path") {
3446 setup_raid_path (config.get_raid_path());
3448 } else if (p == "timecode-format") {
3452 } else if (p == "video-pullup") {
3456 } else if (p == "seamless-loop") {
3458 if (play_loop && transport_rolling()) {
3459 // to reset diskstreams etc
3460 request_play_loop (true);
3463 } else if (p == "rf-speed") {
3465 cumulative_rf_motion = 0;
3468 } else if (p == "click-sound") {
3470 setup_click_sounds (1);
3472 } else if (p == "click-emphasis-sound") {
3474 setup_click_sounds (-1);
3476 } else if (p == "clicking") {
3478 if (Config->get_clicking()) {
3479 if (_click_io && click_data) { // don't require emphasis data
3486 } else if (p == "click-gain") {
3489 _click_gain->set_gain (Config->get_click_gain(), this);
3492 } else if (p == "send-mtc") {
3494 if (Config->get_send_mtc ()) {
3495 /* mark us ready to send */
3496 next_quarter_frame_to_send = 0;
3499 } else if (p == "send-mmc") {
3501 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3503 } else if (p == "midi-feedback") {
3505 session_midi_feedback = Config->get_midi_feedback();
3507 } else if (p == "jack-time-master") {
3509 engine().reset_timebase ();
3511 } else if (p == "native-file-header-format") {
3513 if (!first_file_header_format_reset) {
3514 reset_native_file_format ();
3517 first_file_header_format_reset = false;
3519 } else if (p == "native-file-data-format") {
3521 if (!first_file_data_format_reset) {
3522 reset_native_file_format ();
3525 first_file_data_format_reset = false;
3527 } else if (p == "external-sync") {
3528 if (!config.get_external_sync()) {
3529 drop_sync_source ();
3531 switch_to_sync_source (config.get_sync_source());
3533 } else if (p == "remote-model") {
3534 set_remote_control_ids ();
3535 } else if (p == "denormal-model") {
3537 } else if (p == "history-depth") {
3538 set_history_depth (Config->get_history_depth());
3539 } else if (p == "sync-all-route-ordering") {
3540 sync_order_keys ("session");
3541 } else if (p == "initial-program-change") {
3543 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3546 buf[0] = MIDI::program; // channel zero by default
3547 buf[1] = (Config->get_initial_program_change() & 0x7f);
3549 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3551 } else if (p == "solo-mute-override") {
3552 // catch_up_on_solo_mute_override ();
3553 } else if (p == "listen-position" || p == "pfl-position") {
3554 listen_position_changed ();
3555 } else if (p == "solo-control-is-listen-control") {
3556 solo_control_mode_changed ();
3557 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3558 last_timecode_valid = false;
3559 } else if (p == "playback-buffer-seconds") {
3560 AudioSource::allocate_working_buffers (frame_rate());
3561 } else if (p == "automation-thinning-factor") {
3562 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3569 Session::set_history_depth (uint32_t d)
3571 _history.set_depth (d);
3575 Session::load_diskstreams_2X (XMLNode const & node, int)
3578 XMLNodeConstIterator citer;
3580 clist = node.children();
3582 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3585 /* diskstreams added automatically by DiskstreamCreated handler */
3586 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3587 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3588 _diskstreams_2X.push_back (dsp);
3590 error << _("Session: unknown diskstream type in XML") << endmsg;
3594 catch (failed_constructor& err) {
3595 error << _("Session: could not load diskstream via XML state") << endmsg;
3603 /** Connect things to the MMC object */
3605 Session::setup_midi_machine_control ()
3607 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3609 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3610 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3611 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3612 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3613 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3614 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3615 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3616 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3617 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3618 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3619 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3620 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3621 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3623 /* also handle MIDI SPP because its so common */
3625 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3626 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3627 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3630 boost::shared_ptr<Controllable>
3631 Session::solo_cut_control() const
3633 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3634 controls in Ardour that currently get presented to the user in the GUI that require
3635 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3637 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3638 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3642 return _solo_cut_control;
3646 Session::rename (const std::string& new_name)
3648 string legal_name = legalize_for_path (new_name);
3654 string const old_sources_root = _session_dir->sources_root().to_string ();
3656 #define RENAME ::rename
3661 * interchange subdirectory
3665 * Backup files are left unchanged and not renamed.
3668 /* pass one: not 100% safe check that the new directory names don't
3672 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3677 /* this is a stupid hack because Glib::path_get_dirname() is
3678 * lexical-only, and so passing it /a/b/c/ gives a different
3679 * result than passing it /a/b/c ...
3682 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3683 oldstr = oldstr.substr (0, oldstr.length() - 1);
3686 string base = Glib::path_get_dirname (oldstr);
3687 string p = Glib::path_get_basename (oldstr);
3689 newstr = Glib::build_filename (base, legal_name);
3691 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3698 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3703 /* this is a stupid hack because Glib::path_get_dirname() is
3704 * lexical-only, and so passing it /a/b/c/ gives a different
3705 * result than passing it /a/b/c ...
3708 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3709 oldstr = oldstr.substr (0, oldstr.length() - 1);
3712 string base = Glib::path_get_dirname (oldstr);
3713 string p = Glib::path_get_basename (oldstr);
3715 newstr = Glib::build_filename (base, legal_name);
3717 cerr << "Rename " << oldstr << " => " << newstr << endl;
3719 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3724 (*_session_dir) = newstr;
3729 /* directory below interchange */
3731 v.push_back (newstr);
3732 v.push_back (interchange_dir_name);
3735 oldstr = Glib::build_filename (v);
3738 v.push_back (newstr);
3739 v.push_back (interchange_dir_name);
3740 v.push_back (legal_name);
3742 newstr = Glib::build_filename (v);
3744 cerr << "Rename " << oldstr << " => " << newstr << endl;
3746 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3753 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3754 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3756 cerr << "Rename " << oldstr << " => " << newstr << endl;
3758 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3765 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3767 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3768 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3770 cerr << "Rename " << oldstr << " => " << newstr << endl;
3772 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3777 /* update file source paths */
3779 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3780 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3782 string p = fs->path ();
3783 boost::replace_all (p, old_sources_root, _session_dir->sources_root().to_string ());
3788 /* remove old name from recent sessions */
3790 remove_recent_sessions (_path);
3793 _current_snapshot_name = new_name;
3798 /* save state again to get everything just right */
3800 save_state (_current_snapshot_name);
3803 /* add to recent sessions */
3805 store_recent_sessions (new_name, _path);