2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "libardour-config.h"
33 #include <cstdio> /* snprintf(3) ... grrr */
47 #include <sys/param.h>
48 #include <sys/mount.h>
54 #include <glibmm/thread.h>
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_patch_manager.h"
94 #include "ardour/midi_playlist.h"
95 #include "ardour/midi_region.h"
96 #include "ardour/midi_source.h"
97 #include "ardour/midi_track.h"
98 #include "ardour/named_selection.h"
99 #include "ardour/pannable.h"
100 #include "ardour/processor.h"
101 #include "ardour/port.h"
102 #include "ardour/proxy_controllable.h"
103 #include "ardour/recent_sessions.h"
104 #include "ardour/region_factory.h"
105 #include "ardour/route_group.h"
106 #include "ardour/send.h"
107 #include "ardour/session.h"
108 #include "ardour/session_directory.h"
109 #include "ardour/session_metadata.h"
110 #include "ardour/session_state_utils.h"
111 #include "ardour/session_playlists.h"
112 #include "ardour/session_utils.h"
113 #include "ardour/silentfilesource.h"
114 #include "ardour/slave.h"
115 #include "ardour/smf_source.h"
116 #include "ardour/sndfile_helpers.h"
117 #include "ardour/sndfilesource.h"
118 #include "ardour/source_factory.h"
119 #include "ardour/template_utils.h"
120 #include "ardour/tempo.h"
121 #include "ardour/ticker.h"
122 #include "ardour/user_bundle.h"
123 #include "ardour/utils.h"
124 #include "ardour/utils.h"
125 #include "ardour/version.h"
126 #include "ardour/playlist_factory.h"
128 #include "control_protocol/control_protocol.h"
134 using namespace ARDOUR;
137 /** @param snapshot_name Snapshot name, without the .ardour prefix */
139 Session::first_stage_init (string fullpath, string snapshot_name)
141 if (fullpath.length() == 0) {
143 throw failed_constructor();
146 char buf[PATH_MAX+1];
147 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
148 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
150 throw failed_constructor();
155 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
156 _path += G_DIR_SEPARATOR;
159 /* these two are just provisional settings. set_state()
160 will likely override them.
163 _name = _current_snapshot_name = snapshot_name;
165 set_history_depth (Config->get_history_depth());
167 _current_frame_rate = _engine.frame_rate ();
168 _nominal_frame_rate = _current_frame_rate;
169 _base_frame_rate = _current_frame_rate;
171 _tempo_map = new TempoMap (_current_frame_rate);
172 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
175 _non_soloed_outs_muted = false;
177 _solo_isolated_cnt = 0;
178 g_atomic_int_set (&processing_prohibited, 0);
179 _transport_speed = 0;
180 _last_transport_speed = 0;
181 _target_transport_speed = 0;
182 auto_play_legal = false;
183 transport_sub_state = 0;
184 _transport_frame = 0;
185 _requested_return_frame = -1;
186 _session_range_location = 0;
187 g_atomic_int_set (&_record_status, Disabled);
188 loop_changing = false;
191 _last_roll_location = 0;
192 _last_roll_or_reversal_location = 0;
193 _last_record_location = 0;
194 pending_locate_frame = 0;
195 pending_locate_roll = false;
196 pending_locate_flush = false;
197 state_was_pending = false;
199 outbound_mtc_timecode_frame = 0;
200 next_quarter_frame_to_send = -1;
201 current_block_size = 0;
202 solo_update_disabled = false;
203 _have_captured = false;
204 _worst_output_latency = 0;
205 _worst_input_latency = 0;
206 _worst_track_latency = 0;
207 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
208 _was_seamless = Config->get_seamless_loop ();
210 _send_qf_mtc = false;
211 _pframes_since_last_mtc = 0;
212 g_atomic_int_set (&_playback_load, 100);
213 g_atomic_int_set (&_capture_load, 100);
216 pending_abort = false;
217 destructive_index = 0;
218 first_file_data_format_reset = true;
219 first_file_header_format_reset = true;
220 post_export_sync = false;
223 no_questions_about_missing_files = false;
224 _speakers.reset (new Speakers);
226 AudioDiskstream::allocate_working_buffers();
228 /* default short fade = 15ms */
230 Crossfade::set_short_xfade_length ((framecnt_t) floor (config.get_short_xfade_seconds() * frame_rate()));
231 SndFileSource::setup_standard_crossfades (*this, frame_rate());
233 last_mmc_step.tv_sec = 0;
234 last_mmc_step.tv_usec = 0;
237 /* click sounds are unset by default, which causes us to internal
238 waveforms for clicks.
242 click_emphasis_length = 0;
245 process_function = &Session::process_with_events;
247 if (config.get_use_video_sync()) {
248 waiting_for_sync_offset = true;
250 waiting_for_sync_offset = false;
253 last_timecode_when = 0;
254 last_timecode_valid = false;
258 last_rr_session_dir = session_dirs.begin();
259 refresh_disk_space ();
261 /* default: assume simple stereo speaker configuration */
263 _speakers->setup_default_speakers (2);
267 average_slave_delta = 1800; // !!! why 1800 ????
268 have_first_delta_accumulator = false;
269 delta_accumulator_cnt = 0;
270 _slave_state = Stopped;
272 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
273 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
274 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
275 add_controllable (_solo_cut_control);
277 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
279 /* These are all static "per-class" signals */
281 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
282 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
283 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
284 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
285 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
287 /* stop IO objects from doing stuff until we're ready for them */
289 Delivery::disable_panners ();
290 IO::disable_connecting ();
294 Session::second_stage_init ()
296 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
299 if (load_state (_current_snapshot_name)) {
304 if (_butler->start_thread()) {
308 if (start_midi_thread ()) {
312 setup_midi_machine_control ();
314 // set_state() will call setup_raid_path(), but if it's a new session we need
315 // to call setup_raid_path() here.
318 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
322 setup_raid_path(_path);
325 /* we can't save till after ::when_engine_running() is called,
326 because otherwise we save state with no connections made.
327 therefore, we reset _state_of_the_state because ::set_state()
328 will have cleared it.
330 we also have to include Loading so that any events that get
331 generated between here and the end of ::when_engine_running()
332 will be processed directly rather than queued.
335 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
337 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
338 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
339 setup_click_sounds (0);
340 setup_midi_control ();
342 /* Pay attention ... */
344 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
345 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
348 when_engine_running ();
351 /* handle this one in a different way than all others, so that its clear what happened */
353 catch (AudioEngine::PortRegistrationFailure& err) {
354 error << err.what() << endmsg;
362 BootMessage (_("Reset Remote Controls"));
364 send_full_time_code (0);
365 _engine.transport_locate (0);
367 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
368 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
370 MidiClockTicker::instance().set_session (this);
371 MIDI::Name::MidiPatchManager::instance().set_session (this);
373 /* initial program change will be delivered later; see ::config_changed() */
375 _state_of_the_state = Clean;
377 Port::set_connecting_blocked (false);
379 DirtyChanged (); /* EMIT SIGNAL */
381 if (state_was_pending) {
382 save_state (_current_snapshot_name);
383 remove_pending_capture_state ();
384 state_was_pending = false;
387 BootMessage (_("Session loading complete"));
393 Session::raid_path () const
395 SearchPath raid_search_path;
397 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
398 raid_search_path += sys::path((*i).path);
401 return raid_search_path.to_string ();
405 Session::setup_raid_path (string path)
414 session_dirs.clear ();
416 SearchPath search_path(path);
417 SearchPath sound_search_path;
418 SearchPath midi_search_path;
420 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
421 sp.path = (*i).to_string ();
422 sp.blocks = 0; // not needed
423 session_dirs.push_back (sp);
425 SessionDirectory sdir(sp.path);
427 sound_search_path += sdir.sound_path ();
428 midi_search_path += sdir.midi_path ();
431 // reset the round-robin soundfile path thingie
432 last_rr_session_dir = session_dirs.begin();
436 Session::path_is_within_session (const std::string& path)
438 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
439 if (path.find ((*i).path) == 0) {
447 Session::ensure_subdirs ()
451 dir = session_directory().peak_path().to_string();
453 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
454 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
458 dir = session_directory().sound_path().to_string();
460 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
461 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
465 dir = session_directory().midi_path().to_string();
467 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
468 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
472 dir = session_directory().dead_path().to_string();
474 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
475 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
479 dir = session_directory().export_path().to_string();
481 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
482 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
486 dir = analysis_dir ();
488 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
489 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
493 dir = plugins_dir ();
495 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
496 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
503 /** Caller must not hold process lock */
505 Session::create (const string& mix_template, BusProfile* bus_profile)
507 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
508 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
512 if (ensure_subdirs ()) {
516 _writable = exists_and_writable (sys::path (_path));
518 if (!mix_template.empty()) {
519 std::string in_path = mix_template;
521 ifstream in(in_path.c_str());
524 string out_path = _path;
526 out_path += statefile_suffix;
528 ofstream out(out_path.c_str());
536 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
542 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
549 /* Instantiate metadata */
551 _metadata = new SessionMetadata ();
553 /* set initial start + end point */
555 _state_of_the_state = Clean;
557 /* set up Master Out and Control Out if necessary */
563 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
565 if (bus_profile->master_out_channels) {
566 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
570 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
571 boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
574 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
575 r->input()->ensure_io (count, false, this);
576 r->output()->ensure_io (count, false, this);
578 r->set_remote_control_id (control_id++);
582 if (Config->get_use_monitor_bus()) {
583 boost::shared_ptr<Route> r (new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO));
587 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
588 boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
591 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
592 r->input()->ensure_io (count, false, this);
593 r->output()->ensure_io (count, false, this);
595 r->set_remote_control_id (control_id);
601 /* prohibit auto-connect to master, because there isn't one */
602 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
606 add_routes (rl, false, false);
609 /* this allows the user to override settings with an environment variable.
612 if (no_auto_connect()) {
613 bus_profile->input_ac = AutoConnectOption (0);
614 bus_profile->output_ac = AutoConnectOption (0);
617 Config->set_input_auto_connect (bus_profile->input_ac);
618 Config->set_output_auto_connect (bus_profile->output_ac);
627 Session::maybe_write_autosave()
629 if (dirty() && record_status() != Recording) {
630 save_state("", true);
635 Session::remove_pending_capture_state ()
637 sys::path pending_state_file_path(_session_dir->root_path());
639 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
643 sys::remove (pending_state_file_path);
645 catch(sys::filesystem_error& ex)
647 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
648 pending_state_file_path.to_string(), ex.what()) << endmsg;
652 /** Rename a state file.
653 * @param old_name Old snapshot name.
654 * @param new_name New snapshot name.
657 Session::rename_state (string old_name, string new_name)
659 if (old_name == _current_snapshot_name || old_name == _name) {
660 /* refuse to rename the current snapshot or the "main" one */
664 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
665 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
667 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
668 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
672 sys::rename (old_xml_path, new_xml_path);
674 catch (const sys::filesystem_error& err)
676 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
677 old_name, new_name, err.what()) << endmsg;
681 /** Remove a state file.
682 * @param snapshot_name Snapshot name.
685 Session::remove_state (string snapshot_name)
687 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
688 // refuse to remove the current snapshot or the "main" one
692 sys::path xml_path(_session_dir->root_path());
694 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
696 if (!create_backup_file (xml_path)) {
697 // don't remove it if a backup can't be made
698 // create_backup_file will log the error.
703 sys::remove (xml_path);
706 #ifdef HAVE_JACK_SESSION
708 Session::jack_session_event (jack_session_event_t * event)
712 struct tm local_time;
715 localtime_r (&n, &local_time);
716 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
718 if (event->type == JackSessionSaveTemplate)
720 if (save_template( timebuf )) {
721 event->flags = JackSessionSaveError;
723 string cmd ("ardour3 -P -U ");
724 cmd += event->client_uuid;
728 event->command_line = strdup (cmd.c_str());
733 if (save_state (timebuf)) {
734 event->flags = JackSessionSaveError;
736 sys::path xml_path (_session_dir->root_path());
737 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
739 string cmd ("ardour3 -P -U ");
740 cmd += event->client_uuid;
742 cmd += xml_path.to_string();
745 event->command_line = strdup (cmd.c_str());
749 jack_session_reply (_engine.jack(), event);
751 if (event->type == JackSessionSaveAndQuit) {
752 Quit (); /* EMIT SIGNAL */
755 jack_session_event_free( event );
759 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
761 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
764 sys::path xml_path(_session_dir->root_path());
766 if (!_writable || (_state_of_the_state & CannotSave)) {
770 if (!_engine.connected ()) {
771 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
777 /* tell sources we're saving first, in case they write out to a new file
778 * which should be saved with the state rather than the old one */
779 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
780 i->second->session_saved();
783 tree.set_root (&get_state());
785 if (snapshot_name.empty()) {
786 snapshot_name = _current_snapshot_name;
787 } else if (switch_to_snapshot) {
788 _current_snapshot_name = snapshot_name;
793 /* proper save: use statefile_suffix (.ardour in English) */
795 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
797 /* make a backup copy of the old file */
799 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
800 // create_backup_file will log the error
806 /* pending save: use pending_suffix (.pending in English) */
807 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
810 sys::path tmp_path(_session_dir->root_path());
812 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
814 // cerr << "actually writing state to " << xml_path.to_string() << endl;
816 if (!tree.write (tmp_path.to_string())) {
817 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
818 sys::remove (tmp_path);
823 if (::rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
824 error << string_compose (_("could not rename temporary session file %1 to %2"),
825 tmp_path.to_string(), xml_path.to_string()) << endmsg;
826 sys::remove (tmp_path);
833 save_history (snapshot_name);
835 bool was_dirty = dirty();
837 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
840 DirtyChanged (); /* EMIT SIGNAL */
843 StateSaved (snapshot_name); /* EMIT SIGNAL */
850 Session::restore_state (string snapshot_name)
852 if (load_state (snapshot_name) == 0) {
853 set_state (*state_tree->root(), Stateful::loading_state_version);
860 Session::load_state (string snapshot_name)
865 state_was_pending = false;
867 /* check for leftover pending state from a crashed capture attempt */
869 sys::path xmlpath(_session_dir->root_path());
870 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
872 if (sys::exists (xmlpath)) {
874 /* there is pending state from a crashed capture attempt */
876 boost::optional<int> r = AskAboutPendingState();
877 if (r.get_value_or (1)) {
878 state_was_pending = true;
882 if (!state_was_pending) {
883 xmlpath = _session_dir->root_path();
884 xmlpath /= snapshot_name;
887 if (!sys::exists (xmlpath)) {
888 xmlpath = _session_dir->root_path();
889 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
890 if (!sys::exists (xmlpath)) {
891 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
896 state_tree = new XMLTree;
900 _writable = exists_and_writable (xmlpath);
902 if (!state_tree->read (xmlpath.to_string())) {
903 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
909 XMLNode& root (*state_tree->root());
911 if (root.name() != X_("Session")) {
912 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
918 const XMLProperty* prop;
920 if ((prop = root.property ("version")) == 0) {
921 /* no version implies very old version of Ardour */
922 Stateful::loading_state_version = 1000;
928 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
929 Stateful::loading_state_version = (major * 1000) + minor;
932 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
934 sys::path backup_path(_session_dir->root_path());
936 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
938 // only create a backup once
939 if (sys::exists (backup_path)) {
943 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
944 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
949 sys::copy_file (xmlpath, backup_path);
951 catch(sys::filesystem_error& ex)
953 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
954 xmlpath.to_string(), ex.what())
964 Session::load_options (const XMLNode& node)
966 LocaleGuard lg (X_("POSIX"));
967 config.set_variables (node);
978 Session::get_template()
980 /* if we don't disable rec-enable, diskstreams
981 will believe they need to store their capture
982 sources in their state node.
985 disable_record (false);
991 Session::state(bool full_state)
993 XMLNode* node = new XMLNode("Session");
996 // store libardour version, just in case
998 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
999 node->add_property("version", string(buf));
1001 /* store configuration settings */
1005 node->add_property ("name", _name);
1006 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1007 node->add_property ("sample-rate", buf);
1009 if (session_dirs.size() > 1) {
1013 vector<space_and_path>::iterator i = session_dirs.begin();
1014 vector<space_and_path>::iterator next;
1016 ++i; /* skip the first one */
1020 while (i != session_dirs.end()) {
1024 if (next != session_dirs.end()) {
1034 child = node->add_child ("Path");
1035 child->add_content (p);
1039 /* save the ID counter */
1041 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1042 node->add_property ("id-counter", buf);
1044 /* save the event ID counter */
1046 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1047 node->add_property ("event-counter", buf);
1049 /* various options */
1051 node->add_child_nocopy (config.get_variables ());
1053 node->add_child_nocopy (_metadata->get_state());
1055 child = node->add_child ("Sources");
1058 Glib::Mutex::Lock sl (source_lock);
1060 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1062 /* Don't save information about non-file Sources, or
1063 * about non-destructive file sources that are empty
1064 * and unused by any regions.
1067 boost::shared_ptr<FileSource> fs;
1069 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1071 if (!fs->destructive()) {
1072 if (fs->empty() && !fs->used()) {
1077 child->add_child_nocopy (siter->second->get_state());
1082 child = node->add_child ("Regions");
1085 Glib::Mutex::Lock rl (region_lock);
1086 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1087 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1088 boost::shared_ptr<Region> r = i->second;
1089 /* only store regions not attached to playlists */
1090 if (r->playlist() == 0) {
1091 child->add_child_nocopy (r->state ());
1095 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1097 if (!cassocs.empty()) {
1098 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1100 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1102 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1103 i->first->id().print (buf, sizeof (buf));
1104 can->add_property (X_("copy"), buf);
1105 i->second->id().print (buf, sizeof (buf));
1106 can->add_property (X_("original"), buf);
1107 ca->add_child_nocopy (*can);
1113 node->add_child_nocopy (_locations->get_state());
1115 // for a template, just create a new Locations, populate it
1116 // with the default start and end, and get the state for that.
1117 Locations loc (*this);
1118 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1119 range->set (max_framepos, 0);
1121 node->add_child_nocopy (loc.get_state());
1124 child = node->add_child ("Bundles");
1126 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1127 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1128 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1130 child->add_child_nocopy (b->get_state());
1135 child = node->add_child ("Routes");
1137 boost::shared_ptr<RouteList> r = routes.reader ();
1139 RoutePublicOrderSorter cmp;
1140 RouteList public_order (*r);
1141 public_order.sort (cmp);
1143 /* the sort should have put control outs first */
1146 assert (_monitor_out == public_order.front());
1149 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1150 if (!(*i)->is_hidden()) {
1152 child->add_child_nocopy ((*i)->get_state());
1154 child->add_child_nocopy ((*i)->get_template());
1160 playlists->add_state (node, full_state);
1162 child = node->add_child ("RouteGroups");
1163 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1164 child->add_child_nocopy ((*i)->get_state());
1168 child = node->add_child ("Click");
1169 child->add_child_nocopy (_click_io->state (full_state));
1173 child = node->add_child ("NamedSelections");
1174 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1176 child->add_child_nocopy ((*i)->get_state());
1181 node->add_child_nocopy (_speakers->get_state());
1182 node->add_child_nocopy (_tempo_map->get_state());
1183 node->add_child_nocopy (get_control_protocol_state());
1186 node->add_child_copy (*_extra_xml);
1193 Session::get_control_protocol_state ()
1195 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1196 return cpm.get_state();
1200 Session::set_state (const XMLNode& node, int version)
1204 const XMLProperty* prop;
1207 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1209 if (node.name() != X_("Session")) {
1210 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1214 if ((prop = node.property ("version")) != 0) {
1215 version = atoi (prop->value ()) * 1000;
1218 if ((prop = node.property ("name")) != 0) {
1219 _name = prop->value ();
1222 if ((prop = node.property (X_("sample-rate"))) != 0) {
1224 _nominal_frame_rate = atoi (prop->value());
1226 if (_nominal_frame_rate != _current_frame_rate) {
1227 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1228 if (r.get_value_or (0)) {
1234 setup_raid_path(_session_dir->root_path().to_string());
1236 if ((prop = node.property (X_("id-counter"))) != 0) {
1238 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1239 ID::init_counter (x);
1241 /* old sessions used a timebased counter, so fake
1242 the startup ID counter based on a standard
1247 ID::init_counter (now);
1250 if ((prop = node.property (X_("event-counter"))) != 0) {
1251 Evoral::init_event_id_counter (atoi (prop->value()));
1254 IO::disable_connecting ();
1256 Stateful::save_extra_xml (node);
1258 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1259 load_options (*child);
1260 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1261 load_options (*child);
1263 error << _("Session: XML state has no options section") << endmsg;
1266 if (version >= 3000) {
1267 if ((child = find_named_node (node, "Metadata")) == 0) {
1268 warning << _("Session: XML state has no metadata section") << endmsg;
1269 } else if (_metadata->set_state (*child, version)) {
1274 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1275 _speakers->set_state (*child, version);
1278 if ((child = find_named_node (node, "Sources")) == 0) {
1279 error << _("Session: XML state has no sources section") << endmsg;
1281 } else if (load_sources (*child)) {
1285 if ((child = find_named_node (node, "TempoMap")) == 0) {
1286 error << _("Session: XML state has no Tempo Map section") << endmsg;
1288 } else if (_tempo_map->set_state (*child, version)) {
1292 if ((child = find_named_node (node, "Locations")) == 0) {
1293 error << _("Session: XML state has no locations section") << endmsg;
1295 } else if (_locations->set_state (*child, version)) {
1301 if ((location = _locations->auto_loop_location()) != 0) {
1302 set_auto_loop_location (location);
1305 if ((location = _locations->auto_punch_location()) != 0) {
1306 set_auto_punch_location (location);
1309 if ((location = _locations->session_range_location()) != 0) {
1310 delete _session_range_location;
1311 _session_range_location = location;
1314 if (_session_range_location) {
1315 AudioFileSource::set_header_position_offset (_session_range_location->start());
1318 if ((child = find_named_node (node, "Regions")) == 0) {
1319 error << _("Session: XML state has no Regions section") << endmsg;
1321 } else if (load_regions (*child)) {
1325 if ((child = find_named_node (node, "Playlists")) == 0) {
1326 error << _("Session: XML state has no playlists section") << endmsg;
1328 } else if (playlists->load (*this, *child)) {
1332 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1334 } else if (playlists->load_unused (*this, *child)) {
1338 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1339 if (load_compounds (*child)) {
1344 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1345 if (load_named_selections (*child)) {
1350 if (version >= 3000) {
1351 if ((child = find_named_node (node, "Bundles")) == 0) {
1352 warning << _("Session: XML state has no bundles section") << endmsg;
1355 /* We can't load Bundles yet as they need to be able
1356 to convert from port names to Port objects, which can't happen until
1358 _bundle_xml_node = new XMLNode (*child);
1362 if (version < 3000) {
1363 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1364 error << _("Session: XML state has no diskstreams section") << endmsg;
1366 } else if (load_diskstreams_2X (*child, version)) {
1371 if ((child = find_named_node (node, "Routes")) == 0) {
1372 error << _("Session: XML state has no routes section") << endmsg;
1374 } else if (load_routes (*child, version)) {
1378 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1379 _diskstreams_2X.clear ();
1381 if (version >= 3000) {
1383 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1384 error << _("Session: XML state has no route groups section") << endmsg;
1386 } else if (load_route_groups (*child, version)) {
1390 } else if (version < 3000) {
1392 if ((child = find_named_node (node, "EditGroups")) == 0) {
1393 error << _("Session: XML state has no edit groups section") << endmsg;
1395 } else if (load_route_groups (*child, version)) {
1399 if ((child = find_named_node (node, "MixGroups")) == 0) {
1400 error << _("Session: XML state has no mix groups section") << endmsg;
1402 } else if (load_route_groups (*child, version)) {
1407 if ((child = find_named_node (node, "Click")) == 0) {
1408 warning << _("Session: XML state has no click section") << endmsg;
1409 } else if (_click_io) {
1410 _click_io->set_state (*child, version);
1413 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1414 ControlProtocolManager::instance().set_protocol_states (*child);
1417 /* here beginneth the second phase ... */
1419 StateReady (); /* EMIT SIGNAL */
1428 Session::load_routes (const XMLNode& node, int version)
1431 XMLNodeConstIterator niter;
1432 RouteList new_routes;
1434 nlist = node.children();
1438 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1440 boost::shared_ptr<Route> route;
1441 if (version < 3000) {
1442 route = XMLRouteFactory_2X (**niter, version);
1444 route = XMLRouteFactory (**niter, version);
1448 error << _("Session: cannot create Route from XML description.") << endmsg;
1452 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1454 new_routes.push_back (route);
1457 add_routes (new_routes, false, false);
1462 boost::shared_ptr<Route>
1463 Session::XMLRouteFactory (const XMLNode& node, int version)
1465 boost::shared_ptr<Route> ret;
1467 if (node.name() != "Route") {
1471 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1473 DataType type = DataType::AUDIO;
1474 const XMLProperty* prop = node.property("default-type");
1477 type = DataType (prop->value());
1480 assert (type != DataType::NIL);
1484 boost::shared_ptr<Track> track;
1486 if (type == DataType::AUDIO) {
1487 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1489 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1492 if (track->init()) {
1496 if (track->set_state (node, version)) {
1500 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1501 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1506 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1508 if (r->init () == 0 && r->set_state (node, version) == 0) {
1509 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1510 boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1519 boost::shared_ptr<Route>
1520 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1522 boost::shared_ptr<Route> ret;
1524 if (node.name() != "Route") {
1528 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1530 ds_prop = node.property (X_("diskstream"));
1533 DataType type = DataType::AUDIO;
1534 const XMLProperty* prop = node.property("default-type");
1537 type = DataType (prop->value());
1540 assert (type != DataType::NIL);
1544 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1545 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1549 if (i == _diskstreams_2X.end()) {
1550 error << _("Could not find diskstream for route") << endmsg;
1551 return boost::shared_ptr<Route> ();
1554 boost::shared_ptr<Track> track;
1556 if (type == DataType::AUDIO) {
1557 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1559 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1562 if (track->init()) {
1566 if (track->set_state (node, version)) {
1570 track->set_diskstream (*i);
1572 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1573 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1578 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1580 if (r->init () == 0 && r->set_state (node, version) == 0) {
1581 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1582 boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1592 Session::load_regions (const XMLNode& node)
1595 XMLNodeConstIterator niter;
1596 boost::shared_ptr<Region> region;
1598 nlist = node.children();
1602 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1603 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1604 error << _("Session: cannot create Region from XML description.");
1605 const XMLProperty *name = (**niter).property("name");
1608 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1619 Session::load_compounds (const XMLNode& node)
1621 XMLNodeList calist = node.children();
1622 XMLNodeConstIterator caiter;
1623 XMLProperty *caprop;
1625 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1626 XMLNode* ca = *caiter;
1630 if ((caprop = ca->property (X_("original"))) == 0) {
1633 orig_id = caprop->value();
1635 if ((caprop = ca->property (X_("copy"))) == 0) {
1638 copy_id = caprop->value();
1640 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1641 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1643 if (!orig || !copy) {
1644 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1650 RegionFactory::add_compound_association (orig, copy);
1657 Session::load_nested_sources (const XMLNode& node)
1660 XMLNodeConstIterator niter;
1662 nlist = node.children();
1664 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1665 if ((*niter)->name() == "Source") {
1667 /* it may already exist, so don't recreate it unnecessarily
1670 XMLProperty* prop = (*niter)->property (X_("id"));
1672 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1676 ID source_id (prop->value());
1678 if (!source_by_id (source_id)) {
1681 SourceFactory::create (*this, **niter, true);
1683 catch (failed_constructor& err) {
1684 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1691 boost::shared_ptr<Region>
1692 Session::XMLRegionFactory (const XMLNode& node, bool full)
1694 const XMLProperty* type = node.property("type");
1698 const XMLNodeList& nlist = node.children();
1700 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1701 XMLNode *child = (*niter);
1702 if (child->name() == "NestedSource") {
1703 load_nested_sources (*child);
1707 if (!type || type->value() == "audio") {
1708 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1709 } else if (type->value() == "midi") {
1710 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1713 } catch (failed_constructor& err) {
1714 return boost::shared_ptr<Region> ();
1717 return boost::shared_ptr<Region> ();
1720 boost::shared_ptr<AudioRegion>
1721 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1723 const XMLProperty* prop;
1724 boost::shared_ptr<Source> source;
1725 boost::shared_ptr<AudioSource> as;
1727 SourceList master_sources;
1728 uint32_t nchans = 1;
1731 if (node.name() != X_("Region")) {
1732 return boost::shared_ptr<AudioRegion>();
1735 if ((prop = node.property (X_("channels"))) != 0) {
1736 nchans = atoi (prop->value().c_str());
1739 if ((prop = node.property ("name")) == 0) {
1740 cerr << "no name for this region\n";
1744 if ((prop = node.property (X_("source-0"))) == 0) {
1745 if ((prop = node.property ("source")) == 0) {
1746 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1747 return boost::shared_ptr<AudioRegion>();
1751 PBD::ID s_id (prop->value());
1753 if ((source = source_by_id (s_id)) == 0) {
1754 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1755 return boost::shared_ptr<AudioRegion>();
1758 as = boost::dynamic_pointer_cast<AudioSource>(source);
1760 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1761 return boost::shared_ptr<AudioRegion>();
1764 sources.push_back (as);
1766 /* pickup other channels */
1768 for (uint32_t n=1; n < nchans; ++n) {
1769 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1770 if ((prop = node.property (buf)) != 0) {
1772 PBD::ID id2 (prop->value());
1774 if ((source = source_by_id (id2)) == 0) {
1775 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1776 return boost::shared_ptr<AudioRegion>();
1779 as = boost::dynamic_pointer_cast<AudioSource>(source);
1781 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1782 return boost::shared_ptr<AudioRegion>();
1784 sources.push_back (as);
1788 for (uint32_t n = 0; n < nchans; ++n) {
1789 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1790 if ((prop = node.property (buf)) != 0) {
1792 PBD::ID id2 (prop->value());
1794 if ((source = source_by_id (id2)) == 0) {
1795 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1796 return boost::shared_ptr<AudioRegion>();
1799 as = boost::dynamic_pointer_cast<AudioSource>(source);
1801 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1802 return boost::shared_ptr<AudioRegion>();
1804 master_sources.push_back (as);
1809 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1811 /* a final detail: this is the one and only place that we know how long missing files are */
1813 if (region->whole_file()) {
1814 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1815 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1817 sfp->set_length (region->length());
1822 if (!master_sources.empty()) {
1823 if (master_sources.size() != nchans) {
1824 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1826 region->set_master_sources (master_sources);
1834 catch (failed_constructor& err) {
1835 return boost::shared_ptr<AudioRegion>();
1839 boost::shared_ptr<MidiRegion>
1840 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1842 const XMLProperty* prop;
1843 boost::shared_ptr<Source> source;
1844 boost::shared_ptr<MidiSource> ms;
1847 if (node.name() != X_("Region")) {
1848 return boost::shared_ptr<MidiRegion>();
1851 if ((prop = node.property ("name")) == 0) {
1852 cerr << "no name for this region\n";
1856 if ((prop = node.property (X_("source-0"))) == 0) {
1857 if ((prop = node.property ("source")) == 0) {
1858 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1859 return boost::shared_ptr<MidiRegion>();
1863 PBD::ID s_id (prop->value());
1865 if ((source = source_by_id (s_id)) == 0) {
1866 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1867 return boost::shared_ptr<MidiRegion>();
1870 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1872 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1873 return boost::shared_ptr<MidiRegion>();
1876 sources.push_back (ms);
1879 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1880 /* a final detail: this is the one and only place that we know how long missing files are */
1882 if (region->whole_file()) {
1883 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1884 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1886 sfp->set_length (region->length());
1894 catch (failed_constructor& err) {
1895 return boost::shared_ptr<MidiRegion>();
1900 Session::get_sources_as_xml ()
1903 XMLNode* node = new XMLNode (X_("Sources"));
1904 Glib::Mutex::Lock lm (source_lock);
1906 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1907 node->add_child_nocopy (i->second->get_state());
1914 Session::path_from_region_name (DataType type, string name, string identifier)
1916 char buf[PATH_MAX+1];
1918 SessionDirectory sdir(get_best_session_directory_for_new_source());
1919 sys::path source_dir = ((type == DataType::AUDIO)
1920 ? sdir.sound_path() : sdir.midi_path());
1922 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1924 for (n = 0; n < 999999; ++n) {
1925 if (identifier.length()) {
1926 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1927 identifier.c_str(), n, ext.c_str());
1929 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1933 sys::path source_path = source_dir / buf;
1935 if (!sys::exists (source_path)) {
1936 return source_path.to_string();
1940 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1949 Session::load_sources (const XMLNode& node)
1952 XMLNodeConstIterator niter;
1953 boost::shared_ptr<Source> source;
1955 nlist = node.children();
1959 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1962 if ((source = XMLSourceFactory (**niter)) == 0) {
1963 error << _("Session: cannot create Source from XML description.") << endmsg;
1966 } catch (MissingSource& err) {
1970 if (!no_questions_about_missing_files) {
1971 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1976 switch (user_choice) {
1978 /* user added a new search location, so try again */
1983 /* user asked to quit the entire session load
1988 no_questions_about_missing_files = true;
1992 no_questions_about_missing_files = true;
1997 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1998 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2007 boost::shared_ptr<Source>
2008 Session::XMLSourceFactory (const XMLNode& node)
2010 if (node.name() != "Source") {
2011 return boost::shared_ptr<Source>();
2015 /* note: do peak building in another thread when loading session state */
2016 return SourceFactory::create (*this, node, true);
2019 catch (failed_constructor& err) {
2020 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2021 return boost::shared_ptr<Source>();
2026 Session::save_template (string template_name)
2030 if (_state_of_the_state & CannotSave) {
2034 sys::path user_template_dir(user_template_directory());
2038 sys::create_directories (user_template_dir);
2040 catch(sys::filesystem_error& ex)
2042 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
2043 user_template_dir.to_string(), ex.what()) << endmsg;
2047 tree.set_root (&get_template());
2049 sys::path template_file_path(user_template_dir);
2050 template_file_path /= template_name + template_suffix;
2052 if (sys::exists (template_file_path))
2054 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2055 template_file_path.to_string()) << endmsg;
2059 if (!tree.write (template_file_path.to_string())) {
2060 error << _("template not saved") << endmsg;
2068 Session::rename_template (string old_name, string new_name)
2070 sys::path old_path (user_template_directory());
2071 old_path /= old_name + template_suffix;
2073 sys::path new_path(user_template_directory());
2074 new_path /= new_name + template_suffix;
2076 if (sys::exists (new_path)) {
2077 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
2078 new_path.to_string()) << endmsg;
2083 sys::rename (old_path, new_path);
2091 Session::delete_template (string name)
2093 sys::path path = user_template_directory();
2094 path /= name + template_suffix;
2105 Session::refresh_disk_space ()
2108 struct statfs statfsbuf;
2109 vector<space_and_path>::iterator i;
2110 Glib::Mutex::Lock lm (space_lock);
2113 /* get freespace on every FS that is part of the session path */
2115 _total_free_4k_blocks = 0;
2117 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2118 statfs ((*i).path.c_str(), &statfsbuf);
2120 scale = statfsbuf.f_bsize/4096.0;
2122 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2123 _total_free_4k_blocks += (*i).blocks;
2129 Session::get_best_session_directory_for_new_source ()
2131 vector<space_and_path>::iterator i;
2132 string result = _session_dir->root_path().to_string();
2134 /* handle common case without system calls */
2136 if (session_dirs.size() == 1) {
2140 /* OK, here's the algorithm we're following here:
2142 We want to select which directory to use for
2143 the next file source to be created. Ideally,
2144 we'd like to use a round-robin process so as to
2145 get maximum performance benefits from splitting
2146 the files across multiple disks.
2148 However, in situations without much diskspace, an
2149 RR approach may end up filling up a filesystem
2150 with new files while others still have space.
2151 Its therefore important to pay some attention to
2152 the freespace in the filesystem holding each
2153 directory as well. However, if we did that by
2154 itself, we'd keep creating new files in the file
2155 system with the most space until it was as full
2156 as all others, thus negating any performance
2157 benefits of this RAID-1 like approach.
2159 So, we use a user-configurable space threshold. If
2160 there are at least 2 filesystems with more than this
2161 much space available, we use RR selection between them.
2162 If not, then we pick the filesystem with the most space.
2164 This gets a good balance between the two
2168 refresh_disk_space ();
2170 int free_enough = 0;
2172 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2173 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2178 if (free_enough >= 2) {
2179 /* use RR selection process, ensuring that the one
2183 i = last_rr_session_dir;
2186 if (++i == session_dirs.end()) {
2187 i = session_dirs.begin();
2190 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2191 if (create_session_directory ((*i).path)) {
2193 last_rr_session_dir = i;
2198 } while (i != last_rr_session_dir);
2202 /* pick FS with the most freespace (and that
2203 seems to actually work ...)
2206 vector<space_and_path> sorted;
2207 space_and_path_ascending_cmp cmp;
2209 sorted = session_dirs;
2210 sort (sorted.begin(), sorted.end(), cmp);
2212 for (i = sorted.begin(); i != sorted.end(); ++i) {
2213 if (create_session_directory ((*i).path)) {
2215 last_rr_session_dir = i;
2225 Session::load_named_selections (const XMLNode& node)
2228 XMLNodeConstIterator niter;
2231 nlist = node.children();
2235 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2237 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2238 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2246 Session::XMLNamedSelectionFactory (const XMLNode& node)
2249 return new NamedSelection (*this, node);
2252 catch (failed_constructor& err) {
2258 Session::automation_dir () const
2260 return Glib::build_filename (_path, "automation");
2264 Session::analysis_dir () const
2266 return Glib::build_filename (_path, "analysis");
2270 Session::plugins_dir () const
2272 return Glib::build_filename (_path, "plugins");
2276 Session::load_bundles (XMLNode const & node)
2278 XMLNodeList nlist = node.children();
2279 XMLNodeConstIterator niter;
2283 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2284 if ((*niter)->name() == "InputBundle") {
2285 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2286 } else if ((*niter)->name() == "OutputBundle") {
2287 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2289 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2298 Session::load_route_groups (const XMLNode& node, int version)
2300 XMLNodeList nlist = node.children();
2301 XMLNodeConstIterator niter;
2305 if (version >= 3000) {
2307 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2308 if ((*niter)->name() == "RouteGroup") {
2309 RouteGroup* rg = new RouteGroup (*this, "");
2310 add_route_group (rg);
2311 rg->set_state (**niter, version);
2315 } else if (version < 3000) {
2317 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2318 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2319 RouteGroup* rg = new RouteGroup (*this, "");
2320 add_route_group (rg);
2321 rg->set_state (**niter, version);
2330 Session::auto_save()
2332 save_state (_current_snapshot_name);
2336 state_file_filter (const string &str, void */*arg*/)
2338 return (str.length() > strlen(statefile_suffix) &&
2339 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2343 bool operator()(const string* a, const string* b) {
2349 remove_end(string* state)
2351 string statename(*state);
2353 string::size_type start,end;
2354 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2355 statename = statename.substr (start+1);
2358 if ((end = statename.rfind(".ardour")) == string::npos) {
2359 end = statename.length();
2362 return new string(statename.substr (0, end));
2366 Session::possible_states (string path)
2368 PathScanner scanner;
2369 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2371 transform(states->begin(), states->end(), states->begin(), remove_end);
2374 sort (states->begin(), states->end(), cmp);
2380 Session::possible_states () const
2382 return possible_states(_path);
2386 Session::add_route_group (RouteGroup* g)
2388 _route_groups.push_back (g);
2389 route_group_added (g); /* EMIT SIGNAL */
2391 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2392 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2393 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2399 Session::remove_route_group (RouteGroup& rg)
2401 list<RouteGroup*>::iterator i;
2403 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2404 _route_groups.erase (i);
2407 route_group_removed (); /* EMIT SIGNAL */
2411 /** Set a new order for our route groups, without adding or removing any.
2412 * @param groups Route group list in the new order.
2415 Session::reorder_route_groups (list<RouteGroup*> groups)
2417 _route_groups = groups;
2419 route_groups_reordered (); /* EMIT SIGNAL */
2425 Session::route_group_by_name (string name)
2427 list<RouteGroup *>::iterator i;
2429 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2430 if ((*i)->name() == name) {
2438 Session::all_route_group() const
2440 return *_all_route_group;
2444 Session::add_commands (vector<Command*> const & cmds)
2446 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2452 Session::begin_reversible_command (const string& name)
2454 begin_reversible_command (g_quark_from_string (name.c_str ()));
2457 /** Begin a reversible command using a GQuark to identify it.
2458 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2459 * but there must be as many begin...()s as there are commit...()s.
2462 Session::begin_reversible_command (GQuark q)
2464 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2465 to hold all the commands that are committed. This keeps the order of
2466 commands correct in the history.
2469 if (_current_trans == 0) {
2470 /* start a new transaction */
2471 assert (_current_trans_quarks.empty ());
2472 _current_trans = new UndoTransaction();
2473 _current_trans->set_name (g_quark_to_string (q));
2476 _current_trans_quarks.push_front (q);
2480 Session::commit_reversible_command (Command *cmd)
2482 assert (_current_trans);
2483 assert (!_current_trans_quarks.empty ());
2488 _current_trans->add_command (cmd);
2491 _current_trans_quarks.pop_front ();
2493 if (!_current_trans_quarks.empty ()) {
2494 /* the transaction we're committing is not the top-level one */
2498 if (_current_trans->empty()) {
2499 /* no commands were added to the transaction, so just get rid of it */
2500 delete _current_trans;
2505 gettimeofday (&now, 0);
2506 _current_trans->set_timestamp (now);
2508 _history.add (_current_trans);
2513 accept_all_audio_files (const string& path, void */*arg*/)
2515 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2519 if (!AudioFileSource::safe_audio_file_extension (path)) {
2527 accept_all_midi_files (const string& path, void */*arg*/)
2529 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2533 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2534 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2535 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2539 accept_all_state_files (const string& path, void */*arg*/)
2541 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2545 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2549 Session::find_all_sources (string path, set<string>& result)
2554 if (!tree.read (path)) {
2558 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2563 XMLNodeConstIterator niter;
2565 nlist = node->children();
2569 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2573 if ((prop = (*niter)->property (X_("type"))) == 0) {
2577 DataType type (prop->value());
2579 if ((prop = (*niter)->property (X_("name"))) == 0) {
2583 if (Glib::path_is_absolute (prop->value())) {
2584 /* external file, ignore */
2592 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2593 result.insert (found_path);
2601 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2603 PathScanner scanner;
2604 vector<string*>* state_files;
2606 string this_snapshot_path;
2612 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2613 ripped = ripped.substr (0, ripped.length() - 1);
2616 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2618 if (state_files == 0) {
2623 this_snapshot_path = _path;
2624 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2625 this_snapshot_path += statefile_suffix;
2627 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2629 if (exclude_this_snapshot && **i == this_snapshot_path) {
2633 if (find_all_sources (**i, result) < 0) {
2641 struct RegionCounter {
2642 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2643 AudioSourceList::iterator iter;
2644 boost::shared_ptr<Region> region;
2647 RegionCounter() : count (0) {}
2651 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2653 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2654 return r.get_value_or (1);
2658 Session::cleanup_regions ()
2660 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2662 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2664 boost::shared_ptr<AudioRegion> audio_region = boost::dynamic_pointer_cast<AudioRegion>( i->second);
2666 if (!audio_region) {
2670 uint32_t used = playlists->region_use_count (audio_region);
2672 if (used == 0 && !audio_region->automatic()) {
2673 RegionFactory::map_remove(i->second);
2677 /* dump the history list */
2684 Session::cleanup_sources (CleanupReport& rep)
2686 // FIXME: needs adaptation to midi
2688 vector<boost::shared_ptr<Source> > dead_sources;
2689 PathScanner scanner;
2692 vector<space_and_path>::iterator i;
2693 vector<space_and_path>::iterator nexti;
2694 vector<string*>* candidates;
2695 vector<string*>* candidates2;
2696 vector<string> unused;
2697 set<string> all_sources;
2702 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2704 /* consider deleting all unused playlists */
2706 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2711 /* sync the "all regions" property of each playlist with its current state
2714 playlists->sync_all_regions_with_regions ();
2716 /* find all un-used sources */
2721 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2723 SourceMap::iterator tmp;
2728 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2732 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2733 dead_sources.push_back (i->second);
2734 i->second->drop_references ();
2740 /* build a list of all the possible audio directories for the session */
2742 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2747 SessionDirectory sdir ((*i).path);
2748 audio_path += sdir.sound_path().to_string();
2750 if (nexti != session_dirs.end()) {
2758 /* build a list of all the possible midi directories for the session */
2760 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2765 SessionDirectory sdir ((*i).path);
2766 midi_path += sdir.midi_path().to_string();
2768 if (nexti != session_dirs.end()) {
2775 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2776 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2782 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2783 candidates->push_back (*i);
2788 candidates = candidates2; // might still be null
2791 /* find all sources, but don't use this snapshot because the
2792 state file on disk still references sources we may have already
2796 find_all_sources_across_snapshots (all_sources, true);
2798 /* add our current source list
2801 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2802 boost::shared_ptr<FileSource> fs;
2803 SourceMap::iterator tmp = i;
2806 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2807 if (playlists->source_use_count (fs) != 0) {
2808 all_sources.insert (fs->path());
2811 /* we might not remove this source from disk, because it may be used
2812 by other snapshots, but its not being used in this version
2813 so lets get rid of it now, along with any representative regions
2817 RegionFactory::remove_regions_using_source (i->second);
2825 char tmppath1[PATH_MAX+1];
2826 char tmppath2[PATH_MAX+1];
2829 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2834 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2836 if (realpath(spath.c_str(), tmppath1) == 0) {
2837 error << string_compose (_("Cannot expand path %1 (%2)"),
2838 spath, strerror (errno)) << endmsg;
2842 if (realpath((*i).c_str(), tmppath2) == 0) {
2843 error << string_compose (_("Cannot expand path %1 (%2)"),
2844 (*i), strerror (errno)) << endmsg;
2848 if (strcmp(tmppath1, tmppath2) == 0) {
2855 unused.push_back (spath);
2864 /* now try to move all unused files into the "dead" directory(ies) */
2866 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2867 struct stat statbuf;
2871 /* don't move the file across filesystems, just
2872 stick it in the `dead_dir_name' directory
2873 on whichever filesystem it was already on.
2876 if ((*x).find ("/sounds/") != string::npos) {
2878 /* old school, go up 1 level */
2880 newpath = Glib::path_get_dirname (*x); // "sounds"
2881 newpath = Glib::path_get_dirname (newpath); // "session-name"
2885 /* new school, go up 4 levels */
2887 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2888 newpath = Glib::path_get_dirname (newpath); // "session-name"
2889 newpath = Glib::path_get_dirname (newpath); // "interchange"
2890 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2893 newpath = Glib::build_filename (newpath, dead_dir_name);
2895 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2896 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2900 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2902 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2904 /* the new path already exists, try versioning */
2906 char buf[PATH_MAX+1];
2910 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2913 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2914 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2918 if (version == 999) {
2919 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2923 newpath = newpath_v;
2928 /* it doesn't exist, or we can't read it or something */
2932 stat ((*x).c_str(), &statbuf);
2934 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2935 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2936 (*x), newpath, strerror (errno))
2941 /* see if there an easy to find peakfile for this file, and remove it.
2944 string base = basename_nosuffix (*x);
2945 base += "%A"; /* this is what we add for the channel suffix of all native files,
2946 or for the first channel of embedded files. it will miss
2947 some peakfiles for other channels
2949 string peakpath = peak_path (base);
2951 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2952 if (::unlink (peakpath.c_str()) != 0) {
2953 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2954 peakpath, _path, strerror (errno))
2956 /* try to back out */
2957 ::rename (newpath.c_str(), _path.c_str());
2962 rep.paths.push_back (*x);
2963 rep.space += statbuf.st_size;
2966 /* dump the history list */
2970 /* save state so we don't end up a session file
2971 referring to non-existent sources.
2978 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2984 Session::cleanup_trash_sources (CleanupReport& rep)
2986 // FIXME: needs adaptation for MIDI
2988 vector<space_and_path>::iterator i;
2994 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2996 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2998 clear_directory (dead_dir, &rep.space, &rep.paths);
3005 Session::set_dirty ()
3007 bool was_dirty = dirty();
3009 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3013 DirtyChanged(); /* EMIT SIGNAL */
3019 Session::set_clean ()
3021 bool was_dirty = dirty();
3023 _state_of_the_state = Clean;
3027 DirtyChanged(); /* EMIT SIGNAL */
3032 Session::set_deletion_in_progress ()
3034 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3038 Session::clear_deletion_in_progress ()
3040 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3044 Session::add_controllable (boost::shared_ptr<Controllable> c)
3046 /* this adds a controllable to the list managed by the Session.
3047 this is a subset of those managed by the Controllable class
3048 itself, and represents the only ones whose state will be saved
3049 as part of the session.
3052 Glib::Mutex::Lock lm (controllables_lock);
3053 controllables.insert (c);
3056 struct null_deleter { void operator()(void const *) const {} };
3059 Session::remove_controllable (Controllable* c)
3061 if (_state_of_the_state | Deletion) {
3065 Glib::Mutex::Lock lm (controllables_lock);
3067 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3069 if (x != controllables.end()) {
3070 controllables.erase (x);
3074 boost::shared_ptr<Controllable>
3075 Session::controllable_by_id (const PBD::ID& id)
3077 Glib::Mutex::Lock lm (controllables_lock);
3079 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3080 if ((*i)->id() == id) {
3085 return boost::shared_ptr<Controllable>();
3088 boost::shared_ptr<Controllable>
3089 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3091 boost::shared_ptr<Controllable> c;
3092 boost::shared_ptr<Route> r;
3094 switch (desc.top_level_type()) {
3095 case ControllableDescriptor::NamedRoute:
3097 std::string str = desc.top_level_name();
3098 if (str == "master") {
3100 } else if (str == "control" || str == "listen") {
3103 r = route_by_name (desc.top_level_name());
3108 case ControllableDescriptor::RemoteControlID:
3109 r = route_by_remote_id (desc.rid());
3117 switch (desc.subtype()) {
3118 case ControllableDescriptor::Gain:
3119 c = r->gain_control ();
3122 case ControllableDescriptor::Solo:
3123 c = r->solo_control();
3126 case ControllableDescriptor::Mute:
3127 c = r->mute_control();
3130 case ControllableDescriptor::Recenable:
3132 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3135 c = t->rec_enable_control ();
3140 case ControllableDescriptor::PanDirection:
3142 c = r->pannable()->pan_azimuth_control;
3146 case ControllableDescriptor::PanWidth:
3148 c = r->pannable()->pan_width_control;
3152 case ControllableDescriptor::PanElevation:
3154 c = r->pannable()->pan_elevation_control;
3158 case ControllableDescriptor::Balance:
3159 /* XXX simple pan control */
3162 case ControllableDescriptor::PluginParameter:
3164 uint32_t plugin = desc.target (0);
3165 uint32_t parameter_index = desc.target (1);
3167 /* revert to zero based counting */
3173 if (parameter_index > 0) {
3177 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3180 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3181 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3186 case ControllableDescriptor::SendGain:
3188 uint32_t send = desc.target (0);
3190 /* revert to zero-based counting */
3196 boost::shared_ptr<Processor> p = r->nth_send (send);
3199 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3200 boost::shared_ptr<Amp> a = s->amp();
3203 c = s->amp()->gain_control();
3210 /* relax and return a null pointer */
3218 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3221 Stateful::add_instant_xml (node, _path);
3224 if (write_to_config) {
3225 Config->add_instant_xml (node);
3230 Session::instant_xml (const string& node_name)
3232 return Stateful::instant_xml (node_name, _path);
3236 Session::save_history (string snapshot_name)
3244 if (snapshot_name.empty()) {
3245 snapshot_name = _current_snapshot_name;
3248 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3249 const string backup_filename = history_filename + backup_suffix;
3250 const sys::path xml_path = _session_dir->root_path() / history_filename;
3251 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3253 if (sys::exists (xml_path)) {
3256 sys::rename (xml_path, backup_path);
3258 catch (const sys::filesystem_error& err)
3260 error << _("could not backup old history file, current history not saved") << endmsg;
3265 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3269 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3271 if (!tree.write (xml_path.to_string()))
3273 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3277 sys::remove (xml_path);
3278 sys::rename (backup_path, xml_path);
3280 catch (const sys::filesystem_error& err)
3282 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3283 backup_path.to_string(), err.what()) << endmsg;
3293 Session::restore_history (string snapshot_name)
3297 if (snapshot_name.empty()) {
3298 snapshot_name = _current_snapshot_name;
3301 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3302 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3304 info << "Loading history from " << xml_path.to_string() << endmsg;
3306 if (!sys::exists (xml_path)) {
3307 info << string_compose (_("%1: no history file \"%2\" for this session."),
3308 _name, xml_path.to_string()) << endmsg;
3312 if (!tree.read (xml_path.to_string())) {
3313 error << string_compose (_("Could not understand session history file \"%1\""),
3314 xml_path.to_string()) << endmsg;
3321 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3324 UndoTransaction* ut = new UndoTransaction ();
3327 ut->set_name(t->property("name")->value());
3328 stringstream ss(t->property("tv-sec")->value());
3330 ss.str(t->property("tv-usec")->value());
3332 ut->set_timestamp(tv);
3334 for (XMLNodeConstIterator child_it = t->children().begin();
3335 child_it != t->children().end(); child_it++)
3337 XMLNode *n = *child_it;
3340 if (n->name() == "MementoCommand" ||
3341 n->name() == "MementoUndoCommand" ||
3342 n->name() == "MementoRedoCommand") {
3344 if ((c = memento_command_factory(n))) {
3348 } else if (n->name() == "NoteDiffCommand") {
3349 PBD::ID id (n->property("midi-source")->value());
3350 boost::shared_ptr<MidiSource> midi_source =
3351 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3353 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3355 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3358 } else if (n->name() == "SysExDiffCommand") {
3360 PBD::ID id (n->property("midi-source")->value());
3361 boost::shared_ptr<MidiSource> midi_source =
3362 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3364 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3366 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3369 } else if (n->name() == "PatchChangeDiffCommand") {
3371 PBD::ID id (n->property("midi-source")->value());
3372 boost::shared_ptr<MidiSource> midi_source =
3373 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3375 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3377 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3380 } else if (n->name() == "StatefulDiffCommand") {
3381 if ((c = stateful_diff_command_factory (n))) {
3382 ut->add_command (c);
3385 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3396 Session::config_changed (std::string p, bool ours)
3402 if (p == "seamless-loop") {
3404 } else if (p == "rf-speed") {
3406 } else if (p == "auto-loop") {
3408 } else if (p == "auto-input") {
3410 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3411 /* auto-input only makes a difference if we're rolling */
3412 set_track_monitor_input_status (!config.get_auto_input());
3415 } else if (p == "punch-in") {
3419 if ((location = _locations->auto_punch_location()) != 0) {
3421 if (config.get_punch_in ()) {
3422 replace_event (SessionEvent::PunchIn, location->start());
3424 remove_event (location->start(), SessionEvent::PunchIn);
3428 } else if (p == "punch-out") {
3432 if ((location = _locations->auto_punch_location()) != 0) {
3434 if (config.get_punch_out()) {
3435 replace_event (SessionEvent::PunchOut, location->end());
3437 clear_events (SessionEvent::PunchOut);
3441 } else if (p == "edit-mode") {
3443 Glib::Mutex::Lock lm (playlists->lock);
3445 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3446 (*i)->set_edit_mode (Config->get_edit_mode ());
3449 } else if (p == "use-video-sync") {
3451 waiting_for_sync_offset = config.get_use_video_sync();
3453 } else if (p == "mmc-control") {
3455 //poke_midi_thread ();
3457 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3459 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3461 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3463 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3465 } else if (p == "midi-control") {
3467 //poke_midi_thread ();
3469 } else if (p == "raid-path") {
3471 setup_raid_path (config.get_raid_path());
3473 } else if (p == "timecode-format") {
3477 } else if (p == "video-pullup") {
3481 } else if (p == "seamless-loop") {
3483 if (play_loop && transport_rolling()) {
3484 // to reset diskstreams etc
3485 request_play_loop (true);
3488 } else if (p == "rf-speed") {
3490 cumulative_rf_motion = 0;
3493 } else if (p == "click-sound") {
3495 setup_click_sounds (1);
3497 } else if (p == "click-emphasis-sound") {
3499 setup_click_sounds (-1);
3501 } else if (p == "clicking") {
3503 if (Config->get_clicking()) {
3504 if (_click_io && click_data) { // don't require emphasis data
3511 } else if (p == "send-mtc") {
3513 if (Config->get_send_mtc ()) {
3514 /* mark us ready to send */
3515 next_quarter_frame_to_send = 0;
3518 } else if (p == "send-mmc") {
3520 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3522 } else if (p == "midi-feedback") {
3524 session_midi_feedback = Config->get_midi_feedback();
3526 } else if (p == "jack-time-master") {
3528 engine().reset_timebase ();
3530 } else if (p == "native-file-header-format") {
3532 if (!first_file_header_format_reset) {
3533 reset_native_file_format ();
3536 first_file_header_format_reset = false;
3538 } else if (p == "native-file-data-format") {
3540 if (!first_file_data_format_reset) {
3541 reset_native_file_format ();
3544 first_file_data_format_reset = false;
3546 } else if (p == "external-sync") {
3547 if (!config.get_external_sync()) {
3548 drop_sync_source ();
3550 switch_to_sync_source (config.get_sync_source());
3552 } else if (p == "remote-model") {
3553 set_remote_control_ids ();
3554 } else if (p == "denormal-model") {
3556 } else if (p == "history-depth") {
3557 set_history_depth (Config->get_history_depth());
3558 } else if (p == "sync-all-route-ordering") {
3559 sync_order_keys ("session");
3560 } else if (p == "initial-program-change") {
3562 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3565 buf[0] = MIDI::program; // channel zero by default
3566 buf[1] = (Config->get_initial_program_change() & 0x7f);
3568 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3570 } else if (p == "solo-mute-override") {
3571 // catch_up_on_solo_mute_override ();
3572 } else if (p == "listen-position" || p == "pfl-position") {
3573 listen_position_changed ();
3574 } else if (p == "solo-control-is-listen-control") {
3575 solo_control_mode_changed ();
3576 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3577 last_timecode_valid = false;
3578 } else if (p == "playback-buffer-seconds") {
3579 AudioSource::allocate_working_buffers (frame_rate());
3586 Session::set_history_depth (uint32_t d)
3588 _history.set_depth (d);
3592 Session::load_diskstreams_2X (XMLNode const & node, int)
3595 XMLNodeConstIterator citer;
3597 clist = node.children();
3599 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3602 /* diskstreams added automatically by DiskstreamCreated handler */
3603 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3604 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3605 _diskstreams_2X.push_back (dsp);
3607 error << _("Session: unknown diskstream type in XML") << endmsg;
3611 catch (failed_constructor& err) {
3612 error << _("Session: could not load diskstream via XML state") << endmsg;
3620 /** Connect things to the MMC object */
3622 Session::setup_midi_machine_control ()
3624 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3626 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3627 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3628 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3629 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3630 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3631 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3632 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3633 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3634 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3635 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3636 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3637 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3638 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3640 /* also handle MIDI SPP because its so common */
3642 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3643 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3644 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));
3647 boost::shared_ptr<Controllable>
3648 Session::solo_cut_control() const
3650 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3651 controls in Ardour that currently get presented to the user in the GUI that require
3652 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3654 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3655 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3659 return _solo_cut_control;
3663 Session::rename (const std::string& new_name)
3665 string legal_name = legalize_for_path (new_name);
3671 #define RENAME ::rename
3676 * interchange subdirectory
3680 * Backup files are left unchanged and not renamed.
3683 /* pass one: not 100% safe check that the new directory names don't
3687 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3692 /* this is a stupid hack because Glib::path_get_dirname() is
3693 * lexical-only, and so passing it /a/b/c/ gives a different
3694 * result than passing it /a/b/c ...
3697 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3698 oldstr = oldstr.substr (0, oldstr.length() - 1);
3701 string base = Glib::path_get_dirname (oldstr);
3702 string p = Glib::path_get_basename (oldstr);
3704 newstr = Glib::build_filename (base, legal_name);
3706 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3713 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3718 /* this is a stupid hack because Glib::path_get_dirname() is
3719 * lexical-only, and so passing it /a/b/c/ gives a different
3720 * result than passing it /a/b/c ...
3723 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3724 oldstr = oldstr.substr (0, oldstr.length() - 1);
3727 string base = Glib::path_get_dirname (oldstr);
3728 string p = Glib::path_get_basename (oldstr);
3730 newstr = Glib::build_filename (base, legal_name);
3732 cerr << "Rename " << oldstr << " => " << newstr << endl;
3734 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3739 (*_session_dir) = newstr;
3744 /* directory below interchange */
3746 v.push_back (newstr);
3747 v.push_back (interchange_dir_name);
3750 oldstr = Glib::build_filename (v);
3753 v.push_back (newstr);
3754 v.push_back (interchange_dir_name);
3755 v.push_back (legal_name);
3757 newstr = Glib::build_filename (v);
3759 cerr << "Rename " << oldstr << " => " << newstr << endl;
3761 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3768 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3769 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3771 cerr << "Rename " << oldstr << " => " << newstr << endl;
3773 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3780 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3782 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3783 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3785 cerr << "Rename " << oldstr << " => " << newstr << endl;
3787 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3792 /* remove old name from recent sessions */
3794 remove_recent_sessions (_path);
3797 _current_snapshot_name = new_name;
3802 /* save state again to get everything just right */
3804 save_state (_current_snapshot_name);
3807 /* add to recent sessions */
3809 store_recent_sessions (new_name, _path);