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 Stateful::save_extra_xml (node);
1255 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1256 load_options (*child);
1257 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1258 load_options (*child);
1260 error << _("Session: XML state has no options section") << endmsg;
1263 if (version >= 3000) {
1264 if ((child = find_named_node (node, "Metadata")) == 0) {
1265 warning << _("Session: XML state has no metadata section") << endmsg;
1266 } else if (_metadata->set_state (*child, version)) {
1271 if ((child = find_named_node (node, "Locations")) == 0) {
1272 error << _("Session: XML state has no locations section") << endmsg;
1274 } else if (_locations->set_state (*child, version)) {
1278 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1279 _speakers->set_state (*child, version);
1284 if ((location = _locations->auto_loop_location()) != 0) {
1285 set_auto_loop_location (location);
1288 if ((location = _locations->auto_punch_location()) != 0) {
1289 set_auto_punch_location (location);
1292 if ((location = _locations->session_range_location()) != 0) {
1293 delete _session_range_location;
1294 _session_range_location = location;
1297 if (_session_range_location) {
1298 AudioFileSource::set_header_position_offset (_session_range_location->start());
1301 if ((child = find_named_node (node, "Sources")) == 0) {
1302 error << _("Session: XML state has no sources section") << endmsg;
1304 } else if (load_sources (*child)) {
1308 if ((child = find_named_node (node, "TempoMap")) == 0) {
1309 error << _("Session: XML state has no Tempo Map section") << endmsg;
1311 } else if (_tempo_map->set_state (*child, version)) {
1315 if ((child = find_named_node (node, "Regions")) == 0) {
1316 error << _("Session: XML state has no Regions section") << endmsg;
1318 } else if (load_regions (*child)) {
1322 if ((child = find_named_node (node, "Playlists")) == 0) {
1323 error << _("Session: XML state has no playlists section") << endmsg;
1325 } else if (playlists->load (*this, *child)) {
1329 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1331 } else if (playlists->load_unused (*this, *child)) {
1335 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1336 if (load_compounds (*child)) {
1341 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1342 if (load_named_selections (*child)) {
1347 if (version >= 3000) {
1348 if ((child = find_named_node (node, "Bundles")) == 0) {
1349 warning << _("Session: XML state has no bundles section") << endmsg;
1352 /* We can't load Bundles yet as they need to be able
1353 to convert from port names to Port objects, which can't happen until
1355 _bundle_xml_node = new XMLNode (*child);
1359 if (version < 3000) {
1360 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1361 error << _("Session: XML state has no diskstreams section") << endmsg;
1363 } else if (load_diskstreams_2X (*child, version)) {
1368 if ((child = find_named_node (node, "Routes")) == 0) {
1369 error << _("Session: XML state has no routes section") << endmsg;
1371 } else if (load_routes (*child, version)) {
1375 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1376 _diskstreams_2X.clear ();
1378 if (version >= 3000) {
1380 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1381 error << _("Session: XML state has no route groups section") << endmsg;
1383 } else if (load_route_groups (*child, version)) {
1387 } else if (version < 3000) {
1389 if ((child = find_named_node (node, "EditGroups")) == 0) {
1390 error << _("Session: XML state has no edit groups section") << endmsg;
1392 } else if (load_route_groups (*child, version)) {
1396 if ((child = find_named_node (node, "MixGroups")) == 0) {
1397 error << _("Session: XML state has no mix groups section") << endmsg;
1399 } else if (load_route_groups (*child, version)) {
1404 if ((child = find_named_node (node, "Click")) == 0) {
1405 warning << _("Session: XML state has no click section") << endmsg;
1406 } else if (_click_io) {
1407 _click_io->set_state (*child, version);
1410 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1411 ControlProtocolManager::instance().set_protocol_states (*child);
1414 /* here beginneth the second phase ... */
1416 StateReady (); /* EMIT SIGNAL */
1425 Session::load_routes (const XMLNode& node, int version)
1428 XMLNodeConstIterator niter;
1429 RouteList new_routes;
1431 nlist = node.children();
1435 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1437 boost::shared_ptr<Route> route;
1438 if (version < 3000) {
1439 route = XMLRouteFactory_2X (**niter, version);
1441 route = XMLRouteFactory (**niter, version);
1445 error << _("Session: cannot create Route from XML description.") << endmsg;
1449 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1451 new_routes.push_back (route);
1454 add_routes (new_routes, false, false);
1459 boost::shared_ptr<Route>
1460 Session::XMLRouteFactory (const XMLNode& node, int version)
1462 boost::shared_ptr<Route> ret;
1464 if (node.name() != "Route") {
1468 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1470 DataType type = DataType::AUDIO;
1471 const XMLProperty* prop = node.property("default-type");
1474 type = DataType (prop->value());
1477 assert (type != DataType::NIL);
1481 boost::shared_ptr<Track> track;
1483 if (type == DataType::AUDIO) {
1484 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1486 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1489 if (track->init()) {
1493 if (track->set_state (node, version)) {
1497 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1498 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1503 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1505 if (r->init () == 0 && r->set_state (node, version) == 0) {
1506 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1507 boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1516 boost::shared_ptr<Route>
1517 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1519 boost::shared_ptr<Route> ret;
1521 if (node.name() != "Route") {
1525 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1527 ds_prop = node.property (X_("diskstream"));
1530 DataType type = DataType::AUDIO;
1531 const XMLProperty* prop = node.property("default-type");
1534 type = DataType (prop->value());
1537 assert (type != DataType::NIL);
1541 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1542 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1546 if (i == _diskstreams_2X.end()) {
1547 error << _("Could not find diskstream for route") << endmsg;
1548 return boost::shared_ptr<Route> ();
1551 boost::shared_ptr<Track> track;
1553 if (type == DataType::AUDIO) {
1554 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1556 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1559 if (track->init()) {
1563 if (track->set_state (node, version)) {
1567 track->set_diskstream (*i);
1569 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1570 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1575 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1577 if (r->init () == 0 && r->set_state (node, version) == 0) {
1578 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1579 boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1589 Session::load_regions (const XMLNode& node)
1592 XMLNodeConstIterator niter;
1593 boost::shared_ptr<Region> region;
1595 nlist = node.children();
1599 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1600 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1601 error << _("Session: cannot create Region from XML description.");
1602 const XMLProperty *name = (**niter).property("name");
1605 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1616 Session::load_compounds (const XMLNode& node)
1618 XMLNodeList calist = node.children();
1619 XMLNodeConstIterator caiter;
1620 XMLProperty *caprop;
1622 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1623 XMLNode* ca = *caiter;
1627 if ((caprop = ca->property (X_("original"))) == 0) {
1630 orig_id = caprop->value();
1632 if ((caprop = ca->property (X_("copy"))) == 0) {
1635 copy_id = caprop->value();
1637 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1638 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1640 if (!orig || !copy) {
1641 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1647 RegionFactory::add_compound_association (orig, copy);
1654 Session::load_nested_sources (const XMLNode& node)
1657 XMLNodeConstIterator niter;
1659 nlist = node.children();
1661 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1662 if ((*niter)->name() == "Source") {
1664 /* it may already exist, so don't recreate it unnecessarily
1667 XMLProperty* prop = (*niter)->property (X_("id"));
1669 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1673 ID source_id (prop->value());
1675 if (!source_by_id (source_id)) {
1678 SourceFactory::create (*this, **niter, true);
1680 catch (failed_constructor& err) {
1681 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1688 boost::shared_ptr<Region>
1689 Session::XMLRegionFactory (const XMLNode& node, bool full)
1691 const XMLProperty* type = node.property("type");
1695 const XMLNodeList& nlist = node.children();
1697 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1698 XMLNode *child = (*niter);
1699 if (child->name() == "NestedSource") {
1700 load_nested_sources (*child);
1704 if (!type || type->value() == "audio") {
1705 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1706 } else if (type->value() == "midi") {
1707 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1710 } catch (failed_constructor& err) {
1711 return boost::shared_ptr<Region> ();
1714 return boost::shared_ptr<Region> ();
1717 boost::shared_ptr<AudioRegion>
1718 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1720 const XMLProperty* prop;
1721 boost::shared_ptr<Source> source;
1722 boost::shared_ptr<AudioSource> as;
1724 SourceList master_sources;
1725 uint32_t nchans = 1;
1728 if (node.name() != X_("Region")) {
1729 return boost::shared_ptr<AudioRegion>();
1732 if ((prop = node.property (X_("channels"))) != 0) {
1733 nchans = atoi (prop->value().c_str());
1736 if ((prop = node.property ("name")) == 0) {
1737 cerr << "no name for this region\n";
1741 if ((prop = node.property (X_("source-0"))) == 0) {
1742 if ((prop = node.property ("source")) == 0) {
1743 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1744 return boost::shared_ptr<AudioRegion>();
1748 PBD::ID s_id (prop->value());
1750 if ((source = source_by_id (s_id)) == 0) {
1751 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1752 return boost::shared_ptr<AudioRegion>();
1755 as = boost::dynamic_pointer_cast<AudioSource>(source);
1757 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1758 return boost::shared_ptr<AudioRegion>();
1761 sources.push_back (as);
1763 /* pickup other channels */
1765 for (uint32_t n=1; n < nchans; ++n) {
1766 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1767 if ((prop = node.property (buf)) != 0) {
1769 PBD::ID id2 (prop->value());
1771 if ((source = source_by_id (id2)) == 0) {
1772 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1773 return boost::shared_ptr<AudioRegion>();
1776 as = boost::dynamic_pointer_cast<AudioSource>(source);
1778 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1779 return boost::shared_ptr<AudioRegion>();
1781 sources.push_back (as);
1785 for (uint32_t n = 0; n < nchans; ++n) {
1786 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1787 if ((prop = node.property (buf)) != 0) {
1789 PBD::ID id2 (prop->value());
1791 if ((source = source_by_id (id2)) == 0) {
1792 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1793 return boost::shared_ptr<AudioRegion>();
1796 as = boost::dynamic_pointer_cast<AudioSource>(source);
1798 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1799 return boost::shared_ptr<AudioRegion>();
1801 master_sources.push_back (as);
1806 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1808 /* a final detail: this is the one and only place that we know how long missing files are */
1810 if (region->whole_file()) {
1811 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1812 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1814 sfp->set_length (region->length());
1819 if (!master_sources.empty()) {
1820 if (master_sources.size() != nchans) {
1821 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1823 region->set_master_sources (master_sources);
1831 catch (failed_constructor& err) {
1832 return boost::shared_ptr<AudioRegion>();
1836 boost::shared_ptr<MidiRegion>
1837 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1839 const XMLProperty* prop;
1840 boost::shared_ptr<Source> source;
1841 boost::shared_ptr<MidiSource> ms;
1844 if (node.name() != X_("Region")) {
1845 return boost::shared_ptr<MidiRegion>();
1848 if ((prop = node.property ("name")) == 0) {
1849 cerr << "no name for this region\n";
1853 if ((prop = node.property (X_("source-0"))) == 0) {
1854 if ((prop = node.property ("source")) == 0) {
1855 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1856 return boost::shared_ptr<MidiRegion>();
1860 PBD::ID s_id (prop->value());
1862 if ((source = source_by_id (s_id)) == 0) {
1863 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1864 return boost::shared_ptr<MidiRegion>();
1867 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1869 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1870 return boost::shared_ptr<MidiRegion>();
1873 sources.push_back (ms);
1876 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1877 /* a final detail: this is the one and only place that we know how long missing files are */
1879 if (region->whole_file()) {
1880 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1881 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1883 sfp->set_length (region->length());
1891 catch (failed_constructor& err) {
1892 return boost::shared_ptr<MidiRegion>();
1897 Session::get_sources_as_xml ()
1900 XMLNode* node = new XMLNode (X_("Sources"));
1901 Glib::Mutex::Lock lm (source_lock);
1903 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1904 node->add_child_nocopy (i->second->get_state());
1911 Session::path_from_region_name (DataType type, string name, string identifier)
1913 char buf[PATH_MAX+1];
1915 SessionDirectory sdir(get_best_session_directory_for_new_source());
1916 sys::path source_dir = ((type == DataType::AUDIO)
1917 ? sdir.sound_path() : sdir.midi_path());
1919 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1921 for (n = 0; n < 999999; ++n) {
1922 if (identifier.length()) {
1923 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1924 identifier.c_str(), n, ext.c_str());
1926 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1930 sys::path source_path = source_dir / buf;
1932 if (!sys::exists (source_path)) {
1933 return source_path.to_string();
1937 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1946 Session::load_sources (const XMLNode& node)
1949 XMLNodeConstIterator niter;
1950 boost::shared_ptr<Source> source;
1952 nlist = node.children();
1956 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1959 if ((source = XMLSourceFactory (**niter)) == 0) {
1960 error << _("Session: cannot create Source from XML description.") << endmsg;
1963 } catch (MissingSource& err) {
1967 if (!no_questions_about_missing_files) {
1968 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1973 switch (user_choice) {
1975 /* user added a new search location, so try again */
1980 /* user asked to quit the entire session load
1985 no_questions_about_missing_files = true;
1989 no_questions_about_missing_files = true;
1994 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1995 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2004 boost::shared_ptr<Source>
2005 Session::XMLSourceFactory (const XMLNode& node)
2007 if (node.name() != "Source") {
2008 return boost::shared_ptr<Source>();
2012 /* note: do peak building in another thread when loading session state */
2013 return SourceFactory::create (*this, node, true);
2016 catch (failed_constructor& err) {
2017 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2018 return boost::shared_ptr<Source>();
2023 Session::save_template (string template_name)
2027 if (_state_of_the_state & CannotSave) {
2031 sys::path user_template_dir(user_template_directory());
2035 sys::create_directories (user_template_dir);
2037 catch(sys::filesystem_error& ex)
2039 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
2040 user_template_dir.to_string(), ex.what()) << endmsg;
2044 tree.set_root (&get_template());
2046 sys::path template_file_path(user_template_dir);
2047 template_file_path /= template_name + template_suffix;
2049 if (sys::exists (template_file_path))
2051 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2052 template_file_path.to_string()) << endmsg;
2056 if (!tree.write (template_file_path.to_string())) {
2057 error << _("template not saved") << endmsg;
2065 Session::rename_template (string old_name, string new_name)
2067 sys::path old_path (user_template_directory());
2068 old_path /= old_name + template_suffix;
2070 sys::path new_path(user_template_directory());
2071 new_path /= new_name + template_suffix;
2073 if (sys::exists (new_path)) {
2074 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
2075 new_path.to_string()) << endmsg;
2080 sys::rename (old_path, new_path);
2088 Session::delete_template (string name)
2090 sys::path path = user_template_directory();
2091 path /= name + template_suffix;
2102 Session::refresh_disk_space ()
2105 struct statfs statfsbuf;
2106 vector<space_and_path>::iterator i;
2107 Glib::Mutex::Lock lm (space_lock);
2110 /* get freespace on every FS that is part of the session path */
2112 _total_free_4k_blocks = 0;
2114 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2115 statfs ((*i).path.c_str(), &statfsbuf);
2117 scale = statfsbuf.f_bsize/4096.0;
2119 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2120 _total_free_4k_blocks += (*i).blocks;
2126 Session::get_best_session_directory_for_new_source ()
2128 vector<space_and_path>::iterator i;
2129 string result = _session_dir->root_path().to_string();
2131 /* handle common case without system calls */
2133 if (session_dirs.size() == 1) {
2137 /* OK, here's the algorithm we're following here:
2139 We want to select which directory to use for
2140 the next file source to be created. Ideally,
2141 we'd like to use a round-robin process so as to
2142 get maximum performance benefits from splitting
2143 the files across multiple disks.
2145 However, in situations without much diskspace, an
2146 RR approach may end up filling up a filesystem
2147 with new files while others still have space.
2148 Its therefore important to pay some attention to
2149 the freespace in the filesystem holding each
2150 directory as well. However, if we did that by
2151 itself, we'd keep creating new files in the file
2152 system with the most space until it was as full
2153 as all others, thus negating any performance
2154 benefits of this RAID-1 like approach.
2156 So, we use a user-configurable space threshold. If
2157 there are at least 2 filesystems with more than this
2158 much space available, we use RR selection between them.
2159 If not, then we pick the filesystem with the most space.
2161 This gets a good balance between the two
2165 refresh_disk_space ();
2167 int free_enough = 0;
2169 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2170 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2175 if (free_enough >= 2) {
2176 /* use RR selection process, ensuring that the one
2180 i = last_rr_session_dir;
2183 if (++i == session_dirs.end()) {
2184 i = session_dirs.begin();
2187 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2188 if (create_session_directory ((*i).path)) {
2190 last_rr_session_dir = i;
2195 } while (i != last_rr_session_dir);
2199 /* pick FS with the most freespace (and that
2200 seems to actually work ...)
2203 vector<space_and_path> sorted;
2204 space_and_path_ascending_cmp cmp;
2206 sorted = session_dirs;
2207 sort (sorted.begin(), sorted.end(), cmp);
2209 for (i = sorted.begin(); i != sorted.end(); ++i) {
2210 if (create_session_directory ((*i).path)) {
2212 last_rr_session_dir = i;
2222 Session::load_named_selections (const XMLNode& node)
2225 XMLNodeConstIterator niter;
2228 nlist = node.children();
2232 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2234 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2235 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2243 Session::XMLNamedSelectionFactory (const XMLNode& node)
2246 return new NamedSelection (*this, node);
2249 catch (failed_constructor& err) {
2255 Session::automation_dir () const
2257 return Glib::build_filename (_path, "automation");
2261 Session::analysis_dir () const
2263 return Glib::build_filename (_path, "analysis");
2267 Session::plugins_dir () const
2269 return Glib::build_filename (_path, "plugins");
2273 Session::load_bundles (XMLNode const & node)
2275 XMLNodeList nlist = node.children();
2276 XMLNodeConstIterator niter;
2280 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2281 if ((*niter)->name() == "InputBundle") {
2282 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2283 } else if ((*niter)->name() == "OutputBundle") {
2284 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2286 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2295 Session::load_route_groups (const XMLNode& node, int version)
2297 XMLNodeList nlist = node.children();
2298 XMLNodeConstIterator niter;
2302 if (version >= 3000) {
2304 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2305 if ((*niter)->name() == "RouteGroup") {
2306 RouteGroup* rg = new RouteGroup (*this, "");
2307 add_route_group (rg);
2308 rg->set_state (**niter, version);
2312 } else if (version < 3000) {
2314 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2315 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2316 RouteGroup* rg = new RouteGroup (*this, "");
2317 add_route_group (rg);
2318 rg->set_state (**niter, version);
2327 Session::auto_save()
2329 save_state (_current_snapshot_name);
2333 state_file_filter (const string &str, void */*arg*/)
2335 return (str.length() > strlen(statefile_suffix) &&
2336 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2340 bool operator()(const string* a, const string* b) {
2346 remove_end(string* state)
2348 string statename(*state);
2350 string::size_type start,end;
2351 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2352 statename = statename.substr (start+1);
2355 if ((end = statename.rfind(".ardour")) == string::npos) {
2356 end = statename.length();
2359 return new string(statename.substr (0, end));
2363 Session::possible_states (string path)
2365 PathScanner scanner;
2366 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2368 transform(states->begin(), states->end(), states->begin(), remove_end);
2371 sort (states->begin(), states->end(), cmp);
2377 Session::possible_states () const
2379 return possible_states(_path);
2383 Session::add_route_group (RouteGroup* g)
2385 _route_groups.push_back (g);
2386 route_group_added (g); /* EMIT SIGNAL */
2388 g->MembershipChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2389 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2395 Session::remove_route_group (RouteGroup& rg)
2397 list<RouteGroup*>::iterator i;
2399 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2400 _route_groups.erase (i);
2403 route_group_removed (); /* EMIT SIGNAL */
2407 /** Set a new order for our route groups, without adding or removing any.
2408 * @param groups Route group list in the new order.
2411 Session::reorder_route_groups (list<RouteGroup*> groups)
2413 _route_groups = groups;
2415 route_groups_reordered (); /* EMIT SIGNAL */
2421 Session::route_group_by_name (string name)
2423 list<RouteGroup *>::iterator i;
2425 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2426 if ((*i)->name() == name) {
2434 Session::all_route_group() const
2436 return *_all_route_group;
2440 Session::add_commands (vector<Command*> const & cmds)
2442 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2448 Session::begin_reversible_command (const string& name)
2450 begin_reversible_command (g_quark_from_string (name.c_str ()));
2453 /** Begin a reversible command using a GQuark to identify it.
2454 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2455 * but there must be as many begin...()s as there are commit...()s.
2458 Session::begin_reversible_command (GQuark q)
2460 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2461 to hold all the commands that are committed. This keeps the order of
2462 commands correct in the history.
2465 if (_current_trans == 0) {
2466 /* start a new transaction */
2467 assert (_current_trans_quarks.empty ());
2468 _current_trans = new UndoTransaction();
2469 _current_trans->set_name (g_quark_to_string (q));
2472 _current_trans_quarks.push_front (q);
2476 Session::commit_reversible_command (Command *cmd)
2478 assert (_current_trans);
2479 assert (!_current_trans_quarks.empty ());
2484 _current_trans->add_command (cmd);
2487 _current_trans_quarks.pop_front ();
2489 if (!_current_trans_quarks.empty ()) {
2490 /* the transaction we're committing is not the top-level one */
2494 if (_current_trans->empty()) {
2495 /* no commands were added to the transaction, so just get rid of it */
2496 delete _current_trans;
2501 gettimeofday (&now, 0);
2502 _current_trans->set_timestamp (now);
2504 _history.add (_current_trans);
2509 accept_all_audio_files (const string& path, void */*arg*/)
2511 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2515 if (!AudioFileSource::safe_audio_file_extension (path)) {
2523 accept_all_midi_files (const string& path, void */*arg*/)
2525 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2529 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2530 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2531 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2535 accept_all_state_files (const string& path, void */*arg*/)
2537 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2541 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2545 Session::find_all_sources (string path, set<string>& result)
2550 if (!tree.read (path)) {
2554 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2559 XMLNodeConstIterator niter;
2561 nlist = node->children();
2565 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2569 if ((prop = (*niter)->property (X_("type"))) == 0) {
2573 DataType type (prop->value());
2575 if ((prop = (*niter)->property (X_("name"))) == 0) {
2579 if (Glib::path_is_absolute (prop->value())) {
2580 /* external file, ignore */
2588 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2589 result.insert (found_path);
2597 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2599 PathScanner scanner;
2600 vector<string*>* state_files;
2602 string this_snapshot_path;
2608 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2609 ripped = ripped.substr (0, ripped.length() - 1);
2612 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2614 if (state_files == 0) {
2619 this_snapshot_path = _path;
2620 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2621 this_snapshot_path += statefile_suffix;
2623 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2625 if (exclude_this_snapshot && **i == this_snapshot_path) {
2629 if (find_all_sources (**i, result) < 0) {
2637 struct RegionCounter {
2638 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2639 AudioSourceList::iterator iter;
2640 boost::shared_ptr<Region> region;
2643 RegionCounter() : count (0) {}
2647 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2649 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2650 return r.get_value_or (1);
2654 Session::cleanup_regions ()
2656 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2658 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2660 boost::shared_ptr<AudioRegion> audio_region = boost::dynamic_pointer_cast<AudioRegion>( i->second);
2662 if (!audio_region) {
2666 uint32_t used = playlists->region_use_count (audio_region);
2668 if (used == 0 && !audio_region->automatic()) {
2669 RegionFactory::map_remove(i->second);
2673 /* dump the history list */
2680 Session::cleanup_sources (CleanupReport& rep)
2682 // FIXME: needs adaptation to midi
2684 vector<boost::shared_ptr<Source> > dead_sources;
2685 PathScanner scanner;
2688 vector<space_and_path>::iterator i;
2689 vector<space_and_path>::iterator nexti;
2690 vector<string*>* candidates;
2691 vector<string*>* candidates2;
2692 vector<string> unused;
2693 set<string> all_sources;
2698 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2700 /* consider deleting all unused playlists */
2702 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2707 /* sync the "all regions" property of each playlist with its current state
2710 playlists->sync_all_regions_with_regions ();
2712 /* find all un-used sources */
2717 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2719 SourceMap::iterator tmp;
2724 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2728 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2729 dead_sources.push_back (i->second);
2730 i->second->drop_references ();
2736 /* build a list of all the possible audio directories for the session */
2738 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2743 SessionDirectory sdir ((*i).path);
2744 audio_path += sdir.sound_path().to_string();
2746 if (nexti != session_dirs.end()) {
2754 /* build a list of all the possible midi directories for the session */
2756 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2761 SessionDirectory sdir ((*i).path);
2762 midi_path += sdir.midi_path().to_string();
2764 if (nexti != session_dirs.end()) {
2771 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2772 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2778 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2779 candidates->push_back (*i);
2784 candidates = candidates2; // might still be null
2787 /* find all sources, but don't use this snapshot because the
2788 state file on disk still references sources we may have already
2792 find_all_sources_across_snapshots (all_sources, true);
2794 /* add our current source list
2797 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2798 boost::shared_ptr<FileSource> fs;
2799 SourceMap::iterator tmp = i;
2802 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2803 if (playlists->source_use_count (fs) != 0) {
2804 all_sources.insert (fs->path());
2807 /* we might not remove this source from disk, because it may be used
2808 by other snapshots, but its not being used in this version
2809 so lets get rid of it now, along with any representative regions
2813 RegionFactory::remove_regions_using_source (i->second);
2821 char tmppath1[PATH_MAX+1];
2822 char tmppath2[PATH_MAX+1];
2825 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2830 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2832 if (realpath(spath.c_str(), tmppath1) == 0) {
2833 error << string_compose (_("Cannot expand path %1 (%2)"),
2834 spath, strerror (errno)) << endmsg;
2838 if (realpath((*i).c_str(), tmppath2) == 0) {
2839 error << string_compose (_("Cannot expand path %1 (%2)"),
2840 (*i), strerror (errno)) << endmsg;
2844 if (strcmp(tmppath1, tmppath2) == 0) {
2851 unused.push_back (spath);
2860 /* now try to move all unused files into the "dead" directory(ies) */
2862 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2863 struct stat statbuf;
2867 /* don't move the file across filesystems, just
2868 stick it in the `dead_dir_name' directory
2869 on whichever filesystem it was already on.
2872 if ((*x).find ("/sounds/") != string::npos) {
2874 /* old school, go up 1 level */
2876 newpath = Glib::path_get_dirname (*x); // "sounds"
2877 newpath = Glib::path_get_dirname (newpath); // "session-name"
2881 /* new school, go up 4 levels */
2883 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2884 newpath = Glib::path_get_dirname (newpath); // "session-name"
2885 newpath = Glib::path_get_dirname (newpath); // "interchange"
2886 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2889 newpath = Glib::build_filename (newpath, dead_dir_name);
2891 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2892 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2896 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2898 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2900 /* the new path already exists, try versioning */
2902 char buf[PATH_MAX+1];
2906 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2909 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2910 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2914 if (version == 999) {
2915 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2919 newpath = newpath_v;
2924 /* it doesn't exist, or we can't read it or something */
2928 stat ((*x).c_str(), &statbuf);
2930 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2931 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2932 (*x), newpath, strerror (errno))
2937 /* see if there an easy to find peakfile for this file, and remove it.
2940 string base = basename_nosuffix (*x);
2941 base += "%A"; /* this is what we add for the channel suffix of all native files,
2942 or for the first channel of embedded files. it will miss
2943 some peakfiles for other channels
2945 string peakpath = peak_path (base);
2947 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2948 if (::unlink (peakpath.c_str()) != 0) {
2949 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2950 peakpath, _path, strerror (errno))
2952 /* try to back out */
2953 rename (newpath.c_str(), _path.c_str());
2958 rep.paths.push_back (*x);
2959 rep.space += statbuf.st_size;
2962 /* dump the history list */
2966 /* save state so we don't end up a session file
2967 referring to non-existent sources.
2974 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2980 Session::cleanup_trash_sources (CleanupReport& rep)
2982 // FIXME: needs adaptation for MIDI
2984 vector<space_and_path>::iterator i;
2990 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2992 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2994 clear_directory (dead_dir, &rep.space, &rep.paths);
3001 Session::set_dirty ()
3003 bool was_dirty = dirty();
3005 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3009 DirtyChanged(); /* EMIT SIGNAL */
3015 Session::set_clean ()
3017 bool was_dirty = dirty();
3019 _state_of_the_state = Clean;
3023 DirtyChanged(); /* EMIT SIGNAL */
3028 Session::set_deletion_in_progress ()
3030 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3034 Session::clear_deletion_in_progress ()
3036 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3040 Session::add_controllable (boost::shared_ptr<Controllable> c)
3042 /* this adds a controllable to the list managed by the Session.
3043 this is a subset of those managed by the Controllable class
3044 itself, and represents the only ones whose state will be saved
3045 as part of the session.
3048 Glib::Mutex::Lock lm (controllables_lock);
3049 controllables.insert (c);
3052 struct null_deleter { void operator()(void const *) const {} };
3055 Session::remove_controllable (Controllable* c)
3057 if (_state_of_the_state | Deletion) {
3061 Glib::Mutex::Lock lm (controllables_lock);
3063 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3065 if (x != controllables.end()) {
3066 controllables.erase (x);
3070 boost::shared_ptr<Controllable>
3071 Session::controllable_by_id (const PBD::ID& id)
3073 Glib::Mutex::Lock lm (controllables_lock);
3075 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3076 if ((*i)->id() == id) {
3081 return boost::shared_ptr<Controllable>();
3084 boost::shared_ptr<Controllable>
3085 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3087 boost::shared_ptr<Controllable> c;
3088 boost::shared_ptr<Route> r;
3090 switch (desc.top_level_type()) {
3091 case ControllableDescriptor::NamedRoute:
3093 std::string str = desc.top_level_name();
3094 if (str == "master") {
3096 } else if (str == "control" || str == "listen") {
3099 r = route_by_name (desc.top_level_name());
3104 case ControllableDescriptor::RemoteControlID:
3105 r = route_by_remote_id (desc.rid());
3113 switch (desc.subtype()) {
3114 case ControllableDescriptor::Gain:
3115 c = r->gain_control ();
3118 case ControllableDescriptor::Solo:
3119 c = r->solo_control();
3122 case ControllableDescriptor::Mute:
3123 c = r->mute_control();
3126 case ControllableDescriptor::Recenable:
3128 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3131 c = t->rec_enable_control ();
3136 case ControllableDescriptor::PanDirection:
3138 c = r->pannable()->pan_azimuth_control;
3142 case ControllableDescriptor::PanWidth:
3144 c = r->pannable()->pan_width_control;
3148 case ControllableDescriptor::PanElevation:
3150 c = r->pannable()->pan_elevation_control;
3154 case ControllableDescriptor::Balance:
3155 /* XXX simple pan control */
3158 case ControllableDescriptor::PluginParameter:
3160 uint32_t plugin = desc.target (0);
3161 uint32_t parameter_index = desc.target (1);
3163 /* revert to zero based counting */
3169 if (parameter_index > 0) {
3173 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3176 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3177 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3182 case ControllableDescriptor::SendGain:
3184 uint32_t send = desc.target (0);
3186 /* revert to zero-based counting */
3192 boost::shared_ptr<Processor> p = r->nth_send (send);
3195 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3196 boost::shared_ptr<Amp> a = s->amp();
3199 c = s->amp()->gain_control();
3206 /* relax and return a null pointer */
3214 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3217 Stateful::add_instant_xml (node, _path);
3220 if (write_to_config) {
3221 Config->add_instant_xml (node);
3226 Session::instant_xml (const string& node_name)
3228 return Stateful::instant_xml (node_name, _path);
3232 Session::save_history (string snapshot_name)
3240 if (snapshot_name.empty()) {
3241 snapshot_name = _current_snapshot_name;
3244 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3245 const string backup_filename = history_filename + backup_suffix;
3246 const sys::path xml_path = _session_dir->root_path() / history_filename;
3247 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3249 if (sys::exists (xml_path)) {
3252 sys::rename (xml_path, backup_path);
3254 catch (const sys::filesystem_error& err)
3256 error << _("could not backup old history file, current history not saved") << endmsg;
3261 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3265 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3267 if (!tree.write (xml_path.to_string()))
3269 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3273 sys::remove (xml_path);
3274 sys::rename (backup_path, xml_path);
3276 catch (const sys::filesystem_error& err)
3278 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3279 backup_path.to_string(), err.what()) << endmsg;
3289 Session::restore_history (string snapshot_name)
3293 if (snapshot_name.empty()) {
3294 snapshot_name = _current_snapshot_name;
3297 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3298 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3300 info << "Loading history from " << xml_path.to_string() << endmsg;
3302 if (!sys::exists (xml_path)) {
3303 info << string_compose (_("%1: no history file \"%2\" for this session."),
3304 _name, xml_path.to_string()) << endmsg;
3308 if (!tree.read (xml_path.to_string())) {
3309 error << string_compose (_("Could not understand session history file \"%1\""),
3310 xml_path.to_string()) << endmsg;
3317 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3320 UndoTransaction* ut = new UndoTransaction ();
3323 ut->set_name(t->property("name")->value());
3324 stringstream ss(t->property("tv-sec")->value());
3326 ss.str(t->property("tv-usec")->value());
3328 ut->set_timestamp(tv);
3330 for (XMLNodeConstIterator child_it = t->children().begin();
3331 child_it != t->children().end(); child_it++)
3333 XMLNode *n = *child_it;
3336 if (n->name() == "MementoCommand" ||
3337 n->name() == "MementoUndoCommand" ||
3338 n->name() == "MementoRedoCommand") {
3340 if ((c = memento_command_factory(n))) {
3344 } else if (n->name() == "NoteDiffCommand") {
3345 PBD::ID id (n->property("midi-source")->value());
3346 boost::shared_ptr<MidiSource> midi_source =
3347 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3349 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3351 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3354 } else if (n->name() == "SysExDiffCommand") {
3356 PBD::ID id (n->property("midi-source")->value());
3357 boost::shared_ptr<MidiSource> midi_source =
3358 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3360 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3362 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3365 } else if (n->name() == "PatchChangeDiffCommand") {
3367 PBD::ID id (n->property("midi-source")->value());
3368 boost::shared_ptr<MidiSource> midi_source =
3369 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3371 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3373 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3376 } else if (n->name() == "StatefulDiffCommand") {
3377 if ((c = stateful_diff_command_factory (n))) {
3378 ut->add_command (c);
3381 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3392 Session::config_changed (std::string p, bool ours)
3398 if (p == "seamless-loop") {
3400 } else if (p == "rf-speed") {
3402 } else if (p == "auto-loop") {
3404 } else if (p == "auto-input") {
3406 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3407 /* auto-input only makes a difference if we're rolling */
3408 set_track_monitor_input_status (!config.get_auto_input());
3411 } else if (p == "punch-in") {
3415 if ((location = _locations->auto_punch_location()) != 0) {
3417 if (config.get_punch_in ()) {
3418 replace_event (SessionEvent::PunchIn, location->start());
3420 remove_event (location->start(), SessionEvent::PunchIn);
3424 } else if (p == "punch-out") {
3428 if ((location = _locations->auto_punch_location()) != 0) {
3430 if (config.get_punch_out()) {
3431 replace_event (SessionEvent::PunchOut, location->end());
3433 clear_events (SessionEvent::PunchOut);
3437 } else if (p == "edit-mode") {
3439 Glib::Mutex::Lock lm (playlists->lock);
3441 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3442 (*i)->set_edit_mode (Config->get_edit_mode ());
3445 } else if (p == "use-video-sync") {
3447 waiting_for_sync_offset = config.get_use_video_sync();
3449 } else if (p == "mmc-control") {
3451 //poke_midi_thread ();
3453 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3455 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3457 } else if (p == "mmc-send-id") {
3459 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3461 } else if (p == "midi-control") {
3463 //poke_midi_thread ();
3465 } else if (p == "raid-path") {
3467 setup_raid_path (config.get_raid_path());
3469 } else if (p == "timecode-format") {
3473 } else if (p == "video-pullup") {
3477 } else if (p == "seamless-loop") {
3479 if (play_loop && transport_rolling()) {
3480 // to reset diskstreams etc
3481 request_play_loop (true);
3484 } else if (p == "rf-speed") {
3486 cumulative_rf_motion = 0;
3489 } else if (p == "click-sound") {
3491 setup_click_sounds (1);
3493 } else if (p == "click-emphasis-sound") {
3495 setup_click_sounds (-1);
3497 } else if (p == "clicking") {
3499 if (Config->get_clicking()) {
3500 if (_click_io && click_data) { // don't require emphasis data
3507 } else if (p == "send-mtc") {
3509 if (Config->get_send_mtc ()) {
3510 /* mark us ready to send */
3511 next_quarter_frame_to_send = 0;
3514 } else if (p == "send-mmc") {
3516 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3518 } else if (p == "midi-feedback") {
3520 session_midi_feedback = Config->get_midi_feedback();
3522 } else if (p == "jack-time-master") {
3524 engine().reset_timebase ();
3526 } else if (p == "native-file-header-format") {
3528 if (!first_file_header_format_reset) {
3529 reset_native_file_format ();
3532 first_file_header_format_reset = false;
3534 } else if (p == "native-file-data-format") {
3536 if (!first_file_data_format_reset) {
3537 reset_native_file_format ();
3540 first_file_data_format_reset = false;
3542 } else if (p == "external-sync") {
3543 if (!config.get_external_sync()) {
3544 drop_sync_source ();
3546 switch_to_sync_source (config.get_sync_source());
3548 } else if (p == "remote-model") {
3549 set_remote_control_ids ();
3550 } else if (p == "denormal-model") {
3552 } else if (p == "history-depth") {
3553 set_history_depth (Config->get_history_depth());
3554 } else if (p == "sync-all-route-ordering") {
3555 sync_order_keys ("session");
3556 } else if (p == "initial-program-change") {
3558 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3561 buf[0] = MIDI::program; // channel zero by default
3562 buf[1] = (Config->get_initial_program_change() & 0x7f);
3564 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3566 } else if (p == "solo-mute-override") {
3567 // catch_up_on_solo_mute_override ();
3568 } else if (p == "listen-position" || p == "pfl-position") {
3569 listen_position_changed ();
3570 } else if (p == "solo-control-is-listen-control") {
3571 solo_control_mode_changed ();
3572 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3573 last_timecode_valid = false;
3574 } else if (p == "playback-buffer-seconds") {
3575 AudioSource::allocate_working_buffers (frame_rate());
3582 Session::set_history_depth (uint32_t d)
3584 _history.set_depth (d);
3588 Session::load_diskstreams_2X (XMLNode const & node, int)
3591 XMLNodeConstIterator citer;
3593 clist = node.children();
3595 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3598 /* diskstreams added automatically by DiskstreamCreated handler */
3599 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3600 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3601 _diskstreams_2X.push_back (dsp);
3603 error << _("Session: unknown diskstream type in XML") << endmsg;
3607 catch (failed_constructor& err) {
3608 error << _("Session: could not load diskstream via XML state") << endmsg;
3616 /** Connect things to the MMC object */
3618 Session::setup_midi_machine_control ()
3620 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3622 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3623 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3624 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3625 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3626 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3627 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3628 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3629 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3630 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3631 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3632 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3633 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3634 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3636 /* also handle MIDI SPP because its so common */
3638 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3639 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3640 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));
3643 boost::shared_ptr<Controllable>
3644 Session::solo_cut_control() const
3646 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3647 controls in Ardour that currently get presented to the user in the GUI that require
3648 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3650 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3651 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3655 return _solo_cut_control;