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"
25 #define __STDC_FORMAT_MACROS 1
34 #include <cstdio> /* snprintf(3) ... grrr */
48 #include <sys/param.h>
49 #include <sys/mount.h>
53 #include <glibmm/thread.h>
55 #include "midi++/mmc.h"
56 #include "midi++/port.h"
57 #include "midi++/manager.h"
59 #include "pbd/boost_debug.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_track.h"
73 #include "ardour/audioengine.h"
74 #include "ardour/audiofilesource.h"
75 #include "ardour/audioplaylist.h"
76 #include "ardour/audioregion.h"
77 #include "ardour/auditioner.h"
78 #include "ardour/buffer.h"
79 #include "ardour/butler.h"
80 #include "ardour/configuration.h"
81 #include "ardour/control_protocol_manager.h"
82 #include "ardour/crossfade.h"
83 #include "ardour/cycle_timer.h"
84 #include "ardour/directory_names.h"
85 #include "ardour/filename_extensions.h"
86 #include "ardour/io_processor.h"
87 #include "ardour/location.h"
88 #include "ardour/midi_diskstream.h"
89 #include "ardour/midi_patch_manager.h"
90 #include "ardour/midi_playlist.h"
91 #include "ardour/midi_region.h"
92 #include "ardour/midi_source.h"
93 #include "ardour/midi_track.h"
94 #include "ardour/named_selection.h"
95 #include "ardour/processor.h"
96 #include "ardour/port.h"
97 #include "ardour/region_factory.h"
98 #include "ardour/route_group.h"
99 #include "ardour/send.h"
100 #include "ardour/session.h"
101 #include "ardour/session_directory.h"
102 #include "ardour/session_metadata.h"
103 #include "ardour/session_state_utils.h"
104 #include "ardour/session_playlists.h"
105 #include "ardour/session_utils.h"
106 #include "ardour/silentfilesource.h"
107 #include "ardour/slave.h"
108 #include "ardour/smf_source.h"
109 #include "ardour/sndfile_helpers.h"
110 #include "ardour/sndfilesource.h"
111 #include "ardour/source_factory.h"
112 #include "ardour/template_utils.h"
113 #include "ardour/tempo.h"
114 #include "ardour/ticker.h"
115 #include "ardour/user_bundle.h"
116 #include "ardour/utils.h"
117 #include "ardour/utils.h"
118 #include "ardour/version.h"
119 #include "ardour/playlist_factory.h"
121 #include "control_protocol/control_protocol.h"
127 using namespace ARDOUR;
131 Session::first_stage_init (string fullpath, string snapshot_name)
133 if (fullpath.length() == 0) {
135 throw failed_constructor();
138 char buf[PATH_MAX+1];
139 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
140 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
142 throw failed_constructor();
147 if (_path[_path.length()-1] != '/') {
151 if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
157 /* these two are just provisional settings. set_state()
158 will likely override them.
161 _name = _current_snapshot_name = snapshot_name;
163 set_history_depth (Config->get_history_depth());
165 _current_frame_rate = _engine.frame_rate ();
166 _nominal_frame_rate = _current_frame_rate;
167 _base_frame_rate = _current_frame_rate;
169 _tempo_map = new TempoMap (_current_frame_rate);
170 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
173 _non_soloed_outs_muted = false;
175 _solo_isolated_cnt = 0;
176 g_atomic_int_set (&processing_prohibited, 0);
177 _transport_speed = 0;
178 _last_transport_speed = 0;
179 _target_transport_speed = 0;
180 auto_play_legal = false;
181 transport_sub_state = 0;
182 _transport_frame = 0;
183 _requested_return_frame = -1;
184 _session_range_location = 0;
185 g_atomic_int_set (&_record_status, Disabled);
186 loop_changing = false;
189 _last_roll_location = 0;
190 _last_roll_or_reversal_location = 0;
191 _last_record_location = 0;
192 pending_locate_frame = 0;
193 pending_locate_roll = false;
194 pending_locate_flush = false;
195 state_was_pending = false;
197 outbound_mtc_timecode_frame = 0;
198 next_quarter_frame_to_send = -1;
199 current_block_size = 0;
200 solo_update_disabled = false;
201 _have_captured = false;
202 _worst_output_latency = 0;
203 _worst_input_latency = 0;
204 _worst_track_latency = 0;
205 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
206 _was_seamless = Config->get_seamless_loop ();
208 session_send_mtc = false;
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 AudioDiskstream::allocate_working_buffers();
222 /* default short fade = 15ms */
224 Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
225 SndFileSource::setup_standard_crossfades (*this, frame_rate());
227 last_mmc_step.tv_sec = 0;
228 last_mmc_step.tv_usec = 0;
231 /* click sounds are unset by default, which causes us to internal
232 waveforms for clicks.
236 click_emphasis_length = 0;
239 process_function = &Session::process_with_events;
241 if (config.get_use_video_sync()) {
242 waiting_for_sync_offset = true;
244 waiting_for_sync_offset = false;
247 last_timecode_when = 0;
248 _timecode_offset = 0;
249 _timecode_offset_negative = true;
250 last_timecode_valid = false;
254 last_rr_session_dir = session_dirs.begin();
255 refresh_disk_space ();
257 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
261 average_slave_delta = 1800; // !!! why 1800 ????
262 have_first_delta_accumulator = false;
263 delta_accumulator_cnt = 0;
264 _slave_state = Stopped;
266 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
268 /* These are all static "per-class" signals */
270 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
271 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
272 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
273 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
274 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
276 /* stop IO objects from doing stuff until we're ready for them */
278 Delivery::disable_panners ();
279 IO::disable_connecting ();
283 Session::second_stage_init ()
285 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
288 if (load_state (_current_snapshot_name)) {
291 cleanup_stubfiles ();
294 if (_butler->start_thread()) {
298 if (start_midi_thread ()) {
302 setup_midi_machine_control ();
304 // set_state() will call setup_raid_path(), but if it's a new session we need
305 // to call setup_raid_path() here.
308 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
312 setup_raid_path(_path);
315 /* we can't save till after ::when_engine_running() is called,
316 because otherwise we save state with no connections made.
317 therefore, we reset _state_of_the_state because ::set_state()
318 will have cleared it.
320 we also have to include Loading so that any events that get
321 generated between here and the end of ::when_engine_running()
322 will be processed directly rather than queued.
325 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
327 _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
328 _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
329 setup_click_sounds (0);
330 setup_midi_control ();
332 /* Pay attention ... */
334 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
335 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
338 when_engine_running ();
341 /* handle this one in a different way than all others, so that its clear what happened */
343 catch (AudioEngine::PortRegistrationFailure& err) {
344 error << err.what() << endmsg;
352 BootMessage (_("Reset Remote Controls"));
354 send_full_time_code (0);
355 _engine.transport_locate (0);
357 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
358 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
360 MidiClockTicker::instance().set_session (this);
361 MIDI::Name::MidiPatchManager::instance().set_session (this);
363 /* initial program change will be delivered later; see ::config_changed() */
365 BootMessage (_("Reset Control Protocols"));
367 ControlProtocolManager::instance().set_session (this);
369 _state_of_the_state = Clean;
371 Port::set_connecting_blocked (false);
373 DirtyChanged (); /* EMIT SIGNAL */
375 if (state_was_pending) {
376 save_state (_current_snapshot_name);
377 remove_pending_capture_state ();
378 state_was_pending = false;
381 BootMessage (_("Session loading complete"));
387 Session::raid_path () const
389 SearchPath raid_search_path;
391 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
392 raid_search_path += sys::path((*i).path);
395 return raid_search_path.to_string ();
399 Session::setup_raid_path (string path)
408 session_dirs.clear ();
410 SearchPath search_path(path);
411 SearchPath sound_search_path;
412 SearchPath midi_search_path;
414 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
415 sp.path = (*i).to_string ();
416 sp.blocks = 0; // not needed
417 session_dirs.push_back (sp);
419 SessionDirectory sdir(sp.path);
421 sound_search_path += sdir.sound_path ();
422 midi_search_path += sdir.midi_path ();
425 // set the search path for each data type
426 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
427 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
429 // reset the round-robin soundfile path thingie
430 last_rr_session_dir = session_dirs.begin();
434 Session::path_is_within_session (const std::string& path)
436 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
437 if (path.find ((*i).path) == 0) {
445 Session::ensure_subdirs ()
449 dir = session_directory().peak_path().to_string();
451 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
452 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
456 dir = session_directory().sound_path().to_string();
458 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
459 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
463 dir = session_directory().sound_stub_path().to_string();
465 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
466 error << string_compose(_("Session: cannot create session stub sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
470 dir = session_directory().midi_path().to_string();
472 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
473 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
477 dir = session_directory().midi_stub_path().to_string();
479 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
480 error << string_compose(_("Session: cannot create session stub midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
484 dir = session_directory().dead_sound_path().to_string();
486 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
487 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
491 dir = session_directory().export_path().to_string();
493 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
494 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
498 dir = analysis_dir ();
500 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
501 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
509 Session::create (const string& mix_template, BusProfile* bus_profile)
512 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
513 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
517 if (ensure_subdirs ()) {
521 if (!mix_template.empty()) {
522 std::string in_path = mix_template;
524 ifstream in(in_path.c_str());
527 string out_path = _path;
529 out_path += statefile_suffix;
531 ofstream out(out_path.c_str());
539 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
545 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
552 /* Instantiate metadata */
554 _metadata = new SessionMetadata ();
556 /* set initial start + end point */
558 _state_of_the_state = Clean;
560 /* set up Master Out and Control Out if necessary */
566 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
568 if (bus_profile->master_out_channels) {
569 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
574 boost_debug_shared_ptr_mark_interesting (rt, "Route");
575 boost::shared_ptr<Route> r (rt);
576 r->input()->ensure_io (count, false, this);
577 r->output()->ensure_io (count, false, this);
578 r->set_remote_control_id (control_id++);
582 if (Config->get_use_monitor_bus()) {
583 Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO);
588 boost_debug_shared_ptr_mark_interesting (rt, "Route");
589 boost::shared_ptr<Route> r (rt);
590 r->input()->ensure_io (count, false, this);
591 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);
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 snapshot_name Snapshot name.
653 Session::rename_state (string old_name, string new_name)
655 if (old_name == _current_snapshot_name || old_name == _name) {
656 /* refuse to rename the current snapshot or the "main" one */
660 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
661 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
663 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
664 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
668 sys::rename (old_xml_path, new_xml_path);
670 catch (const sys::filesystem_error& err)
672 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
673 old_name, new_name, err.what()) << endmsg;
677 /** Remove a state file.
678 * @param snapshot_name Snapshot name.
681 Session::remove_state (string snapshot_name)
683 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
684 // refuse to remove the current snapshot or the "main" one
688 sys::path xml_path(_session_dir->root_path());
690 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
692 if (!create_backup_file (xml_path)) {
693 // don't remove it if a backup can't be made
694 // create_backup_file will log the error.
699 sys::remove (xml_path);
702 #ifdef HAVE_JACK_SESSION
704 Session::jack_session_event (jack_session_event_t * event)
708 struct tm local_time;
711 localtime_r (&n, &local_time);
712 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
714 if (event->type == JackSessionSaveTemplate)
716 if (save_template( timebuf )) {
717 event->flags = JackSessionSaveError;
719 string cmd ("ardour3 -P -U ");
720 cmd += event->client_uuid;
724 event->command_line = strdup (cmd.c_str());
729 if (save_state (timebuf)) {
730 event->flags = JackSessionSaveError;
732 sys::path xml_path (_session_dir->root_path());
733 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
735 string cmd ("ardour3 -P -U ");
736 cmd += event->client_uuid;
738 cmd += xml_path.to_string();
741 event->command_line = strdup (cmd.c_str());
745 jack_session_reply (_engine.jack(), event);
747 if (event->type == JackSessionSaveAndQuit) {
748 // TODO: make ardour quit.
751 jack_session_event_free( event );
756 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
759 sys::path xml_path(_session_dir->root_path());
761 if (!_writable || (_state_of_the_state & CannotSave)) {
765 if (!_engine.connected ()) {
766 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
772 /* tell sources we're saving first, in case they write out to a new file
773 * which should be saved with the state rather than the old one */
774 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
775 i->second->session_saved();
778 tree.set_root (&get_state());
780 if (snapshot_name.empty()) {
781 snapshot_name = _current_snapshot_name;
782 } else if (switch_to_snapshot) {
783 _current_snapshot_name = snapshot_name;
788 /* proper save: use statefile_suffix (.ardour in English) */
790 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
792 /* make a backup copy of the old file */
794 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
795 // create_backup_file will log the error
801 /* pending save: use pending_suffix (.pending in English) */
802 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
805 sys::path tmp_path(_session_dir->root_path());
807 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
809 // cerr << "actually writing state to " << xml_path.to_string() << endl;
811 if (!tree.write (tmp_path.to_string())) {
812 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
813 sys::remove (tmp_path);
818 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
819 error << string_compose (_("could not rename temporary session file %1 to %2"),
820 tmp_path.to_string(), xml_path.to_string()) << endmsg;
821 sys::remove (tmp_path);
828 save_history (snapshot_name);
830 bool was_dirty = dirty();
832 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
835 DirtyChanged (); /* EMIT SIGNAL */
838 StateSaved (snapshot_name); /* EMIT SIGNAL */
845 Session::restore_state (string snapshot_name)
847 if (load_state (snapshot_name) == 0) {
848 set_state (*state_tree->root(), Stateful::loading_state_version);
855 Session::load_state (string snapshot_name)
860 state_was_pending = false;
862 /* check for leftover pending state from a crashed capture attempt */
864 sys::path xmlpath(_session_dir->root_path());
865 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
867 if (sys::exists (xmlpath)) {
869 /* there is pending state from a crashed capture attempt */
871 boost::optional<int> r = AskAboutPendingState();
872 if (r.get_value_or (1)) {
873 state_was_pending = true;
877 if (!state_was_pending) {
878 xmlpath = _session_dir->root_path();
879 xmlpath /= snapshot_name;
882 if (!sys::exists (xmlpath)) {
883 xmlpath = _session_dir->root_path();
884 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
885 if (!sys::exists (xmlpath)) {
886 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
891 state_tree = new XMLTree;
895 /* writable() really reflects the whole folder, but if for any
896 reason the session state file can't be written to, still
900 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
904 if (!state_tree->read (xmlpath.to_string())) {
905 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
911 XMLNode& root (*state_tree->root());
913 if (root.name() != X_("Session")) {
914 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
920 const XMLProperty* prop;
922 if ((prop = root.property ("version")) == 0) {
923 /* no version implies very old version of Ardour */
924 Stateful::loading_state_version = 1000;
930 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
931 Stateful::loading_state_version = (major * 1000) + minor;
934 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
936 sys::path backup_path(_session_dir->root_path());
938 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
940 // only create a backup once
941 if (sys::exists (backup_path)) {
945 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
946 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
951 sys::copy_file (xmlpath, backup_path);
953 catch(sys::filesystem_error& ex)
955 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
956 xmlpath.to_string(), ex.what())
966 Session::load_options (const XMLNode& node)
968 LocaleGuard lg (X_("POSIX"));
969 config.set_variables (node);
980 Session::get_template()
982 /* if we don't disable rec-enable, diskstreams
983 will believe they need to store their capture
984 sources in their state node.
987 disable_record (false);
993 Session::state(bool full_state)
995 XMLNode* node = new XMLNode("Session");
998 // store libardour version, just in case
1000 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
1001 node->add_property("version", string(buf));
1003 /* store configuration settings */
1007 node->add_property ("name", _name);
1008 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
1009 node->add_property ("sample-rate", buf);
1011 if (session_dirs.size() > 1) {
1015 vector<space_and_path>::iterator i = session_dirs.begin();
1016 vector<space_and_path>::iterator next;
1018 ++i; /* skip the first one */
1022 while (i != session_dirs.end()) {
1026 if (next != session_dirs.end()) {
1036 child = node->add_child ("Path");
1037 child->add_content (p);
1041 /* save the ID counter */
1043 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1044 node->add_property ("id-counter", buf);
1046 /* save the event ID counter */
1048 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1049 node->add_property ("event-counter", buf);
1051 /* various options */
1053 node->add_child_nocopy (config.get_variables ());
1055 node->add_child_nocopy (_metadata->get_state());
1057 child = node->add_child ("Sources");
1060 Glib::Mutex::Lock sl (source_lock);
1062 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1064 /* Don't save information about non-destructive file sources that are empty
1065 and unused by any regions.
1068 boost::shared_ptr<FileSource> fs;
1069 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1070 if (!fs->destructive()) {
1071 if (fs->empty() && !fs->used()) {
1077 child->add_child_nocopy (siter->second->get_state());
1081 child = node->add_child ("Regions");
1084 Glib::Mutex::Lock rl (region_lock);
1085 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1086 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1087 boost::shared_ptr<Region> r = i->second;
1088 /* only store regions not attached to playlists */
1089 if (r->playlist() == 0) {
1090 child->add_child_nocopy (r->state ());
1096 node->add_child_nocopy (_locations.get_state());
1098 // for a template, just create a new Locations, populate it
1099 // with the default start and end, and get the state for that.
1101 Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
1102 range->set (max_frames, 0);
1104 node->add_child_nocopy (loc.get_state());
1107 child = node->add_child ("Bundles");
1109 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1110 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1111 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1113 child->add_child_nocopy (b->get_state());
1118 child = node->add_child ("Routes");
1120 boost::shared_ptr<RouteList> r = routes.reader ();
1122 RoutePublicOrderSorter cmp;
1123 RouteList public_order (*r);
1124 public_order.sort (cmp);
1126 /* the sort should have put control outs first */
1129 assert (_monitor_out == public_order.front());
1132 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1133 if (!(*i)->is_hidden()) {
1135 child->add_child_nocopy ((*i)->get_state());
1137 child->add_child_nocopy ((*i)->get_template());
1143 playlists->add_state (node, full_state);
1145 child = node->add_child ("RouteGroups");
1146 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1147 child->add_child_nocopy ((*i)->get_state());
1151 child = node->add_child ("Click");
1152 child->add_child_nocopy (_click_io->state (full_state));
1156 child = node->add_child ("NamedSelections");
1157 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1159 child->add_child_nocopy ((*i)->get_state());
1164 node->add_child_nocopy (_tempo_map->get_state());
1166 node->add_child_nocopy (get_control_protocol_state());
1169 node->add_child_copy (*_extra_xml);
1176 Session::get_control_protocol_state ()
1178 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1179 return cpm.get_state();
1183 Session::set_state (const XMLNode& node, int version)
1187 const XMLProperty* prop;
1190 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1192 if (node.name() != X_("Session")){
1193 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1197 if ((prop = node.property ("version")) != 0) {
1198 version = atoi (prop->value ()) * 1000;
1201 if ((prop = node.property ("name")) != 0) {
1202 _name = prop->value ();
1205 if ((prop = node.property (X_("sample-rate"))) != 0) {
1207 _nominal_frame_rate = atoi (prop->value());
1209 if (_nominal_frame_rate != _current_frame_rate) {
1210 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1211 if (r.get_value_or (0)) {
1217 setup_raid_path(_session_dir->root_path().to_string());
1219 if ((prop = node.property (X_("id-counter"))) != 0) {
1221 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1222 ID::init_counter (x);
1224 /* old sessions used a timebased counter, so fake
1225 the startup ID counter based on a standard
1230 ID::init_counter (now);
1233 if ((prop = node.property (X_("event-counter"))) != 0) {
1234 Evoral::init_event_id_counter (atoi (prop->value()));
1237 IO::disable_connecting ();
1239 /* Object loading order:
1244 MIDI Control // relies on data from Options/Config
1257 if ((child = find_named_node (node, "Extra")) != 0) {
1258 _extra_xml = new XMLNode (*child);
1261 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1262 load_options (*child);
1263 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1264 load_options (*child);
1266 error << _("Session: XML state has no options section") << endmsg;
1269 if (version >= 3000) {
1270 if ((child = find_named_node (node, "Metadata")) == 0) {
1271 warning << _("Session: XML state has no metadata section") << endmsg;
1272 } else if (_metadata->set_state (*child, version)) {
1277 if ((child = find_named_node (node, "Locations")) == 0) {
1278 error << _("Session: XML state has no locations section") << endmsg;
1280 } else if (_locations.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, "Regions")) == 0) {
1311 error << _("Session: XML state has no Regions section") << endmsg;
1313 } else if (load_regions (*child)) {
1317 if ((child = find_named_node (node, "Playlists")) == 0) {
1318 error << _("Session: XML state has no playlists section") << endmsg;
1320 } else if (playlists->load (*this, *child)) {
1324 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1326 } else if (playlists->load_unused (*this, *child)) {
1330 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1331 if (load_named_selections (*child)) {
1336 if (version >= 3000) {
1337 if ((child = find_named_node (node, "Bundles")) == 0) {
1338 warning << _("Session: XML state has no bundles section") << endmsg;
1341 /* We can't load Bundles yet as they need to be able
1342 to convert from port names to Port objects, which can't happen until
1344 _bundle_xml_node = new XMLNode (*child);
1348 if ((child = find_named_node (node, "TempoMap")) == 0) {
1349 error << _("Session: XML state has no Tempo Map section") << endmsg;
1351 } else if (_tempo_map->set_state (*child, version)) {
1355 if (version < 3000) {
1356 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1357 error << _("Session: XML state has no diskstreams section") << endmsg;
1359 } else if (load_diskstreams_2X (*child, version)) {
1364 if ((child = find_named_node (node, "Routes")) == 0) {
1365 error << _("Session: XML state has no routes section") << endmsg;
1367 } else if (load_routes (*child, version)) {
1371 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1372 _diskstreams_2X.clear ();
1374 if (version >= 3000) {
1376 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1377 error << _("Session: XML state has no route groups section") << endmsg;
1379 } else if (load_route_groups (*child, version)) {
1383 } else if (version < 3000) {
1385 if ((child = find_named_node (node, "EditGroups")) == 0) {
1386 error << _("Session: XML state has no edit groups section") << endmsg;
1388 } else if (load_route_groups (*child, version)) {
1392 if ((child = find_named_node (node, "MixGroups")) == 0) {
1393 error << _("Session: XML state has no mix groups section") << endmsg;
1395 } else if (load_route_groups (*child, version)) {
1400 if ((child = find_named_node (node, "Click")) == 0) {
1401 warning << _("Session: XML state has no click section") << endmsg;
1402 } else if (_click_io) {
1403 _click_io->set_state (*child, version);
1406 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1407 ControlProtocolManager::instance().set_protocol_states (*child);
1410 /* here beginneth the second phase ... */
1412 StateReady (); /* EMIT SIGNAL */
1421 Session::load_routes (const XMLNode& node, int version)
1424 XMLNodeConstIterator niter;
1425 RouteList new_routes;
1427 nlist = node.children();
1431 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1433 boost::shared_ptr<Route> route;
1434 if (version < 3000) {
1435 route = XMLRouteFactory_2X (**niter, version);
1437 route = XMLRouteFactory (**niter, version);
1441 error << _("Session: cannot create Route from XML description.") << endmsg;
1445 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1447 new_routes.push_back (route);
1450 add_routes (new_routes, false);
1455 boost::shared_ptr<Route>
1456 Session::XMLRouteFactory (const XMLNode& node, int version)
1458 boost::shared_ptr<Route> ret;
1460 if (node.name() != "Route") {
1464 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1466 DataType type = DataType::AUDIO;
1467 const XMLProperty* prop = node.property("default-type");
1470 type = DataType (prop->value());
1473 assert (type != DataType::NIL);
1479 if (type == DataType::AUDIO) {
1480 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1483 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1486 if (track->init()) {
1491 if (track->set_state (node, version)) {
1496 boost_debug_shared_ptr_mark_interesting (track, "Track");
1500 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1502 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1503 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1513 boost::shared_ptr<Route>
1514 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1516 boost::shared_ptr<Route> ret;
1518 if (node.name() != "Route") {
1522 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1524 ds_prop = node.property (X_("diskstream"));
1527 DataType type = DataType::AUDIO;
1528 const XMLProperty* prop = node.property("default-type");
1531 type = DataType (prop->value());
1534 assert (type != DataType::NIL);
1538 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1539 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1543 if (i == _diskstreams_2X.end()) {
1544 error << _("Could not find diskstream for route") << endmsg;
1545 return boost::shared_ptr<Route> ();
1550 if (type == DataType::AUDIO) {
1551 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1554 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1557 if (track->init()) {
1562 if (track->set_state (node, version)) {
1567 track->set_diskstream (*i);
1569 boost_debug_shared_ptr_mark_interesting (track, "Track");
1573 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1575 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1576 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1587 Session::load_regions (const XMLNode& node)
1590 XMLNodeConstIterator niter;
1591 boost::shared_ptr<Region> region;
1593 nlist = node.children();
1597 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1598 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1599 error << _("Session: cannot create Region from XML description.");
1600 const XMLProperty *name = (**niter).property("name");
1603 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1613 boost::shared_ptr<Region>
1614 Session::XMLRegionFactory (const XMLNode& node, bool full)
1616 const XMLProperty* type = node.property("type");
1620 if (!type || type->value() == "audio") {
1621 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1622 } else if (type->value() == "midi") {
1623 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1626 } catch (failed_constructor& err) {
1627 return boost::shared_ptr<Region> ();
1630 return boost::shared_ptr<Region> ();
1633 boost::shared_ptr<AudioRegion>
1634 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1636 const XMLProperty* prop;
1637 boost::shared_ptr<Source> source;
1638 boost::shared_ptr<AudioSource> as;
1640 SourceList master_sources;
1641 uint32_t nchans = 1;
1644 if (node.name() != X_("Region")) {
1645 return boost::shared_ptr<AudioRegion>();
1648 if ((prop = node.property (X_("channels"))) != 0) {
1649 nchans = atoi (prop->value().c_str());
1652 if ((prop = node.property ("name")) == 0) {
1653 cerr << "no name for this region\n";
1657 if ((prop = node.property (X_("source-0"))) == 0) {
1658 if ((prop = node.property ("source")) == 0) {
1659 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1660 return boost::shared_ptr<AudioRegion>();
1664 PBD::ID s_id (prop->value());
1666 if ((source = source_by_id (s_id)) == 0) {
1667 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1668 return boost::shared_ptr<AudioRegion>();
1671 as = boost::dynamic_pointer_cast<AudioSource>(source);
1673 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1674 return boost::shared_ptr<AudioRegion>();
1677 sources.push_back (as);
1679 /* pickup other channels */
1681 for (uint32_t n=1; n < nchans; ++n) {
1682 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1683 if ((prop = node.property (buf)) != 0) {
1685 PBD::ID id2 (prop->value());
1687 if ((source = source_by_id (id2)) == 0) {
1688 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1689 return boost::shared_ptr<AudioRegion>();
1692 as = boost::dynamic_pointer_cast<AudioSource>(source);
1694 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1695 return boost::shared_ptr<AudioRegion>();
1697 sources.push_back (as);
1701 for (uint32_t n = 0; n < nchans; ++n) {
1702 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1703 if ((prop = node.property (buf)) != 0) {
1705 PBD::ID id2 (prop->value());
1707 if ((source = source_by_id (id2)) == 0) {
1708 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1709 return boost::shared_ptr<AudioRegion>();
1712 as = boost::dynamic_pointer_cast<AudioSource>(source);
1714 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1715 return boost::shared_ptr<AudioRegion>();
1717 master_sources.push_back (as);
1722 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1724 /* a final detail: this is the one and only place that we know how long missing files are */
1726 if (region->whole_file()) {
1727 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1728 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1730 sfp->set_length (region->length());
1735 if (!master_sources.empty()) {
1736 if (master_sources.size() != nchans) {
1737 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1739 region->set_master_sources (master_sources);
1747 catch (failed_constructor& err) {
1748 return boost::shared_ptr<AudioRegion>();
1752 boost::shared_ptr<MidiRegion>
1753 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1755 const XMLProperty* prop;
1756 boost::shared_ptr<Source> source;
1757 boost::shared_ptr<MidiSource> ms;
1760 if (node.name() != X_("Region")) {
1761 return boost::shared_ptr<MidiRegion>();
1764 if ((prop = node.property ("name")) == 0) {
1765 cerr << "no name for this region\n";
1769 if ((prop = node.property (X_("source-0"))) == 0) {
1770 if ((prop = node.property ("source")) == 0) {
1771 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1772 return boost::shared_ptr<MidiRegion>();
1776 PBD::ID s_id (prop->value());
1778 if ((source = source_by_id (s_id)) == 0) {
1779 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1780 return boost::shared_ptr<MidiRegion>();
1783 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1785 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1786 return boost::shared_ptr<MidiRegion>();
1789 sources.push_back (ms);
1792 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1793 /* a final detail: this is the one and only place that we know how long missing files are */
1795 if (region->whole_file()) {
1796 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1797 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1799 sfp->set_length (region->length());
1807 catch (failed_constructor& err) {
1808 return boost::shared_ptr<MidiRegion>();
1813 Session::get_sources_as_xml ()
1816 XMLNode* node = new XMLNode (X_("Sources"));
1817 Glib::Mutex::Lock lm (source_lock);
1819 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1820 node->add_child_nocopy (i->second->get_state());
1827 Session::path_from_region_name (DataType type, string name, string identifier)
1829 char buf[PATH_MAX+1];
1831 SessionDirectory sdir(get_best_session_directory_for_new_source());
1832 sys::path source_dir = ((type == DataType::AUDIO)
1833 ? sdir.sound_path() : sdir.midi_path());
1835 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1837 for (n = 0; n < 999999; ++n) {
1838 if (identifier.length()) {
1839 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1840 identifier.c_str(), n, ext.c_str());
1842 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1846 sys::path source_path = source_dir / buf;
1848 if (!sys::exists (source_path)) {
1849 return source_path.to_string();
1853 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1862 Session::load_sources (const XMLNode& node)
1865 XMLNodeConstIterator niter;
1866 boost::shared_ptr<Source> source;
1868 nlist = node.children();
1872 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1874 if ((source = XMLSourceFactory (**niter)) == 0) {
1875 error << _("Session: cannot create Source from XML description.") << endmsg;
1877 } catch (MissingSource& err) {
1878 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1879 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1886 boost::shared_ptr<Source>
1887 Session::XMLSourceFactory (const XMLNode& node)
1889 if (node.name() != "Source") {
1890 return boost::shared_ptr<Source>();
1894 /* note: do peak building in another thread when loading session state */
1895 return SourceFactory::create (*this, node, true);
1898 catch (failed_constructor& err) {
1899 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1900 return boost::shared_ptr<Source>();
1905 Session::save_template (string template_name)
1909 if (_state_of_the_state & CannotSave) {
1913 sys::path user_template_dir(user_template_directory());
1917 sys::create_directories (user_template_dir);
1919 catch(sys::filesystem_error& ex)
1921 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1922 user_template_dir.to_string(), ex.what()) << endmsg;
1926 tree.set_root (&get_template());
1928 sys::path template_file_path(user_template_dir);
1929 template_file_path /= template_name + template_suffix;
1931 if (sys::exists (template_file_path))
1933 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1934 template_file_path.to_string()) << endmsg;
1938 if (!tree.write (template_file_path.to_string())) {
1939 error << _("mix template not saved") << endmsg;
1947 Session::rename_template (string old_name, string new_name)
1949 sys::path old_path (user_template_directory());
1950 old_path /= old_name + template_suffix;
1952 sys::path new_path(user_template_directory());
1953 new_path /= new_name + template_suffix;
1955 if (sys::exists (new_path)) {
1956 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1957 new_path.to_string()) << endmsg;
1962 sys::rename (old_path, new_path);
1970 Session::delete_template (string name)
1972 sys::path path = user_template_directory();
1973 path /= name + template_suffix;
1984 Session::refresh_disk_space ()
1987 struct statfs statfsbuf;
1988 vector<space_and_path>::iterator i;
1989 Glib::Mutex::Lock lm (space_lock);
1992 /* get freespace on every FS that is part of the session path */
1994 _total_free_4k_blocks = 0;
1996 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1997 statfs ((*i).path.c_str(), &statfsbuf);
1999 scale = statfsbuf.f_bsize/4096.0;
2001 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2002 _total_free_4k_blocks += (*i).blocks;
2008 Session::get_best_session_directory_for_new_source ()
2010 vector<space_and_path>::iterator i;
2011 string result = _session_dir->root_path().to_string();
2013 /* handle common case without system calls */
2015 if (session_dirs.size() == 1) {
2019 /* OK, here's the algorithm we're following here:
2021 We want to select which directory to use for
2022 the next file source to be created. Ideally,
2023 we'd like to use a round-robin process so as to
2024 get maximum performance benefits from splitting
2025 the files across multiple disks.
2027 However, in situations without much diskspace, an
2028 RR approach may end up filling up a filesystem
2029 with new files while others still have space.
2030 Its therefore important to pay some attention to
2031 the freespace in the filesystem holding each
2032 directory as well. However, if we did that by
2033 itself, we'd keep creating new files in the file
2034 system with the most space until it was as full
2035 as all others, thus negating any performance
2036 benefits of this RAID-1 like approach.
2038 So, we use a user-configurable space threshold. If
2039 there are at least 2 filesystems with more than this
2040 much space available, we use RR selection between them.
2041 If not, then we pick the filesystem with the most space.
2043 This gets a good balance between the two
2047 refresh_disk_space ();
2049 int free_enough = 0;
2051 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2052 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2057 if (free_enough >= 2) {
2058 /* use RR selection process, ensuring that the one
2062 i = last_rr_session_dir;
2065 if (++i == session_dirs.end()) {
2066 i = session_dirs.begin();
2069 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2070 if (create_session_directory ((*i).path)) {
2072 last_rr_session_dir = i;
2077 } while (i != last_rr_session_dir);
2081 /* pick FS with the most freespace (and that
2082 seems to actually work ...)
2085 vector<space_and_path> sorted;
2086 space_and_path_ascending_cmp cmp;
2088 sorted = session_dirs;
2089 sort (sorted.begin(), sorted.end(), cmp);
2091 for (i = sorted.begin(); i != sorted.end(); ++i) {
2092 if (create_session_directory ((*i).path)) {
2094 last_rr_session_dir = i;
2104 Session::load_named_selections (const XMLNode& node)
2107 XMLNodeConstIterator niter;
2110 nlist = node.children();
2114 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2116 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2117 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2125 Session::XMLNamedSelectionFactory (const XMLNode& node)
2128 return new NamedSelection (*this, node);
2131 catch (failed_constructor& err) {
2137 Session::automation_dir () const
2139 return Glib::build_filename (_path, "automation");
2143 Session::analysis_dir () const
2145 return Glib::build_filename (_path, "analysis");
2149 Session::load_bundles (XMLNode const & node)
2151 XMLNodeList nlist = node.children();
2152 XMLNodeConstIterator niter;
2156 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2157 if ((*niter)->name() == "InputBundle") {
2158 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2159 } else if ((*niter)->name() == "OutputBundle") {
2160 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2162 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2171 Session::load_route_groups (const XMLNode& node, int version)
2173 XMLNodeList nlist = node.children();
2174 XMLNodeConstIterator niter;
2178 if (version >= 3000) {
2180 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2181 if ((*niter)->name() == "RouteGroup") {
2182 RouteGroup* rg = new RouteGroup (*this, "");
2183 add_route_group (rg);
2184 rg->set_state (**niter, version);
2188 } else if (version < 3000) {
2190 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2191 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2192 RouteGroup* rg = new RouteGroup (*this, "");
2193 add_route_group (rg);
2194 rg->set_state (**niter, version);
2203 Session::auto_save()
2205 save_state (_current_snapshot_name);
2209 state_file_filter (const string &str, void */*arg*/)
2211 return (str.length() > strlen(statefile_suffix) &&
2212 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2216 bool operator()(const string* a, const string* b) {
2222 remove_end(string* state)
2224 string statename(*state);
2226 string::size_type start,end;
2227 if ((start = statename.find_last_of ('/')) != string::npos) {
2228 statename = statename.substr (start+1);
2231 if ((end = statename.rfind(".ardour")) == string::npos) {
2232 end = statename.length();
2235 return new string(statename.substr (0, end));
2239 Session::possible_states (string path)
2241 PathScanner scanner;
2242 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2244 transform(states->begin(), states->end(), states->begin(), remove_end);
2247 sort (states->begin(), states->end(), cmp);
2253 Session::possible_states () const
2255 return possible_states(_path);
2259 Session::add_route_group (RouteGroup* g)
2261 _route_groups.push_back (g);
2262 route_group_added (g); /* EMIT SIGNAL */
2264 g->MembershipChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2265 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2271 Session::remove_route_group (RouteGroup& rg)
2273 list<RouteGroup*>::iterator i;
2275 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2276 _route_groups.erase (i);
2279 route_group_removed (); /* EMIT SIGNAL */
2285 Session::route_group_by_name (string name)
2287 list<RouteGroup *>::iterator i;
2289 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2290 if ((*i)->name() == name) {
2298 Session::start_reversible_command (const string& name)
2300 UndoTransaction* trans = new UndoTransaction();
2301 trans->set_name(name);
2306 Session::finish_reversible_command (UndoTransaction& ut)
2309 gettimeofday(&now, 0);
2310 ut.set_timestamp(now);
2315 Session::begin_reversible_command(const string& name)
2317 UndoTransaction* trans = new UndoTransaction();
2318 trans->set_name(name);
2320 if (!_current_trans.empty()) {
2321 _current_trans.top()->add_command (trans);
2323 _current_trans.push(trans);
2328 Session::commit_reversible_command(Command *cmd)
2330 assert(!_current_trans.empty());
2334 _current_trans.top()->add_command(cmd);
2337 if (_current_trans.top()->empty()) {
2338 _current_trans.pop();
2342 gettimeofday(&now, 0);
2343 _current_trans.top()->set_timestamp(now);
2345 _history.add(_current_trans.top());
2346 _current_trans.pop();
2350 accept_all_non_peak_files (const string& path, void */*arg*/)
2352 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2356 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2360 accept_all_state_files (const string& path, void */*arg*/)
2362 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2366 Session::find_all_sources (string path, set<string>& result)
2371 if (!tree.read (path)) {
2375 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2380 XMLNodeConstIterator niter;
2382 nlist = node->children();
2386 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2390 if ((prop = (*niter)->property (X_("type"))) == 0) {
2394 DataType type (prop->value());
2396 if ((prop = (*niter)->property (X_("name"))) == 0) {
2400 if (prop->value()[0] == '/') {
2401 /* external file, ignore */
2405 Glib::ustring found_path;
2409 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2410 result.insert (found_path);
2418 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2420 PathScanner scanner;
2421 vector<string*>* state_files;
2423 string this_snapshot_path;
2429 if (ripped[ripped.length()-1] == '/') {
2430 ripped = ripped.substr (0, ripped.length() - 1);
2433 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2435 if (state_files == 0) {
2440 this_snapshot_path = _path;
2441 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2442 this_snapshot_path += statefile_suffix;
2444 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2446 if (exclude_this_snapshot && **i == this_snapshot_path) {
2450 if (find_all_sources (**i, result) < 0) {
2458 struct RegionCounter {
2459 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2460 AudioSourceList::iterator iter;
2461 boost::shared_ptr<Region> region;
2464 RegionCounter() : count (0) {}
2468 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2470 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2471 return r.get_value_or (1);
2475 Session::cleanup_sources (CleanupReport& rep)
2477 // FIXME: needs adaptation to midi
2479 vector<boost::shared_ptr<Source> > dead_sources;
2480 PathScanner scanner;
2482 vector<space_and_path>::iterator i;
2483 vector<space_and_path>::iterator nexti;
2484 vector<string*>* soundfiles;
2485 vector<string> unused;
2486 set<string> all_sources;
2491 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2493 /* step 1: consider deleting all unused playlists */
2495 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2500 /* step 2: find all un-used sources */
2505 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2507 SourceMap::iterator tmp;
2512 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2516 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2517 dead_sources.push_back (i->second);
2518 i->second->drop_references ();
2524 /* build a list of all the possible sound directories for the session */
2526 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2531 SessionDirectory sdir ((*i).path);
2532 sound_path += sdir.sound_path().to_string();
2534 if (nexti != session_dirs.end()) {
2541 /* now do the same thing for the files that ended up in the sounds dir(s)
2542 but are not referenced as sources in any snapshot.
2545 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2547 if (soundfiles == 0) {
2551 /* find all sources, but don't use this snapshot because the
2552 state file on disk still references sources we may have already
2556 find_all_sources_across_snapshots (all_sources, true);
2558 /* add our current source list
2561 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2562 boost::shared_ptr<FileSource> fs;
2564 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2565 all_sources.insert (fs->path());
2569 char tmppath1[PATH_MAX+1];
2570 char tmppath2[PATH_MAX+1];
2572 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2577 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2579 if (realpath(spath.c_str(), tmppath1) == 0) {
2580 error << string_compose (_("Cannot expand path %1 (%2)"),
2581 spath, strerror (errno)) << endmsg;
2585 if (realpath((*i).c_str(), tmppath2) == 0) {
2586 error << string_compose (_("Cannot expand path %1 (%2)"),
2587 (*i), strerror (errno)) << endmsg;
2591 if (strcmp(tmppath1, tmppath2) == 0) {
2598 unused.push_back (spath);
2602 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2604 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2605 struct stat statbuf;
2607 rep.paths.push_back (*x);
2608 if (stat ((*x).c_str(), &statbuf) == 0) {
2609 rep.space += statbuf.st_size;
2614 /* don't move the file across filesystems, just
2615 stick it in the `dead_sound_dir_name' directory
2616 on whichever filesystem it was already on.
2619 if ((*x).find ("/sounds/") != string::npos) {
2621 /* old school, go up 1 level */
2623 newpath = Glib::path_get_dirname (*x); // "sounds"
2624 newpath = Glib::path_get_dirname (newpath); // "session-name"
2628 /* new school, go up 4 levels */
2630 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2631 newpath = Glib::path_get_dirname (newpath); // "session-name"
2632 newpath = Glib::path_get_dirname (newpath); // "interchange"
2633 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2637 newpath += dead_sound_dir_name;
2639 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2640 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2645 newpath += Glib::path_get_basename ((*x));
2647 if (access (newpath.c_str(), F_OK) == 0) {
2649 /* the new path already exists, try versioning */
2651 char buf[PATH_MAX+1];
2655 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2658 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2659 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2663 if (version == 999) {
2664 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2668 newpath = newpath_v;
2673 /* it doesn't exist, or we can't read it or something */
2677 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2678 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2679 (*x), newpath, strerror (errno))
2684 /* see if there an easy to find peakfile for this file, and remove it.
2687 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2688 peakpath += peakfile_suffix;
2690 if (access (peakpath.c_str(), W_OK) == 0) {
2691 if (::unlink (peakpath.c_str()) != 0) {
2692 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2693 peakpath, _path, strerror (errno))
2695 /* try to back out */
2696 rename (newpath.c_str(), _path.c_str());
2704 /* dump the history list */
2708 /* save state so we don't end up a session file
2709 referring to non-existent sources.
2715 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2721 Session::cleanup_trash_sources (CleanupReport& rep)
2723 // FIXME: needs adaptation for MIDI
2725 vector<space_and_path>::iterator i;
2726 string dead_sound_dir;
2731 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2733 dead_sound_dir = (*i).path;
2734 dead_sound_dir += dead_sound_dir_name;
2736 clear_directory (dead_sound_dir, &rep.space, &rep.paths);
2743 Session::cleanup_stubfiles ()
2745 vector<space_and_path>::iterator i;
2747 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2750 string lname = legalize_for_path (_name);
2754 /* XXX this is a hack caused by semantic conflicts
2755 between space_and_path and the SessionDirectory concept.
2758 v.push_back ((*i).path);
2759 v.push_back ("interchange");
2760 v.push_back (lname);
2761 v.push_back ("audiofiles");
2762 v.push_back (stub_dir_name);
2764 dir = Glib::build_filename (v);
2766 clear_directory (dir);
2769 v.push_back ((*i).path);
2770 v.push_back ("interchange");
2771 v.push_back (lname);
2772 v.push_back ("midifiles");
2773 v.push_back (stub_dir_name);
2775 dir = Glib::build_filename (v);
2777 clear_directory (dir);
2782 Session::set_dirty ()
2784 bool was_dirty = dirty();
2786 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2790 DirtyChanged(); /* EMIT SIGNAL */
2796 Session::set_clean ()
2798 bool was_dirty = dirty();
2800 _state_of_the_state = Clean;
2804 DirtyChanged(); /* EMIT SIGNAL */
2809 Session::set_deletion_in_progress ()
2811 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2815 Session::clear_deletion_in_progress ()
2817 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2821 Session::add_controllable (boost::shared_ptr<Controllable> c)
2823 /* this adds a controllable to the list managed by the Session.
2824 this is a subset of those managed by the Controllable class
2825 itself, and represents the only ones whose state will be saved
2826 as part of the session.
2829 Glib::Mutex::Lock lm (controllables_lock);
2830 controllables.insert (c);
2833 struct null_deleter { void operator()(void const *) const {} };
2836 Session::remove_controllable (Controllable* c)
2838 if (_state_of_the_state | Deletion) {
2842 Glib::Mutex::Lock lm (controllables_lock);
2844 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2846 if (x != controllables.end()) {
2847 controllables.erase (x);
2851 boost::shared_ptr<Controllable>
2852 Session::controllable_by_id (const PBD::ID& id)
2854 Glib::Mutex::Lock lm (controllables_lock);
2856 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2857 if ((*i)->id() == id) {
2862 return boost::shared_ptr<Controllable>();
2865 boost::shared_ptr<Controllable>
2866 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2868 boost::shared_ptr<Controllable> c;
2869 boost::shared_ptr<Route> r;
2871 switch (desc.top_level_type()) {
2872 case ControllableDescriptor::NamedRoute:
2874 std::string str = desc.top_level_name();
2875 if (str == "master") {
2877 } else if (str == "control" || str == "listen") {
2880 r = route_by_name (desc.top_level_name());
2885 case ControllableDescriptor::RemoteControlID:
2886 r = route_by_remote_id (desc.rid());
2894 switch (desc.subtype()) {
2895 case ControllableDescriptor::Gain:
2896 c = r->gain_control ();
2899 case ControllableDescriptor::Solo:
2900 c = r->solo_control();
2903 case ControllableDescriptor::Mute:
2904 c = r->mute_control();
2907 case ControllableDescriptor::Recenable:
2909 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2912 c = t->rec_enable_control ();
2917 case ControllableDescriptor::Pan:
2918 /* XXX pan control */
2921 case ControllableDescriptor::Balance:
2922 /* XXX simple pan control */
2925 case ControllableDescriptor::PluginParameter:
2927 uint32_t plugin = desc.target (0);
2928 uint32_t parameter_index = desc.target (1);
2930 /* revert to zero based counting */
2936 if (parameter_index > 0) {
2940 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
2943 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
2944 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
2949 case ControllableDescriptor::SendGain:
2951 uint32_t send = desc.target (0);
2953 /* revert to zero-based counting */
2959 boost::shared_ptr<Processor> p = r->nth_send (send);
2962 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
2963 boost::shared_ptr<Amp> a = s->amp();
2966 c = s->amp()->gain_control();
2973 /* relax and return a null pointer */
2981 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2984 Stateful::add_instant_xml (node, _path);
2987 if (write_to_config) {
2988 Config->add_instant_xml (node);
2993 Session::instant_xml (const string& node_name)
2995 return Stateful::instant_xml (node_name, _path);
2999 Session::save_history (string snapshot_name)
3007 if (snapshot_name.empty()) {
3008 snapshot_name = _current_snapshot_name;
3011 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3012 const string backup_filename = history_filename + backup_suffix;
3013 const sys::path xml_path = _session_dir->root_path() / history_filename;
3014 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3016 if (sys::exists (xml_path)) {
3019 sys::rename (xml_path, backup_path);
3021 catch (const sys::filesystem_error& err)
3023 error << _("could not backup old history file, current history not saved") << endmsg;
3028 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3032 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3034 if (!tree.write (xml_path.to_string()))
3036 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3040 sys::remove (xml_path);
3041 sys::rename (backup_path, xml_path);
3043 catch (const sys::filesystem_error& err)
3045 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3046 backup_path.to_string(), err.what()) << endmsg;
3056 Session::restore_history (string snapshot_name)
3060 if (snapshot_name.empty()) {
3061 snapshot_name = _current_snapshot_name;
3064 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3065 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3067 info << "Loading history from " << xml_path.to_string() << endmsg;
3069 if (!sys::exists (xml_path)) {
3070 info << string_compose (_("%1: no history file \"%2\" for this session."),
3071 _name, xml_path.to_string()) << endmsg;
3075 if (!tree.read (xml_path.to_string())) {
3076 error << string_compose (_("Could not understand session history file \"%1\""),
3077 xml_path.to_string()) << endmsg;
3084 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3087 UndoTransaction* ut = new UndoTransaction ();
3090 ut->set_name(t->property("name")->value());
3091 stringstream ss(t->property("tv-sec")->value());
3093 ss.str(t->property("tv-usec")->value());
3095 ut->set_timestamp(tv);
3097 for (XMLNodeConstIterator child_it = t->children().begin();
3098 child_it != t->children().end(); child_it++)
3100 XMLNode *n = *child_it;
3103 if (n->name() == "MementoCommand" ||
3104 n->name() == "MementoUndoCommand" ||
3105 n->name() == "MementoRedoCommand") {
3107 if ((c = memento_command_factory(n))) {
3111 } else if (n->name() == "DiffCommand") {
3112 PBD::ID id(n->property("midi-source")->value());
3113 boost::shared_ptr<MidiSource> midi_source =
3114 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3116 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
3118 error << _("Failed to downcast MidiSource for DiffCommand") << endmsg;
3121 } else if (n->name() == "StatefulDiffCommand") {
3122 if ((c = stateful_diff_command_factory (n))) {
3123 ut->add_command (c);
3126 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3137 Session::config_changed (std::string p, bool ours)
3143 if (p == "seamless-loop") {
3145 } else if (p == "rf-speed") {
3147 } else if (p == "auto-loop") {
3149 } else if (p == "auto-input") {
3151 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3152 /* auto-input only makes a difference if we're rolling */
3154 boost::shared_ptr<RouteList> rl = routes.reader ();
3155 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3156 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3157 if (tr && tr->record_enabled ()) {
3158 tr->monitor_input (!config.get_auto_input());
3163 } else if (p == "punch-in") {
3167 if ((location = _locations.auto_punch_location()) != 0) {
3169 if (config.get_punch_in ()) {
3170 replace_event (SessionEvent::PunchIn, location->start());
3172 remove_event (location->start(), SessionEvent::PunchIn);
3176 } else if (p == "punch-out") {
3180 if ((location = _locations.auto_punch_location()) != 0) {
3182 if (config.get_punch_out()) {
3183 replace_event (SessionEvent::PunchOut, location->end());
3185 clear_events (SessionEvent::PunchOut);
3189 } else if (p == "edit-mode") {
3191 Glib::Mutex::Lock lm (playlists->lock);
3193 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3194 (*i)->set_edit_mode (Config->get_edit_mode ());
3197 } else if (p == "use-video-sync") {
3199 waiting_for_sync_offset = config.get_use_video_sync();
3201 } else if (p == "mmc-control") {
3203 //poke_midi_thread ();
3205 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3207 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3209 } else if (p == "mmc-send-id") {
3211 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3213 } else if (p == "midi-control") {
3215 //poke_midi_thread ();
3217 } else if (p == "raid-path") {
3219 setup_raid_path (config.get_raid_path());
3221 } else if (p == "timecode-format") {
3225 } else if (p == "video-pullup") {
3229 } else if (p == "seamless-loop") {
3231 if (play_loop && transport_rolling()) {
3232 // to reset diskstreams etc
3233 request_play_loop (true);
3236 } else if (p == "rf-speed") {
3238 cumulative_rf_motion = 0;
3241 } else if (p == "click-sound") {
3243 setup_click_sounds (1);
3245 } else if (p == "click-emphasis-sound") {
3247 setup_click_sounds (-1);
3249 } else if (p == "clicking") {
3251 if (Config->get_clicking()) {
3252 if (_click_io && click_data) { // don't require emphasis data
3259 } else if (p == "send-mtc") {
3261 session_send_mtc = Config->get_send_mtc();
3262 if (session_send_mtc) {
3263 /* mark us ready to send */
3264 next_quarter_frame_to_send = 0;
3267 } else if (p == "send-mmc") {
3269 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3271 } else if (p == "midi-feedback") {
3273 session_midi_feedback = Config->get_midi_feedback();
3275 } else if (p == "jack-time-master") {
3277 engine().reset_timebase ();
3279 } else if (p == "native-file-header-format") {
3281 if (!first_file_header_format_reset) {
3282 reset_native_file_format ();
3285 first_file_header_format_reset = false;
3287 } else if (p == "native-file-data-format") {
3289 if (!first_file_data_format_reset) {
3290 reset_native_file_format ();
3293 first_file_data_format_reset = false;
3295 } else if (p == "external-sync") {
3296 if (!config.get_external_sync()) {
3297 drop_sync_source ();
3299 switch_to_sync_source (config.get_sync_source());
3301 } else if (p == "remote-model") {
3302 set_remote_control_ids ();
3303 } else if (p == "denormal-model") {
3305 } else if (p == "history-depth") {
3306 set_history_depth (Config->get_history_depth());
3307 } else if (p == "sync-all-route-ordering") {
3308 sync_order_keys ("session");
3309 } else if (p == "initial-program-change") {
3311 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3314 buf[0] = MIDI::program; // channel zero by default
3315 buf[1] = (Config->get_initial_program_change() & 0x7f);
3317 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3319 } else if (p == "solo-mute-override") {
3320 // catch_up_on_solo_mute_override ();
3321 } else if (p == "listen-position") {
3322 listen_position_changed ();
3323 } else if (p == "solo-control-is-listen-control") {
3324 solo_control_mode_changed ();
3332 Session::set_history_depth (uint32_t d)
3334 _history.set_depth (d);
3338 Session::load_diskstreams_2X (XMLNode const & node, int)
3341 XMLNodeConstIterator citer;
3343 clist = node.children();
3345 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3348 /* diskstreams added automatically by DiskstreamCreated handler */
3349 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3350 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3351 _diskstreams_2X.push_back (dsp);
3353 error << _("Session: unknown diskstream type in XML") << endmsg;
3357 catch (failed_constructor& err) {
3358 error << _("Session: could not load diskstream via XML state") << endmsg;
3366 /** Connect things to the MMC object */
3368 Session::setup_midi_machine_control ()
3370 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3372 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3373 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3374 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3375 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3376 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3377 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3378 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3379 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3380 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3381 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3382 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3383 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3384 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3386 /* also handle MIDI SPP because its so common */
3388 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3389 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3390 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));