2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "libardour-config.h"
33 #include <cstdio> /* snprintf(3) ... grrr */
47 #include <sys/param.h>
48 #include <sys/mount.h>
52 #include <glibmm/thread.h>
54 #include "midi++/mmc.h"
55 #include "midi++/port.h"
56 #include "midi++/manager.h"
58 #include "pbd/boost_debug.h"
59 #include "pbd/basename.h"
60 #include "pbd/controllable_descriptor.h"
61 #include "pbd/enumwriter.h"
62 #include "pbd/error.h"
63 #include "pbd/pathscanner.h"
64 #include "pbd/pthread_utils.h"
65 #include "pbd/search_path.h"
66 #include "pbd/stacktrace.h"
67 #include "pbd/convert.h"
68 #include "pbd/clear_dir.h"
70 #include "ardour/amp.h"
71 #include "ardour/audio_diskstream.h"
72 #include "ardour/audio_playlist_source.h"
73 #include "ardour/audio_track.h"
74 #include "ardour/audioengine.h"
75 #include "ardour/audiofilesource.h"
76 #include "ardour/audioplaylist.h"
77 #include "ardour/audioregion.h"
78 #include "ardour/auditioner.h"
79 #include "ardour/automation_control.h"
80 #include "ardour/buffer.h"
81 #include "ardour/butler.h"
82 #include "ardour/configuration.h"
83 #include "ardour/control_protocol_manager.h"
84 #include "ardour/crossfade.h"
85 #include "ardour/cycle_timer.h"
86 #include "ardour/directory_names.h"
87 #include "ardour/filename_extensions.h"
88 #include "ardour/io_processor.h"
89 #include "ardour/location.h"
90 #include "ardour/midi_diskstream.h"
91 #include "ardour/midi_patch_manager.h"
92 #include "ardour/midi_playlist.h"
93 #include "ardour/midi_region.h"
94 #include "ardour/midi_source.h"
95 #include "ardour/midi_track.h"
96 #include "ardour/named_selection.h"
97 #include "ardour/pannable.h"
98 #include "ardour/processor.h"
99 #include "ardour/port.h"
100 #include "ardour/proxy_controllable.h"
101 #include "ardour/region_factory.h"
102 #include "ardour/route_group.h"
103 #include "ardour/send.h"
104 #include "ardour/session.h"
105 #include "ardour/session_directory.h"
106 #include "ardour/session_metadata.h"
107 #include "ardour/session_state_utils.h"
108 #include "ardour/session_playlists.h"
109 #include "ardour/session_utils.h"
110 #include "ardour/silentfilesource.h"
111 #include "ardour/slave.h"
112 #include "ardour/smf_source.h"
113 #include "ardour/sndfile_helpers.h"
114 #include "ardour/sndfilesource.h"
115 #include "ardour/source_factory.h"
116 #include "ardour/template_utils.h"
117 #include "ardour/tempo.h"
118 #include "ardour/ticker.h"
119 #include "ardour/user_bundle.h"
120 #include "ardour/utils.h"
121 #include "ardour/utils.h"
122 #include "ardour/version.h"
123 #include "ardour/playlist_factory.h"
125 #include "control_protocol/control_protocol.h"
131 using namespace ARDOUR;
136 Session::first_stage_init (string fullpath, string snapshot_name)
138 if (fullpath.length() == 0) {
140 throw failed_constructor();
143 char buf[PATH_MAX+1];
144 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
145 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
147 throw failed_constructor();
152 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
153 _path += G_DIR_SEPARATOR;
156 /* these two are just provisional settings. set_state()
157 will likely override them.
160 _name = _current_snapshot_name = snapshot_name;
162 set_history_depth (Config->get_history_depth());
164 _current_frame_rate = _engine.frame_rate ();
165 _nominal_frame_rate = _current_frame_rate;
166 _base_frame_rate = _current_frame_rate;
168 _tempo_map = new TempoMap (_current_frame_rate);
169 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
172 _non_soloed_outs_muted = false;
174 _solo_isolated_cnt = 0;
175 g_atomic_int_set (&processing_prohibited, 0);
176 _transport_speed = 0;
177 _last_transport_speed = 0;
178 _target_transport_speed = 0;
179 auto_play_legal = false;
180 transport_sub_state = 0;
181 _transport_frame = 0;
182 _requested_return_frame = -1;
183 _session_range_location = 0;
184 g_atomic_int_set (&_record_status, Disabled);
185 loop_changing = false;
188 _last_roll_location = 0;
189 _last_roll_or_reversal_location = 0;
190 _last_record_location = 0;
191 pending_locate_frame = 0;
192 pending_locate_roll = false;
193 pending_locate_flush = false;
194 state_was_pending = false;
196 outbound_mtc_timecode_frame = 0;
197 next_quarter_frame_to_send = -1;
198 current_block_size = 0;
199 solo_update_disabled = false;
200 _have_captured = false;
201 _worst_output_latency = 0;
202 _worst_input_latency = 0;
203 _worst_track_latency = 0;
204 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
205 _was_seamless = Config->get_seamless_loop ();
207 _send_qf_mtc = false;
208 _pframes_since_last_mtc = 0;
209 g_atomic_int_set (&_playback_load, 100);
210 g_atomic_int_set (&_capture_load, 100);
213 pending_abort = false;
214 destructive_index = 0;
215 first_file_data_format_reset = true;
216 first_file_header_format_reset = true;
217 post_export_sync = false;
220 no_questions_about_missing_files = false;
221 _speakers.reset (new Speakers);
223 AudioDiskstream::allocate_working_buffers();
225 /* default short fade = 15ms */
227 Crossfade::set_short_xfade_length ((framecnt_t) floor (config.get_short_xfade_seconds() * frame_rate()));
228 SndFileSource::setup_standard_crossfades (*this, frame_rate());
230 last_mmc_step.tv_sec = 0;
231 last_mmc_step.tv_usec = 0;
234 /* click sounds are unset by default, which causes us to internal
235 waveforms for clicks.
239 click_emphasis_length = 0;
242 process_function = &Session::process_with_events;
244 if (config.get_use_video_sync()) {
245 waiting_for_sync_offset = true;
247 waiting_for_sync_offset = false;
250 last_timecode_when = 0;
251 last_timecode_valid = false;
255 last_rr_session_dir = session_dirs.begin();
256 refresh_disk_space ();
258 /* default: assume simple stereo speaker configuration */
260 _speakers->setup_default_speakers (2);
264 average_slave_delta = 1800; // !!! why 1800 ????
265 have_first_delta_accumulator = false;
266 delta_accumulator_cnt = 0;
267 _slave_state = Stopped;
269 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
270 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
271 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
272 add_controllable (_solo_cut_control);
274 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
276 /* These are all static "per-class" signals */
278 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
279 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
280 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
281 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
282 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
284 /* stop IO objects from doing stuff until we're ready for them */
286 Delivery::disable_panners ();
287 IO::disable_connecting ();
291 Session::second_stage_init ()
293 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
296 if (load_state (_current_snapshot_name)) {
301 if (_butler->start_thread()) {
305 if (start_midi_thread ()) {
309 setup_midi_machine_control ();
311 // set_state() will call setup_raid_path(), but if it's a new session we need
312 // to call setup_raid_path() here.
315 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
319 setup_raid_path(_path);
322 /* we can't save till after ::when_engine_running() is called,
323 because otherwise we save state with no connections made.
324 therefore, we reset _state_of_the_state because ::set_state()
325 will have cleared it.
327 we also have to include Loading so that any events that get
328 generated between here and the end of ::when_engine_running()
329 will be processed directly rather than queued.
332 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
334 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
335 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
336 setup_click_sounds (0);
337 setup_midi_control ();
339 /* Pay attention ... */
341 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
342 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
345 when_engine_running ();
348 /* handle this one in a different way than all others, so that its clear what happened */
350 catch (AudioEngine::PortRegistrationFailure& err) {
351 error << err.what() << endmsg;
359 BootMessage (_("Reset Remote Controls"));
361 send_full_time_code (0);
362 _engine.transport_locate (0);
364 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
365 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
367 MidiClockTicker::instance().set_session (this);
368 MIDI::Name::MidiPatchManager::instance().set_session (this);
370 /* initial program change will be delivered later; see ::config_changed() */
372 _state_of_the_state = Clean;
374 Port::set_connecting_blocked (false);
376 DirtyChanged (); /* EMIT SIGNAL */
378 if (state_was_pending) {
379 save_state (_current_snapshot_name);
380 remove_pending_capture_state ();
381 state_was_pending = false;
384 BootMessage (_("Session loading complete"));
390 Session::raid_path () const
392 SearchPath raid_search_path;
394 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
395 raid_search_path += sys::path((*i).path);
398 return raid_search_path.to_string ();
402 Session::setup_raid_path (string path)
411 session_dirs.clear ();
413 SearchPath search_path(path);
414 SearchPath sound_search_path;
415 SearchPath midi_search_path;
417 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
418 sp.path = (*i).to_string ();
419 sp.blocks = 0; // not needed
420 session_dirs.push_back (sp);
422 SessionDirectory sdir(sp.path);
424 sound_search_path += sdir.sound_path ();
425 midi_search_path += sdir.midi_path ();
428 // reset the round-robin soundfile path thingie
429 last_rr_session_dir = session_dirs.begin();
433 Session::path_is_within_session (const std::string& path)
435 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
436 if (path.find ((*i).path) == 0) {
444 Session::ensure_subdirs ()
448 dir = session_directory().peak_path().to_string();
450 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
451 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
455 dir = session_directory().sound_path().to_string();
457 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
458 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
462 dir = session_directory().midi_path().to_string();
464 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
465 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
469 dir = session_directory().dead_path().to_string();
471 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
472 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
476 dir = session_directory().export_path().to_string();
478 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
479 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
483 dir = analysis_dir ();
485 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
486 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
490 dir = plugins_dir ();
492 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
493 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
500 /** Caller must not hold process lock */
502 Session::create (const string& mix_template, BusProfile* bus_profile)
504 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
505 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
509 if (ensure_subdirs ()) {
513 _writable = exists_and_writable (sys::path (_path));
515 if (!mix_template.empty()) {
516 std::string in_path = mix_template;
518 ifstream in(in_path.c_str());
521 string out_path = _path;
523 out_path += statefile_suffix;
525 ofstream out(out_path.c_str());
533 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
539 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
546 /* Instantiate metadata */
548 _metadata = new SessionMetadata ();
550 /* set initial start + end point */
552 _state_of_the_state = Clean;
554 /* set up Master Out and Control Out if necessary */
560 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
562 if (bus_profile->master_out_channels) {
563 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
567 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
568 boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
571 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
572 r->input()->ensure_io (count, false, this);
573 r->output()->ensure_io (count, false, this);
575 r->set_remote_control_id (control_id++);
579 if (Config->get_use_monitor_bus()) {
580 boost::shared_ptr<Route> r (new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO));
584 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
585 boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
588 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
589 r->input()->ensure_io (count, false, this);
590 r->output()->ensure_io (count, false, this);
592 r->set_remote_control_id (control_id);
598 /* prohibit auto-connect to master, because there isn't one */
599 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
603 add_routes (rl, false, false);
606 /* this allows the user to override settings with an environment variable.
609 if (no_auto_connect()) {
610 bus_profile->input_ac = AutoConnectOption (0);
611 bus_profile->output_ac = AutoConnectOption (0);
614 Config->set_input_auto_connect (bus_profile->input_ac);
615 Config->set_output_auto_connect (bus_profile->output_ac);
624 Session::maybe_write_autosave()
626 if (dirty() && record_status() != Recording) {
627 save_state("", true);
632 Session::remove_pending_capture_state ()
634 sys::path pending_state_file_path(_session_dir->root_path());
636 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
640 sys::remove (pending_state_file_path);
642 catch(sys::filesystem_error& ex)
644 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
645 pending_state_file_path.to_string(), ex.what()) << endmsg;
649 /** Rename a state file.
650 * @param old_name Old snapshot name.
651 * @param new_name New snapshot name.
654 Session::rename_state (string old_name, string new_name)
656 if (old_name == _current_snapshot_name || old_name == _name) {
657 /* refuse to rename the current snapshot or the "main" one */
661 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
662 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
664 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
665 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
669 sys::rename (old_xml_path, new_xml_path);
671 catch (const sys::filesystem_error& err)
673 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
674 old_name, new_name, err.what()) << endmsg;
678 /** Remove a state file.
679 * @param snapshot_name Snapshot name.
682 Session::remove_state (string snapshot_name)
684 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
685 // refuse to remove the current snapshot or the "main" one
689 sys::path xml_path(_session_dir->root_path());
691 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
693 if (!create_backup_file (xml_path)) {
694 // don't remove it if a backup can't be made
695 // create_backup_file will log the error.
700 sys::remove (xml_path);
703 #ifdef HAVE_JACK_SESSION
705 Session::jack_session_event (jack_session_event_t * event)
709 struct tm local_time;
712 localtime_r (&n, &local_time);
713 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
715 if (event->type == JackSessionSaveTemplate)
717 if (save_template( timebuf )) {
718 event->flags = JackSessionSaveError;
720 string cmd ("ardour3 -P -U ");
721 cmd += event->client_uuid;
725 event->command_line = strdup (cmd.c_str());
730 if (save_state (timebuf)) {
731 event->flags = JackSessionSaveError;
733 sys::path xml_path (_session_dir->root_path());
734 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
736 string cmd ("ardour3 -P -U ");
737 cmd += event->client_uuid;
739 cmd += xml_path.to_string();
742 event->command_line = strdup (cmd.c_str());
746 jack_session_reply (_engine.jack(), event);
748 if (event->type == JackSessionSaveAndQuit) {
749 Quit (); /* EMIT SIGNAL */
752 jack_session_event_free( event );
756 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
758 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
761 sys::path xml_path(_session_dir->root_path());
763 if (!_writable || (_state_of_the_state & CannotSave)) {
767 if (!_engine.connected ()) {
768 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
774 /* tell sources we're saving first, in case they write out to a new file
775 * which should be saved with the state rather than the old one */
776 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
777 i->second->session_saved();
780 tree.set_root (&get_state());
782 if (snapshot_name.empty()) {
783 snapshot_name = _current_snapshot_name;
784 } else if (switch_to_snapshot) {
785 _current_snapshot_name = snapshot_name;
790 /* proper save: use statefile_suffix (.ardour in English) */
792 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
794 /* make a backup copy of the old file */
796 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
797 // create_backup_file will log the error
803 /* pending save: use pending_suffix (.pending in English) */
804 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
807 sys::path tmp_path(_session_dir->root_path());
809 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
811 // cerr << "actually writing state to " << xml_path.to_string() << endl;
813 if (!tree.write (tmp_path.to_string())) {
814 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
815 sys::remove (tmp_path);
820 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
821 error << string_compose (_("could not rename temporary session file %1 to %2"),
822 tmp_path.to_string(), xml_path.to_string()) << endmsg;
823 sys::remove (tmp_path);
830 save_history (snapshot_name);
832 bool was_dirty = dirty();
834 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
837 DirtyChanged (); /* EMIT SIGNAL */
840 StateSaved (snapshot_name); /* EMIT SIGNAL */
847 Session::restore_state (string snapshot_name)
849 if (load_state (snapshot_name) == 0) {
850 set_state (*state_tree->root(), Stateful::loading_state_version);
857 Session::load_state (string snapshot_name)
862 state_was_pending = false;
864 /* check for leftover pending state from a crashed capture attempt */
866 sys::path xmlpath(_session_dir->root_path());
867 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
869 if (sys::exists (xmlpath)) {
871 /* there is pending state from a crashed capture attempt */
873 boost::optional<int> r = AskAboutPendingState();
874 if (r.get_value_or (1)) {
875 state_was_pending = true;
879 if (!state_was_pending) {
880 xmlpath = _session_dir->root_path();
881 xmlpath /= snapshot_name;
884 if (!sys::exists (xmlpath)) {
885 xmlpath = _session_dir->root_path();
886 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
887 if (!sys::exists (xmlpath)) {
888 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
893 state_tree = new XMLTree;
897 _writable = exists_and_writable (xmlpath);
899 if (!state_tree->read (xmlpath.to_string())) {
900 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
906 XMLNode& root (*state_tree->root());
908 if (root.name() != X_("Session")) {
909 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
915 const XMLProperty* prop;
917 if ((prop = root.property ("version")) == 0) {
918 /* no version implies very old version of Ardour */
919 Stateful::loading_state_version = 1000;
925 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
926 Stateful::loading_state_version = (major * 1000) + minor;
929 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
931 sys::path backup_path(_session_dir->root_path());
933 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
935 // only create a backup once
936 if (sys::exists (backup_path)) {
940 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
941 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
946 sys::copy_file (xmlpath, backup_path);
948 catch(sys::filesystem_error& ex)
950 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
951 xmlpath.to_string(), ex.what())
961 Session::load_options (const XMLNode& node)
963 LocaleGuard lg (X_("POSIX"));
964 config.set_variables (node);
975 Session::get_template()
977 /* if we don't disable rec-enable, diskstreams
978 will believe they need to store their capture
979 sources in their state node.
982 disable_record (false);
988 Session::state(bool full_state)
990 XMLNode* node = new XMLNode("Session");
993 // store libardour version, just in case
995 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
996 node->add_property("version", string(buf));
998 /* store configuration settings */
1002 node->add_property ("name", _name);
1003 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1004 node->add_property ("sample-rate", buf);
1006 if (session_dirs.size() > 1) {
1010 vector<space_and_path>::iterator i = session_dirs.begin();
1011 vector<space_and_path>::iterator next;
1013 ++i; /* skip the first one */
1017 while (i != session_dirs.end()) {
1021 if (next != session_dirs.end()) {
1031 child = node->add_child ("Path");
1032 child->add_content (p);
1036 /* save the ID counter */
1038 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1039 node->add_property ("id-counter", buf);
1041 /* save the event ID counter */
1043 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1044 node->add_property ("event-counter", buf);
1046 /* various options */
1048 node->add_child_nocopy (config.get_variables ());
1050 node->add_child_nocopy (_metadata->get_state());
1052 child = node->add_child ("Sources");
1055 Glib::Mutex::Lock sl (source_lock);
1057 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1059 /* Don't save information about non-file Sources, or
1060 * about non-destructive file sources that are empty
1061 * and unused by any regions.
1064 boost::shared_ptr<FileSource> fs;
1066 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1068 if (!fs->destructive()) {
1069 if (fs->empty() && !fs->used()) {
1074 child->add_child_nocopy (siter->second->get_state());
1079 child = node->add_child ("Regions");
1082 Glib::Mutex::Lock rl (region_lock);
1083 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1084 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1085 boost::shared_ptr<Region> r = i->second;
1086 /* only store regions not attached to playlists */
1087 if (r->playlist() == 0) {
1088 child->add_child_nocopy (r->state ());
1092 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1094 if (!cassocs.empty()) {
1095 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1097 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1099 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1100 i->first->id().print (buf, sizeof (buf));
1101 can->add_property (X_("copy"), buf);
1102 i->second->id().print (buf, sizeof (buf));
1103 can->add_property (X_("original"), buf);
1104 ca->add_child_nocopy (*can);
1110 node->add_child_nocopy (_locations->get_state());
1112 // for a template, just create a new Locations, populate it
1113 // with the default start and end, and get the state for that.
1114 Locations loc (*this);
1115 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1116 range->set (max_framepos, 0);
1118 node->add_child_nocopy (loc.get_state());
1121 child = node->add_child ("Bundles");
1123 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1124 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1125 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1127 child->add_child_nocopy (b->get_state());
1132 child = node->add_child ("Routes");
1134 boost::shared_ptr<RouteList> r = routes.reader ();
1136 RoutePublicOrderSorter cmp;
1137 RouteList public_order (*r);
1138 public_order.sort (cmp);
1140 /* the sort should have put control outs first */
1143 assert (_monitor_out == public_order.front());
1146 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1147 if (!(*i)->is_hidden()) {
1149 child->add_child_nocopy ((*i)->get_state());
1151 child->add_child_nocopy ((*i)->get_template());
1157 playlists->add_state (node, full_state);
1159 child = node->add_child ("RouteGroups");
1160 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1161 child->add_child_nocopy ((*i)->get_state());
1165 child = node->add_child ("Click");
1166 child->add_child_nocopy (_click_io->state (full_state));
1170 child = node->add_child ("NamedSelections");
1171 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1173 child->add_child_nocopy ((*i)->get_state());
1178 node->add_child_nocopy (_speakers->get_state());
1179 node->add_child_nocopy (_tempo_map->get_state());
1180 node->add_child_nocopy (get_control_protocol_state());
1183 node->add_child_copy (*_extra_xml);
1190 Session::get_control_protocol_state ()
1192 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1193 return cpm.get_state();
1197 Session::set_state (const XMLNode& node, int version)
1201 const XMLProperty* prop;
1204 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1206 if (node.name() != X_("Session")) {
1207 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1211 if ((prop = node.property ("version")) != 0) {
1212 version = atoi (prop->value ()) * 1000;
1215 if ((prop = node.property ("name")) != 0) {
1216 _name = prop->value ();
1219 if ((prop = node.property (X_("sample-rate"))) != 0) {
1221 _nominal_frame_rate = atoi (prop->value());
1223 if (_nominal_frame_rate != _current_frame_rate) {
1224 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1225 if (r.get_value_or (0)) {
1231 setup_raid_path(_session_dir->root_path().to_string());
1233 if ((prop = node.property (X_("id-counter"))) != 0) {
1235 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1236 ID::init_counter (x);
1238 /* old sessions used a timebased counter, so fake
1239 the startup ID counter based on a standard
1244 ID::init_counter (now);
1247 if ((prop = node.property (X_("event-counter"))) != 0) {
1248 Evoral::init_event_id_counter (atoi (prop->value()));
1251 IO::disable_connecting ();
1253 if ((child = find_named_node (node, "Extra")) != 0) {
1254 _extra_xml = new XMLNode (*child);
1257 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1258 load_options (*child);
1259 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1260 load_options (*child);
1262 error << _("Session: XML state has no options section") << endmsg;
1265 if (version >= 3000) {
1266 if ((child = find_named_node (node, "Metadata")) == 0) {
1267 warning << _("Session: XML state has no metadata section") << endmsg;
1268 } else if (_metadata->set_state (*child, version)) {
1273 if ((child = find_named_node (node, "Locations")) == 0) {
1274 error << _("Session: XML state has no locations section") << endmsg;
1276 } else if (_locations->set_state (*child, version)) {
1280 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1281 _speakers->set_state (*child, version);
1286 if ((location = _locations->auto_loop_location()) != 0) {
1287 set_auto_loop_location (location);
1290 if ((location = _locations->auto_punch_location()) != 0) {
1291 set_auto_punch_location (location);
1294 if ((location = _locations->session_range_location()) != 0) {
1295 delete _session_range_location;
1296 _session_range_location = location;
1299 if (_session_range_location) {
1300 AudioFileSource::set_header_position_offset (_session_range_location->start());
1303 if ((child = find_named_node (node, "Sources")) == 0) {
1304 error << _("Session: XML state has no sources section") << endmsg;
1306 } else if (load_sources (*child)) {
1310 if ((child = find_named_node (node, "TempoMap")) == 0) {
1311 error << _("Session: XML state has no Tempo Map section") << endmsg;
1313 } else if (_tempo_map->set_state (*child, version)) {
1317 if ((child = find_named_node (node, "Regions")) == 0) {
1318 error << _("Session: XML state has no Regions section") << endmsg;
1320 } else if (load_regions (*child)) {
1324 if ((child = find_named_node (node, "Playlists")) == 0) {
1325 error << _("Session: XML state has no playlists section") << endmsg;
1327 } else if (playlists->load (*this, *child)) {
1331 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1333 } else if (playlists->load_unused (*this, *child)) {
1337 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1338 if (load_compounds (*child)) {
1343 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1344 if (load_named_selections (*child)) {
1349 if (version >= 3000) {
1350 if ((child = find_named_node (node, "Bundles")) == 0) {
1351 warning << _("Session: XML state has no bundles section") << endmsg;
1354 /* We can't load Bundles yet as they need to be able
1355 to convert from port names to Port objects, which can't happen until
1357 _bundle_xml_node = new XMLNode (*child);
1361 if (version < 3000) {
1362 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1363 error << _("Session: XML state has no diskstreams section") << endmsg;
1365 } else if (load_diskstreams_2X (*child, version)) {
1370 if ((child = find_named_node (node, "Routes")) == 0) {
1371 error << _("Session: XML state has no routes section") << endmsg;
1373 } else if (load_routes (*child, version)) {
1377 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1378 _diskstreams_2X.clear ();
1380 if (version >= 3000) {
1382 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1383 error << _("Session: XML state has no route groups section") << endmsg;
1385 } else if (load_route_groups (*child, version)) {
1389 } else if (version < 3000) {
1391 if ((child = find_named_node (node, "EditGroups")) == 0) {
1392 error << _("Session: XML state has no edit groups section") << endmsg;
1394 } else if (load_route_groups (*child, version)) {
1398 if ((child = find_named_node (node, "MixGroups")) == 0) {
1399 error << _("Session: XML state has no mix groups section") << endmsg;
1401 } else if (load_route_groups (*child, version)) {
1406 if ((child = find_named_node (node, "Click")) == 0) {
1407 warning << _("Session: XML state has no click section") << endmsg;
1408 } else if (_click_io) {
1409 _click_io->set_state (*child, version);
1412 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1413 ControlProtocolManager::instance().set_protocol_states (*child);
1416 /* here beginneth the second phase ... */
1418 StateReady (); /* EMIT SIGNAL */
1427 Session::load_routes (const XMLNode& node, int version)
1430 XMLNodeConstIterator niter;
1431 RouteList new_routes;
1433 nlist = node.children();
1437 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1439 boost::shared_ptr<Route> route;
1440 if (version < 3000) {
1441 route = XMLRouteFactory_2X (**niter, version);
1443 route = XMLRouteFactory (**niter, version);
1447 error << _("Session: cannot create Route from XML description.") << endmsg;
1451 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1453 new_routes.push_back (route);
1456 add_routes (new_routes, false, false);
1461 boost::shared_ptr<Route>
1462 Session::XMLRouteFactory (const XMLNode& node, int version)
1464 boost::shared_ptr<Route> ret;
1466 if (node.name() != "Route") {
1470 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1472 DataType type = DataType::AUDIO;
1473 const XMLProperty* prop = node.property("default-type");
1476 type = DataType (prop->value());
1479 assert (type != DataType::NIL);
1483 boost::shared_ptr<Track> track;
1485 if (type == DataType::AUDIO) {
1486 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1488 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1491 if (track->init()) {
1495 if (track->set_state (node, version)) {
1499 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1500 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1505 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1507 if (r->init () == 0 && r->set_state (node, version) == 0) {
1508 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1509 boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1518 boost::shared_ptr<Route>
1519 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1521 boost::shared_ptr<Route> ret;
1523 if (node.name() != "Route") {
1527 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1529 ds_prop = node.property (X_("diskstream"));
1532 DataType type = DataType::AUDIO;
1533 const XMLProperty* prop = node.property("default-type");
1536 type = DataType (prop->value());
1539 assert (type != DataType::NIL);
1543 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1544 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1548 if (i == _diskstreams_2X.end()) {
1549 error << _("Could not find diskstream for route") << endmsg;
1550 return boost::shared_ptr<Route> ();
1553 boost::shared_ptr<Track> track;
1555 if (type == DataType::AUDIO) {
1556 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1558 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1561 if (track->init()) {
1565 if (track->set_state (node, version)) {
1569 track->set_diskstream (*i);
1571 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1572 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1577 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1579 if (r->init () == 0 && r->set_state (node, version) == 0) {
1580 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1581 boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1591 Session::load_regions (const XMLNode& node)
1594 XMLNodeConstIterator niter;
1595 boost::shared_ptr<Region> region;
1597 nlist = node.children();
1601 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1602 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1603 error << _("Session: cannot create Region from XML description.");
1604 const XMLProperty *name = (**niter).property("name");
1607 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1618 Session::load_compounds (const XMLNode& node)
1620 XMLNodeList calist = node.children();
1621 XMLNodeConstIterator caiter;
1622 XMLProperty *caprop;
1624 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1625 XMLNode* ca = *caiter;
1629 if ((caprop = ca->property (X_("original"))) == 0) {
1632 orig_id = caprop->value();
1634 if ((caprop = ca->property (X_("copy"))) == 0) {
1637 copy_id = caprop->value();
1639 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1640 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1642 if (!orig || !copy) {
1643 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1649 RegionFactory::add_compound_association (orig, copy);
1656 Session::load_nested_sources (const XMLNode& node)
1659 XMLNodeConstIterator niter;
1661 nlist = node.children();
1663 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1664 if ((*niter)->name() == "Source") {
1666 SourceFactory::create (*this, **niter, true);
1668 catch (failed_constructor& err) {
1669 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1675 boost::shared_ptr<Region>
1676 Session::XMLRegionFactory (const XMLNode& node, bool full)
1678 const XMLProperty* type = node.property("type");
1682 const XMLNodeList& nlist = node.children();
1684 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1685 XMLNode *child = (*niter);
1686 if (child->name() == "NestedSource") {
1687 load_nested_sources (*child);
1691 if (!type || type->value() == "audio") {
1692 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1693 } else if (type->value() == "midi") {
1694 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1697 } catch (failed_constructor& err) {
1698 return boost::shared_ptr<Region> ();
1701 return boost::shared_ptr<Region> ();
1704 boost::shared_ptr<AudioRegion>
1705 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1707 const XMLProperty* prop;
1708 boost::shared_ptr<Source> source;
1709 boost::shared_ptr<AudioSource> as;
1711 SourceList master_sources;
1712 uint32_t nchans = 1;
1715 if (node.name() != X_("Region")) {
1716 return boost::shared_ptr<AudioRegion>();
1719 if ((prop = node.property (X_("channels"))) != 0) {
1720 nchans = atoi (prop->value().c_str());
1723 if ((prop = node.property ("name")) == 0) {
1724 cerr << "no name for this region\n";
1728 if ((prop = node.property (X_("source-0"))) == 0) {
1729 if ((prop = node.property ("source")) == 0) {
1730 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1731 return boost::shared_ptr<AudioRegion>();
1735 PBD::ID s_id (prop->value());
1737 if ((source = source_by_id (s_id)) == 0) {
1738 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1739 return boost::shared_ptr<AudioRegion>();
1742 as = boost::dynamic_pointer_cast<AudioSource>(source);
1744 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1745 return boost::shared_ptr<AudioRegion>();
1748 sources.push_back (as);
1750 /* pickup other channels */
1752 for (uint32_t n=1; n < nchans; ++n) {
1753 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1754 if ((prop = node.property (buf)) != 0) {
1756 PBD::ID id2 (prop->value());
1758 if ((source = source_by_id (id2)) == 0) {
1759 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1760 return boost::shared_ptr<AudioRegion>();
1763 as = boost::dynamic_pointer_cast<AudioSource>(source);
1765 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1766 return boost::shared_ptr<AudioRegion>();
1768 sources.push_back (as);
1772 for (uint32_t n = 0; n < nchans; ++n) {
1773 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1774 if ((prop = node.property (buf)) != 0) {
1776 PBD::ID id2 (prop->value());
1778 if ((source = source_by_id (id2)) == 0) {
1779 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1780 return boost::shared_ptr<AudioRegion>();
1783 as = boost::dynamic_pointer_cast<AudioSource>(source);
1785 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1786 return boost::shared_ptr<AudioRegion>();
1788 master_sources.push_back (as);
1793 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1795 /* a final detail: this is the one and only place that we know how long missing files are */
1797 if (region->whole_file()) {
1798 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1799 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1801 sfp->set_length (region->length());
1806 if (!master_sources.empty()) {
1807 if (master_sources.size() != nchans) {
1808 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1810 region->set_master_sources (master_sources);
1818 catch (failed_constructor& err) {
1819 return boost::shared_ptr<AudioRegion>();
1823 boost::shared_ptr<MidiRegion>
1824 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1826 const XMLProperty* prop;
1827 boost::shared_ptr<Source> source;
1828 boost::shared_ptr<MidiSource> ms;
1831 if (node.name() != X_("Region")) {
1832 return boost::shared_ptr<MidiRegion>();
1835 if ((prop = node.property ("name")) == 0) {
1836 cerr << "no name for this region\n";
1840 if ((prop = node.property (X_("source-0"))) == 0) {
1841 if ((prop = node.property ("source")) == 0) {
1842 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1843 return boost::shared_ptr<MidiRegion>();
1847 PBD::ID s_id (prop->value());
1849 if ((source = source_by_id (s_id)) == 0) {
1850 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1851 return boost::shared_ptr<MidiRegion>();
1854 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1856 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1857 return boost::shared_ptr<MidiRegion>();
1860 sources.push_back (ms);
1863 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1864 /* a final detail: this is the one and only place that we know how long missing files are */
1866 if (region->whole_file()) {
1867 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1868 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1870 sfp->set_length (region->length());
1878 catch (failed_constructor& err) {
1879 return boost::shared_ptr<MidiRegion>();
1884 Session::get_sources_as_xml ()
1887 XMLNode* node = new XMLNode (X_("Sources"));
1888 Glib::Mutex::Lock lm (source_lock);
1890 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1891 node->add_child_nocopy (i->second->get_state());
1898 Session::path_from_region_name (DataType type, string name, string identifier)
1900 char buf[PATH_MAX+1];
1902 SessionDirectory sdir(get_best_session_directory_for_new_source());
1903 sys::path source_dir = ((type == DataType::AUDIO)
1904 ? sdir.sound_path() : sdir.midi_path());
1906 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1908 for (n = 0; n < 999999; ++n) {
1909 if (identifier.length()) {
1910 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1911 identifier.c_str(), n, ext.c_str());
1913 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1917 sys::path source_path = source_dir / buf;
1919 if (!sys::exists (source_path)) {
1920 return source_path.to_string();
1924 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1933 Session::load_sources (const XMLNode& node)
1936 XMLNodeConstIterator niter;
1937 boost::shared_ptr<Source> source;
1939 nlist = node.children();
1943 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1946 if ((source = XMLSourceFactory (**niter)) == 0) {
1947 error << _("Session: cannot create Source from XML description.") << endmsg;
1950 } catch (MissingSource& err) {
1954 if (!no_questions_about_missing_files) {
1955 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1960 switch (user_choice) {
1962 /* user added a new search location, so try again */
1967 /* user asked to quit the entire session load
1972 no_questions_about_missing_files = true;
1976 no_questions_about_missing_files = true;
1981 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1982 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1991 boost::shared_ptr<Source>
1992 Session::XMLSourceFactory (const XMLNode& node)
1994 if (node.name() != "Source") {
1995 return boost::shared_ptr<Source>();
1999 /* note: do peak building in another thread when loading session state */
2000 return SourceFactory::create (*this, node, true);
2003 catch (failed_constructor& err) {
2004 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2005 return boost::shared_ptr<Source>();
2010 Session::save_template (string template_name)
2014 if (_state_of_the_state & CannotSave) {
2018 sys::path user_template_dir(user_template_directory());
2022 sys::create_directories (user_template_dir);
2024 catch(sys::filesystem_error& ex)
2026 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
2027 user_template_dir.to_string(), ex.what()) << endmsg;
2031 tree.set_root (&get_template());
2033 sys::path template_file_path(user_template_dir);
2034 template_file_path /= template_name + template_suffix;
2036 if (sys::exists (template_file_path))
2038 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2039 template_file_path.to_string()) << endmsg;
2043 if (!tree.write (template_file_path.to_string())) {
2044 error << _("template not saved") << endmsg;
2052 Session::rename_template (string old_name, string new_name)
2054 sys::path old_path (user_template_directory());
2055 old_path /= old_name + template_suffix;
2057 sys::path new_path(user_template_directory());
2058 new_path /= new_name + template_suffix;
2060 if (sys::exists (new_path)) {
2061 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
2062 new_path.to_string()) << endmsg;
2067 sys::rename (old_path, new_path);
2075 Session::delete_template (string name)
2077 sys::path path = user_template_directory();
2078 path /= name + template_suffix;
2089 Session::refresh_disk_space ()
2092 struct statfs statfsbuf;
2093 vector<space_and_path>::iterator i;
2094 Glib::Mutex::Lock lm (space_lock);
2097 /* get freespace on every FS that is part of the session path */
2099 _total_free_4k_blocks = 0;
2101 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2102 statfs ((*i).path.c_str(), &statfsbuf);
2104 scale = statfsbuf.f_bsize/4096.0;
2106 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2107 _total_free_4k_blocks += (*i).blocks;
2113 Session::get_best_session_directory_for_new_source ()
2115 vector<space_and_path>::iterator i;
2116 string result = _session_dir->root_path().to_string();
2118 /* handle common case without system calls */
2120 if (session_dirs.size() == 1) {
2124 /* OK, here's the algorithm we're following here:
2126 We want to select which directory to use for
2127 the next file source to be created. Ideally,
2128 we'd like to use a round-robin process so as to
2129 get maximum performance benefits from splitting
2130 the files across multiple disks.
2132 However, in situations without much diskspace, an
2133 RR approach may end up filling up a filesystem
2134 with new files while others still have space.
2135 Its therefore important to pay some attention to
2136 the freespace in the filesystem holding each
2137 directory as well. However, if we did that by
2138 itself, we'd keep creating new files in the file
2139 system with the most space until it was as full
2140 as all others, thus negating any performance
2141 benefits of this RAID-1 like approach.
2143 So, we use a user-configurable space threshold. If
2144 there are at least 2 filesystems with more than this
2145 much space available, we use RR selection between them.
2146 If not, then we pick the filesystem with the most space.
2148 This gets a good balance between the two
2152 refresh_disk_space ();
2154 int free_enough = 0;
2156 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2157 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2162 if (free_enough >= 2) {
2163 /* use RR selection process, ensuring that the one
2167 i = last_rr_session_dir;
2170 if (++i == session_dirs.end()) {
2171 i = session_dirs.begin();
2174 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2175 if (create_session_directory ((*i).path)) {
2177 last_rr_session_dir = i;
2182 } while (i != last_rr_session_dir);
2186 /* pick FS with the most freespace (and that
2187 seems to actually work ...)
2190 vector<space_and_path> sorted;
2191 space_and_path_ascending_cmp cmp;
2193 sorted = session_dirs;
2194 sort (sorted.begin(), sorted.end(), cmp);
2196 for (i = sorted.begin(); i != sorted.end(); ++i) {
2197 if (create_session_directory ((*i).path)) {
2199 last_rr_session_dir = i;
2209 Session::load_named_selections (const XMLNode& node)
2212 XMLNodeConstIterator niter;
2215 nlist = node.children();
2219 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2221 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2222 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2230 Session::XMLNamedSelectionFactory (const XMLNode& node)
2233 return new NamedSelection (*this, node);
2236 catch (failed_constructor& err) {
2242 Session::automation_dir () const
2244 return Glib::build_filename (_path, "automation");
2248 Session::analysis_dir () const
2250 return Glib::build_filename (_path, "analysis");
2254 Session::plugins_dir () const
2256 return Glib::build_filename (_path, "plugins");
2260 Session::load_bundles (XMLNode const & node)
2262 XMLNodeList nlist = node.children();
2263 XMLNodeConstIterator niter;
2267 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2268 if ((*niter)->name() == "InputBundle") {
2269 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2270 } else if ((*niter)->name() == "OutputBundle") {
2271 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2273 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2282 Session::load_route_groups (const XMLNode& node, int version)
2284 XMLNodeList nlist = node.children();
2285 XMLNodeConstIterator niter;
2289 if (version >= 3000) {
2291 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2292 if ((*niter)->name() == "RouteGroup") {
2293 RouteGroup* rg = new RouteGroup (*this, "");
2294 add_route_group (rg);
2295 rg->set_state (**niter, version);
2299 } else if (version < 3000) {
2301 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2302 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2303 RouteGroup* rg = new RouteGroup (*this, "");
2304 add_route_group (rg);
2305 rg->set_state (**niter, version);
2314 Session::auto_save()
2316 save_state (_current_snapshot_name);
2320 state_file_filter (const string &str, void */*arg*/)
2322 return (str.length() > strlen(statefile_suffix) &&
2323 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2327 bool operator()(const string* a, const string* b) {
2333 remove_end(string* state)
2335 string statename(*state);
2337 string::size_type start,end;
2338 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2339 statename = statename.substr (start+1);
2342 if ((end = statename.rfind(".ardour")) == string::npos) {
2343 end = statename.length();
2346 return new string(statename.substr (0, end));
2350 Session::possible_states (string path)
2352 PathScanner scanner;
2353 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2355 transform(states->begin(), states->end(), states->begin(), remove_end);
2358 sort (states->begin(), states->end(), cmp);
2364 Session::possible_states () const
2366 return possible_states(_path);
2370 Session::add_route_group (RouteGroup* g)
2372 _route_groups.push_back (g);
2373 route_group_added (g); /* EMIT SIGNAL */
2375 g->MembershipChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2376 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2382 Session::remove_route_group (RouteGroup& rg)
2384 list<RouteGroup*>::iterator i;
2386 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2387 _route_groups.erase (i);
2390 route_group_removed (); /* EMIT SIGNAL */
2394 /** Set a new order for our route groups, without adding or removing any.
2395 * @param groups Route group list in the new order.
2398 Session::reorder_route_groups (list<RouteGroup*> groups)
2400 _route_groups = groups;
2402 route_groups_reordered (); /* EMIT SIGNAL */
2408 Session::route_group_by_name (string name)
2410 list<RouteGroup *>::iterator i;
2412 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2413 if ((*i)->name() == name) {
2421 Session::all_route_group() const
2423 return *_all_route_group;
2427 Session::add_commands (vector<Command*> const & cmds)
2429 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2435 Session::begin_reversible_command (const string& name)
2437 begin_reversible_command (g_quark_from_string (name.c_str ()));
2440 /** Begin a reversible command using a GQuark to identify it.
2441 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2442 * but there must be as many begin...()s as there are commit...()s.
2445 Session::begin_reversible_command (GQuark q)
2447 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2448 to hold all the commands that are committed. This keeps the order of
2449 commands correct in the history.
2452 if (_current_trans == 0) {
2453 /* start a new transaction */
2454 assert (_current_trans_quarks.empty ());
2455 _current_trans = new UndoTransaction();
2456 _current_trans->set_name (g_quark_to_string (q));
2459 _current_trans_quarks.push_front (q);
2463 Session::commit_reversible_command (Command *cmd)
2465 assert (_current_trans);
2466 assert (!_current_trans_quarks.empty ());
2471 _current_trans->add_command (cmd);
2474 _current_trans_quarks.pop_front ();
2476 if (!_current_trans_quarks.empty ()) {
2477 /* the transaction we're committing is not the top-level one */
2481 if (_current_trans->empty()) {
2482 /* no commands were added to the transaction, so just get rid of it */
2483 delete _current_trans;
2488 gettimeofday (&now, 0);
2489 _current_trans->set_timestamp (now);
2491 _history.add (_current_trans);
2496 accept_all_audio_files (const string& path, void */*arg*/)
2498 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2502 if (!AudioFileSource::safe_audio_file_extension (path)) {
2510 accept_all_midi_files (const string& path, void */*arg*/)
2512 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2516 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2517 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2518 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2522 accept_all_state_files (const string& path, void */*arg*/)
2524 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2528 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2532 Session::find_all_sources (string path, set<string>& result)
2537 if (!tree.read (path)) {
2541 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2546 XMLNodeConstIterator niter;
2548 nlist = node->children();
2552 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2556 if ((prop = (*niter)->property (X_("type"))) == 0) {
2560 DataType type (prop->value());
2562 if ((prop = (*niter)->property (X_("name"))) == 0) {
2566 if (Glib::path_is_absolute (prop->value())) {
2567 /* external file, ignore */
2575 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2576 result.insert (found_path);
2584 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2586 PathScanner scanner;
2587 vector<string*>* state_files;
2589 string this_snapshot_path;
2595 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2596 ripped = ripped.substr (0, ripped.length() - 1);
2599 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2601 if (state_files == 0) {
2606 this_snapshot_path = _path;
2607 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2608 this_snapshot_path += statefile_suffix;
2610 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2612 if (exclude_this_snapshot && **i == this_snapshot_path) {
2616 if (find_all_sources (**i, result) < 0) {
2624 struct RegionCounter {
2625 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2626 AudioSourceList::iterator iter;
2627 boost::shared_ptr<Region> region;
2630 RegionCounter() : count (0) {}
2634 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2636 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2637 return r.get_value_or (1);
2641 Session::cleanup_regions ()
2643 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2645 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2647 boost::shared_ptr<AudioRegion> audio_region = boost::dynamic_pointer_cast<AudioRegion>( i->second);
2649 if (!audio_region) {
2653 uint32_t used = playlists->region_use_count (audio_region);
2655 if (used == 0 && !audio_region->automatic()) {
2656 RegionFactory::map_remove(i->second);
2660 /* dump the history list */
2667 Session::cleanup_sources (CleanupReport& rep)
2669 // FIXME: needs adaptation to midi
2671 vector<boost::shared_ptr<Source> > dead_sources;
2672 PathScanner scanner;
2675 vector<space_and_path>::iterator i;
2676 vector<space_and_path>::iterator nexti;
2677 vector<string*>* candidates;
2678 vector<string*>* candidates2;
2679 vector<string> unused;
2680 set<string> all_sources;
2685 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2687 /* consider deleting all unused playlists */
2689 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2694 /* sync the "all regions" property of each playlist with its current state
2697 playlists->sync_all_regions_with_regions ();
2699 /* find all un-used sources */
2704 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2706 SourceMap::iterator tmp;
2711 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2715 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2716 dead_sources.push_back (i->second);
2717 i->second->drop_references ();
2723 /* build a list of all the possible audio directories for the session */
2725 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2730 SessionDirectory sdir ((*i).path);
2731 audio_path += sdir.sound_path().to_string();
2733 if (nexti != session_dirs.end()) {
2741 /* build a list of all the possible midi directories for the session */
2743 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2748 SessionDirectory sdir ((*i).path);
2749 midi_path += sdir.midi_path().to_string();
2751 if (nexti != session_dirs.end()) {
2758 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2759 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2765 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2766 candidates->push_back (*i);
2771 candidates = candidates2; // might still be null
2774 /* find all sources, but don't use this snapshot because the
2775 state file on disk still references sources we may have already
2779 find_all_sources_across_snapshots (all_sources, true);
2781 /* add our current source list
2784 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2785 boost::shared_ptr<FileSource> fs;
2786 SourceMap::iterator tmp = i;
2789 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2790 if (playlists->source_use_count (fs) != 0) {
2791 all_sources.insert (fs->path());
2794 /* we might not remove this source from disk, because it may be used
2795 by other snapshots, but its not being used in this version
2796 so lets get rid of it now, along with any representative regions
2800 RegionFactory::remove_regions_using_source (i->second);
2808 char tmppath1[PATH_MAX+1];
2809 char tmppath2[PATH_MAX+1];
2812 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2817 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2819 if (realpath(spath.c_str(), tmppath1) == 0) {
2820 error << string_compose (_("Cannot expand path %1 (%2)"),
2821 spath, strerror (errno)) << endmsg;
2825 if (realpath((*i).c_str(), tmppath2) == 0) {
2826 error << string_compose (_("Cannot expand path %1 (%2)"),
2827 (*i), strerror (errno)) << endmsg;
2831 if (strcmp(tmppath1, tmppath2) == 0) {
2838 unused.push_back (spath);
2847 /* now try to move all unused files into the "dead" directory(ies) */
2849 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2850 struct stat statbuf;
2854 /* don't move the file across filesystems, just
2855 stick it in the `dead_dir_name' directory
2856 on whichever filesystem it was already on.
2859 if ((*x).find ("/sounds/") != string::npos) {
2861 /* old school, go up 1 level */
2863 newpath = Glib::path_get_dirname (*x); // "sounds"
2864 newpath = Glib::path_get_dirname (newpath); // "session-name"
2868 /* new school, go up 4 levels */
2870 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2871 newpath = Glib::path_get_dirname (newpath); // "session-name"
2872 newpath = Glib::path_get_dirname (newpath); // "interchange"
2873 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2876 newpath = Glib::build_filename (newpath, dead_dir_name);
2878 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2879 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2883 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2885 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2887 /* the new path already exists, try versioning */
2889 char buf[PATH_MAX+1];
2893 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2896 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2897 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2901 if (version == 999) {
2902 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2906 newpath = newpath_v;
2911 /* it doesn't exist, or we can't read it or something */
2915 stat ((*x).c_str(), &statbuf);
2917 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2918 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2919 (*x), newpath, strerror (errno))
2924 /* see if there an easy to find peakfile for this file, and remove it.
2927 string base = basename_nosuffix (*x);
2928 base += "%A"; /* this is what we add for the channel suffix of all native files,
2929 or for the first channel of embedded files. it will miss
2930 some peakfiles for other channels
2932 string peakpath = peak_path (base);
2934 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2935 if (::unlink (peakpath.c_str()) != 0) {
2936 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2937 peakpath, _path, strerror (errno))
2939 /* try to back out */
2940 rename (newpath.c_str(), _path.c_str());
2945 rep.paths.push_back (*x);
2946 rep.space += statbuf.st_size;
2949 /* dump the history list */
2953 /* save state so we don't end up a session file
2954 referring to non-existent sources.
2961 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2967 Session::cleanup_trash_sources (CleanupReport& rep)
2969 // FIXME: needs adaptation for MIDI
2971 vector<space_and_path>::iterator i;
2977 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2979 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2981 clear_directory (dead_dir, &rep.space, &rep.paths);
2988 Session::set_dirty ()
2990 bool was_dirty = dirty();
2992 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2996 DirtyChanged(); /* EMIT SIGNAL */
3002 Session::set_clean ()
3004 bool was_dirty = dirty();
3006 _state_of_the_state = Clean;
3010 DirtyChanged(); /* EMIT SIGNAL */
3015 Session::set_deletion_in_progress ()
3017 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3021 Session::clear_deletion_in_progress ()
3023 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3027 Session::add_controllable (boost::shared_ptr<Controllable> c)
3029 /* this adds a controllable to the list managed by the Session.
3030 this is a subset of those managed by the Controllable class
3031 itself, and represents the only ones whose state will be saved
3032 as part of the session.
3035 Glib::Mutex::Lock lm (controllables_lock);
3036 controllables.insert (c);
3039 struct null_deleter { void operator()(void const *) const {} };
3042 Session::remove_controllable (Controllable* c)
3044 if (_state_of_the_state | Deletion) {
3048 Glib::Mutex::Lock lm (controllables_lock);
3050 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3052 if (x != controllables.end()) {
3053 controllables.erase (x);
3057 boost::shared_ptr<Controllable>
3058 Session::controllable_by_id (const PBD::ID& id)
3060 Glib::Mutex::Lock lm (controllables_lock);
3062 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3063 if ((*i)->id() == id) {
3068 return boost::shared_ptr<Controllable>();
3071 boost::shared_ptr<Controllable>
3072 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3074 boost::shared_ptr<Controllable> c;
3075 boost::shared_ptr<Route> r;
3077 switch (desc.top_level_type()) {
3078 case ControllableDescriptor::NamedRoute:
3080 std::string str = desc.top_level_name();
3081 if (str == "master") {
3083 } else if (str == "control" || str == "listen") {
3086 r = route_by_name (desc.top_level_name());
3091 case ControllableDescriptor::RemoteControlID:
3092 r = route_by_remote_id (desc.rid());
3100 switch (desc.subtype()) {
3101 case ControllableDescriptor::Gain:
3102 c = r->gain_control ();
3105 case ControllableDescriptor::Solo:
3106 c = r->solo_control();
3109 case ControllableDescriptor::Mute:
3110 c = r->mute_control();
3113 case ControllableDescriptor::Recenable:
3115 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3118 c = t->rec_enable_control ();
3123 case ControllableDescriptor::PanDirection:
3125 c = r->pannable()->pan_azimuth_control;
3129 case ControllableDescriptor::PanWidth:
3131 c = r->pannable()->pan_width_control;
3135 case ControllableDescriptor::PanElevation:
3137 c = r->pannable()->pan_elevation_control;
3141 case ControllableDescriptor::Balance:
3142 /* XXX simple pan control */
3145 case ControllableDescriptor::PluginParameter:
3147 uint32_t plugin = desc.target (0);
3148 uint32_t parameter_index = desc.target (1);
3150 /* revert to zero based counting */
3156 if (parameter_index > 0) {
3160 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3163 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3164 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3169 case ControllableDescriptor::SendGain:
3171 uint32_t send = desc.target (0);
3173 /* revert to zero-based counting */
3179 boost::shared_ptr<Processor> p = r->nth_send (send);
3182 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3183 boost::shared_ptr<Amp> a = s->amp();
3186 c = s->amp()->gain_control();
3193 /* relax and return a null pointer */
3201 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3204 Stateful::add_instant_xml (node, _path);
3207 if (write_to_config) {
3208 Config->add_instant_xml (node);
3213 Session::instant_xml (const string& node_name)
3215 return Stateful::instant_xml (node_name, _path);
3219 Session::save_history (string snapshot_name)
3227 if (snapshot_name.empty()) {
3228 snapshot_name = _current_snapshot_name;
3231 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3232 const string backup_filename = history_filename + backup_suffix;
3233 const sys::path xml_path = _session_dir->root_path() / history_filename;
3234 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3236 if (sys::exists (xml_path)) {
3239 sys::rename (xml_path, backup_path);
3241 catch (const sys::filesystem_error& err)
3243 error << _("could not backup old history file, current history not saved") << endmsg;
3248 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3252 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3254 if (!tree.write (xml_path.to_string()))
3256 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3260 sys::remove (xml_path);
3261 sys::rename (backup_path, xml_path);
3263 catch (const sys::filesystem_error& err)
3265 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3266 backup_path.to_string(), err.what()) << endmsg;
3276 Session::restore_history (string snapshot_name)
3280 if (snapshot_name.empty()) {
3281 snapshot_name = _current_snapshot_name;
3284 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3285 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3287 info << "Loading history from " << xml_path.to_string() << endmsg;
3289 if (!sys::exists (xml_path)) {
3290 info << string_compose (_("%1: no history file \"%2\" for this session."),
3291 _name, xml_path.to_string()) << endmsg;
3295 if (!tree.read (xml_path.to_string())) {
3296 error << string_compose (_("Could not understand session history file \"%1\""),
3297 xml_path.to_string()) << endmsg;
3304 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3307 UndoTransaction* ut = new UndoTransaction ();
3310 ut->set_name(t->property("name")->value());
3311 stringstream ss(t->property("tv-sec")->value());
3313 ss.str(t->property("tv-usec")->value());
3315 ut->set_timestamp(tv);
3317 for (XMLNodeConstIterator child_it = t->children().begin();
3318 child_it != t->children().end(); child_it++)
3320 XMLNode *n = *child_it;
3323 if (n->name() == "MementoCommand" ||
3324 n->name() == "MementoUndoCommand" ||
3325 n->name() == "MementoRedoCommand") {
3327 if ((c = memento_command_factory(n))) {
3331 } else if (n->name() == "NoteDiffCommand") {
3332 PBD::ID id (n->property("midi-source")->value());
3333 boost::shared_ptr<MidiSource> midi_source =
3334 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3336 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3338 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3341 } else if (n->name() == "SysExDiffCommand") {
3343 PBD::ID id (n->property("midi-source")->value());
3344 boost::shared_ptr<MidiSource> midi_source =
3345 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3347 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3349 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3352 } else if (n->name() == "PatchChangeDiffCommand") {
3354 PBD::ID id (n->property("midi-source")->value());
3355 boost::shared_ptr<MidiSource> midi_source =
3356 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3358 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3360 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3363 } else if (n->name() == "StatefulDiffCommand") {
3364 if ((c = stateful_diff_command_factory (n))) {
3365 ut->add_command (c);
3368 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3379 Session::config_changed (std::string p, bool ours)
3385 if (p == "seamless-loop") {
3387 } else if (p == "rf-speed") {
3389 } else if (p == "auto-loop") {
3391 } else if (p == "auto-input") {
3393 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3394 /* auto-input only makes a difference if we're rolling */
3395 set_track_monitor_input_status (!config.get_auto_input());
3398 } else if (p == "punch-in") {
3402 if ((location = _locations->auto_punch_location()) != 0) {
3404 if (config.get_punch_in ()) {
3405 replace_event (SessionEvent::PunchIn, location->start());
3407 remove_event (location->start(), SessionEvent::PunchIn);
3411 } else if (p == "punch-out") {
3415 if ((location = _locations->auto_punch_location()) != 0) {
3417 if (config.get_punch_out()) {
3418 replace_event (SessionEvent::PunchOut, location->end());
3420 clear_events (SessionEvent::PunchOut);
3424 } else if (p == "edit-mode") {
3426 Glib::Mutex::Lock lm (playlists->lock);
3428 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3429 (*i)->set_edit_mode (Config->get_edit_mode ());
3432 } else if (p == "use-video-sync") {
3434 waiting_for_sync_offset = config.get_use_video_sync();
3436 } else if (p == "mmc-control") {
3438 //poke_midi_thread ();
3440 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3442 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3444 } else if (p == "mmc-send-id") {
3446 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3448 } else if (p == "midi-control") {
3450 //poke_midi_thread ();
3452 } else if (p == "raid-path") {
3454 setup_raid_path (config.get_raid_path());
3456 } else if (p == "timecode-format") {
3460 } else if (p == "video-pullup") {
3464 } else if (p == "seamless-loop") {
3466 if (play_loop && transport_rolling()) {
3467 // to reset diskstreams etc
3468 request_play_loop (true);
3471 } else if (p == "rf-speed") {
3473 cumulative_rf_motion = 0;
3476 } else if (p == "click-sound") {
3478 setup_click_sounds (1);
3480 } else if (p == "click-emphasis-sound") {
3482 setup_click_sounds (-1);
3484 } else if (p == "clicking") {
3486 if (Config->get_clicking()) {
3487 if (_click_io && click_data) { // don't require emphasis data
3494 } else if (p == "send-mtc") {
3496 if (Config->get_send_mtc ()) {
3497 /* mark us ready to send */
3498 next_quarter_frame_to_send = 0;
3501 } else if (p == "send-mmc") {
3503 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3505 } else if (p == "midi-feedback") {
3507 session_midi_feedback = Config->get_midi_feedback();
3509 } else if (p == "jack-time-master") {
3511 engine().reset_timebase ();
3513 } else if (p == "native-file-header-format") {
3515 if (!first_file_header_format_reset) {
3516 reset_native_file_format ();
3519 first_file_header_format_reset = false;
3521 } else if (p == "native-file-data-format") {
3523 if (!first_file_data_format_reset) {
3524 reset_native_file_format ();
3527 first_file_data_format_reset = false;
3529 } else if (p == "external-sync") {
3530 if (!config.get_external_sync()) {
3531 drop_sync_source ();
3533 switch_to_sync_source (config.get_sync_source());
3535 } else if (p == "remote-model") {
3536 set_remote_control_ids ();
3537 } else if (p == "denormal-model") {
3539 } else if (p == "history-depth") {
3540 set_history_depth (Config->get_history_depth());
3541 } else if (p == "sync-all-route-ordering") {
3542 sync_order_keys ("session");
3543 } else if (p == "initial-program-change") {
3545 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3548 buf[0] = MIDI::program; // channel zero by default
3549 buf[1] = (Config->get_initial_program_change() & 0x7f);
3551 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3553 } else if (p == "solo-mute-override") {
3554 // catch_up_on_solo_mute_override ();
3555 } else if (p == "listen-position" || p == "pfl-position") {
3556 listen_position_changed ();
3557 } else if (p == "solo-control-is-listen-control") {
3558 solo_control_mode_changed ();
3559 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3560 last_timecode_valid = false;
3561 } else if (p == "playback-buffer-seconds") {
3562 AudioSource::allocate_working_buffers (frame_rate());
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, _1, _2));
3626 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3627 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));
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;