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;
221 AudioDiskstream::allocate_working_buffers();
223 /* default short fade = 15ms */
225 Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
226 SndFileSource::setup_standard_crossfades (*this, frame_rate());
228 last_mmc_step.tv_sec = 0;
229 last_mmc_step.tv_usec = 0;
232 /* click sounds are unset by default, which causes us to internal
233 waveforms for clicks.
237 click_emphasis_length = 0;
240 process_function = &Session::process_with_events;
242 if (config.get_use_video_sync()) {
243 waiting_for_sync_offset = true;
245 waiting_for_sync_offset = false;
248 last_timecode_when = 0;
249 _timecode_offset = 0;
250 _timecode_offset_negative = true;
251 last_timecode_valid = false;
255 last_rr_session_dir = session_dirs.begin();
256 refresh_disk_space ();
258 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
262 average_slave_delta = 1800; // !!! why 1800 ????
263 have_first_delta_accumulator = false;
264 delta_accumulator_cnt = 0;
265 _slave_state = Stopped;
267 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
269 /* These are all static "per-class" signals */
271 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
272 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
273 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
274 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
275 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
277 /* stop IO objects from doing stuff until we're ready for them */
279 Delivery::disable_panners ();
280 IO::disable_connecting ();
284 Session::second_stage_init ()
286 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
289 if (load_state (_current_snapshot_name)) {
292 cleanup_stubfiles ();
295 if (_butler->start_thread()) {
299 if (start_midi_thread ()) {
303 setup_midi_machine_control ();
305 // set_state() will call setup_raid_path(), but if it's a new session we need
306 // to call setup_raid_path() here.
309 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
313 setup_raid_path(_path);
316 /* we can't save till after ::when_engine_running() is called,
317 because otherwise we save state with no connections made.
318 therefore, we reset _state_of_the_state because ::set_state()
319 will have cleared it.
321 we also have to include Loading so that any events that get
322 generated between here and the end of ::when_engine_running()
323 will be processed directly rather than queued.
326 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
328 _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
329 _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
330 setup_click_sounds (0);
331 setup_midi_control ();
333 /* Pay attention ... */
335 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
336 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
339 when_engine_running ();
342 /* handle this one in a different way than all others, so that its clear what happened */
344 catch (AudioEngine::PortRegistrationFailure& err) {
345 error << err.what() << endmsg;
353 BootMessage (_("Reset Remote Controls"));
355 send_full_time_code (0);
356 _engine.transport_locate (0);
358 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
359 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
361 MidiClockTicker::instance().set_session (this);
362 MIDI::Name::MidiPatchManager::instance().set_session (this);
364 /* initial program change will be delivered later; see ::config_changed() */
366 BootMessage (_("Reset Control Protocols"));
368 ControlProtocolManager::instance().set_session (this);
370 _state_of_the_state = Clean;
372 Port::set_connecting_blocked (false);
374 DirtyChanged (); /* EMIT SIGNAL */
376 if (state_was_pending) {
377 save_state (_current_snapshot_name);
378 remove_pending_capture_state ();
379 state_was_pending = false;
382 BootMessage (_("Session loading complete"));
388 Session::raid_path () const
390 SearchPath raid_search_path;
392 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
393 raid_search_path += sys::path((*i).path);
396 return raid_search_path.to_string ();
400 Session::setup_raid_path (string path)
409 session_dirs.clear ();
411 SearchPath search_path(path);
412 SearchPath sound_search_path;
413 SearchPath midi_search_path;
415 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
416 sp.path = (*i).to_string ();
417 sp.blocks = 0; // not needed
418 session_dirs.push_back (sp);
420 SessionDirectory sdir(sp.path);
422 sound_search_path += sdir.sound_path ();
423 midi_search_path += sdir.midi_path ();
426 // set the search path for each data type
427 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
428 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
430 // reset the round-robin soundfile path thingie
431 last_rr_session_dir = session_dirs.begin();
435 Session::path_is_within_session (const std::string& path)
437 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
438 if (path.find ((*i).path) == 0) {
446 Session::ensure_subdirs ()
450 dir = session_directory().peak_path().to_string();
452 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
453 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
457 dir = session_directory().sound_path().to_string();
459 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
460 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
464 dir = session_directory().sound_stub_path().to_string();
466 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
467 error << string_compose(_("Session: cannot create session stub sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
471 dir = session_directory().midi_path().to_string();
473 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
474 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
478 dir = session_directory().midi_stub_path().to_string();
480 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
481 error << string_compose(_("Session: cannot create session stub midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
485 dir = session_directory().dead_sound_path().to_string();
487 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
488 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
492 dir = session_directory().export_path().to_string();
494 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
495 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
499 dir = analysis_dir ();
501 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
502 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
510 Session::create (const string& mix_template, BusProfile* bus_profile)
513 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
514 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
518 if (ensure_subdirs ()) {
522 if (!mix_template.empty()) {
523 std::string in_path = mix_template;
525 ifstream in(in_path.c_str());
528 string out_path = _path;
530 out_path += statefile_suffix;
532 ofstream out(out_path.c_str());
540 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
546 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
553 /* Instantiate metadata */
555 _metadata = new SessionMetadata ();
557 /* set initial start + end point */
559 _state_of_the_state = Clean;
561 /* set up Master Out and Control Out if necessary */
567 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
569 if (bus_profile->master_out_channels) {
570 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
575 boost_debug_shared_ptr_mark_interesting (rt, "Route");
576 boost::shared_ptr<Route> r (rt);
577 r->input()->ensure_io (count, false, this);
578 r->output()->ensure_io (count, false, this);
579 r->set_remote_control_id (control_id++);
583 if (Config->get_use_monitor_bus()) {
584 Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO);
589 boost_debug_shared_ptr_mark_interesting (rt, "Route");
590 boost::shared_ptr<Route> r (rt);
591 r->input()->ensure_io (count, false, this);
592 r->output()->ensure_io (count, false, this);
593 r->set_remote_control_id (control_id);
599 /* prohibit auto-connect to master, because there isn't one */
600 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
604 add_routes (rl, false);
607 /* this allows the user to override settings with an environment variable.
610 if (no_auto_connect()) {
611 bus_profile->input_ac = AutoConnectOption (0);
612 bus_profile->output_ac = AutoConnectOption (0);
615 Config->set_input_auto_connect (bus_profile->input_ac);
616 Config->set_output_auto_connect (bus_profile->output_ac);
625 Session::maybe_write_autosave()
627 if (dirty() && record_status() != Recording) {
628 save_state("", true);
633 Session::remove_pending_capture_state ()
635 sys::path pending_state_file_path(_session_dir->root_path());
637 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
641 sys::remove (pending_state_file_path);
643 catch(sys::filesystem_error& ex)
645 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
646 pending_state_file_path.to_string(), ex.what()) << endmsg;
650 /** Rename a state file.
651 * @param snapshot_name 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 // TODO: make ardour quit.
752 jack_session_event_free( event );
757 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
760 sys::path xml_path(_session_dir->root_path());
762 if (!_writable || (_state_of_the_state & CannotSave)) {
766 if (!_engine.connected ()) {
767 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
773 /* tell sources we're saving first, in case they write out to a new file
774 * which should be saved with the state rather than the old one */
775 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
776 i->second->session_saved();
779 tree.set_root (&get_state());
781 if (snapshot_name.empty()) {
782 snapshot_name = _current_snapshot_name;
783 } else if (switch_to_snapshot) {
784 _current_snapshot_name = snapshot_name;
789 /* proper save: use statefile_suffix (.ardour in English) */
791 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
793 /* make a backup copy of the old file */
795 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
796 // create_backup_file will log the error
802 /* pending save: use pending_suffix (.pending in English) */
803 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
806 sys::path tmp_path(_session_dir->root_path());
808 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
810 // cerr << "actually writing state to " << xml_path.to_string() << endl;
812 if (!tree.write (tmp_path.to_string())) {
813 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
814 sys::remove (tmp_path);
819 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
820 error << string_compose (_("could not rename temporary session file %1 to %2"),
821 tmp_path.to_string(), xml_path.to_string()) << endmsg;
822 sys::remove (tmp_path);
829 save_history (snapshot_name);
831 bool was_dirty = dirty();
833 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
836 DirtyChanged (); /* EMIT SIGNAL */
839 StateSaved (snapshot_name); /* EMIT SIGNAL */
846 Session::restore_state (string snapshot_name)
848 if (load_state (snapshot_name) == 0) {
849 set_state (*state_tree->root(), Stateful::loading_state_version);
856 Session::load_state (string snapshot_name)
861 state_was_pending = false;
863 /* check for leftover pending state from a crashed capture attempt */
865 sys::path xmlpath(_session_dir->root_path());
866 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
868 if (sys::exists (xmlpath)) {
870 /* there is pending state from a crashed capture attempt */
872 boost::optional<int> r = AskAboutPendingState();
873 if (r.get_value_or (1)) {
874 state_was_pending = true;
878 if (!state_was_pending) {
879 xmlpath = _session_dir->root_path();
880 xmlpath /= snapshot_name;
883 if (!sys::exists (xmlpath)) {
884 xmlpath = _session_dir->root_path();
885 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
886 if (!sys::exists (xmlpath)) {
887 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
892 state_tree = new XMLTree;
896 /* writable() really reflects the whole folder, but if for any
897 reason the session state file can't be written to, still
901 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
905 if (!state_tree->read (xmlpath.to_string())) {
906 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
912 XMLNode& root (*state_tree->root());
914 if (root.name() != X_("Session")) {
915 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
921 const XMLProperty* prop;
923 if ((prop = root.property ("version")) == 0) {
924 /* no version implies very old version of Ardour */
925 Stateful::loading_state_version = 1000;
931 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
932 Stateful::loading_state_version = (major * 1000) + minor;
935 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
937 sys::path backup_path(_session_dir->root_path());
939 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
941 // only create a backup once
942 if (sys::exists (backup_path)) {
946 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
947 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
952 sys::copy_file (xmlpath, backup_path);
954 catch(sys::filesystem_error& ex)
956 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
957 xmlpath.to_string(), ex.what())
967 Session::load_options (const XMLNode& node)
969 LocaleGuard lg (X_("POSIX"));
970 config.set_variables (node);
981 Session::get_template()
983 /* if we don't disable rec-enable, diskstreams
984 will believe they need to store their capture
985 sources in their state node.
988 disable_record (false);
994 Session::state(bool full_state)
996 XMLNode* node = new XMLNode("Session");
999 // store libardour version, just in case
1001 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
1002 node->add_property("version", string(buf));
1004 /* store configuration settings */
1008 node->add_property ("name", _name);
1009 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
1010 node->add_property ("sample-rate", buf);
1012 if (session_dirs.size() > 1) {
1016 vector<space_and_path>::iterator i = session_dirs.begin();
1017 vector<space_and_path>::iterator next;
1019 ++i; /* skip the first one */
1023 while (i != session_dirs.end()) {
1027 if (next != session_dirs.end()) {
1037 child = node->add_child ("Path");
1038 child->add_content (p);
1042 /* save the ID counter */
1044 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1045 node->add_property ("id-counter", buf);
1047 /* save the event ID counter */
1049 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1050 node->add_property ("event-counter", buf);
1052 /* various options */
1054 node->add_child_nocopy (config.get_variables ());
1056 node->add_child_nocopy (_metadata->get_state());
1058 child = node->add_child ("Sources");
1061 Glib::Mutex::Lock sl (source_lock);
1063 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1065 /* Don't save information about non-destructive file sources that are empty
1066 and unused by any regions.
1069 boost::shared_ptr<FileSource> fs;
1070 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1071 if (!fs->destructive()) {
1072 if (fs->empty() && !fs->used()) {
1078 child->add_child_nocopy (siter->second->get_state());
1082 child = node->add_child ("Regions");
1085 Glib::Mutex::Lock rl (region_lock);
1086 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1087 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1088 boost::shared_ptr<Region> r = i->second;
1089 /* only store regions not attached to playlists */
1090 if (r->playlist() == 0) {
1091 child->add_child_nocopy (r->state ());
1097 node->add_child_nocopy (_locations.get_state());
1099 // for a template, just create a new Locations, populate it
1100 // with the default start and end, and get the state for that.
1102 Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
1103 range->set (max_frames, 0);
1105 node->add_child_nocopy (loc.get_state());
1108 child = node->add_child ("Bundles");
1110 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1111 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1112 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1114 child->add_child_nocopy (b->get_state());
1119 child = node->add_child ("Routes");
1121 boost::shared_ptr<RouteList> r = routes.reader ();
1123 RoutePublicOrderSorter cmp;
1124 RouteList public_order (*r);
1125 public_order.sort (cmp);
1127 /* the sort should have put control outs first */
1130 assert (_monitor_out == public_order.front());
1133 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1134 if (!(*i)->is_hidden()) {
1136 child->add_child_nocopy ((*i)->get_state());
1138 child->add_child_nocopy ((*i)->get_template());
1144 playlists->add_state (node, full_state);
1146 child = node->add_child ("RouteGroups");
1147 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1148 child->add_child_nocopy ((*i)->get_state());
1152 child = node->add_child ("Click");
1153 child->add_child_nocopy (_click_io->state (full_state));
1157 child = node->add_child ("NamedSelections");
1158 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1160 child->add_child_nocopy ((*i)->get_state());
1165 node->add_child_nocopy (_tempo_map->get_state());
1167 node->add_child_nocopy (get_control_protocol_state());
1170 node->add_child_copy (*_extra_xml);
1177 Session::get_control_protocol_state ()
1179 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1180 return cpm.get_state();
1184 Session::set_state (const XMLNode& node, int version)
1188 const XMLProperty* prop;
1191 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1193 if (node.name() != X_("Session")){
1194 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1198 if ((prop = node.property ("version")) != 0) {
1199 version = atoi (prop->value ()) * 1000;
1202 if ((prop = node.property ("name")) != 0) {
1203 _name = prop->value ();
1206 if ((prop = node.property (X_("sample-rate"))) != 0) {
1208 _nominal_frame_rate = atoi (prop->value());
1210 if (_nominal_frame_rate != _current_frame_rate) {
1211 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1212 if (r.get_value_or (0)) {
1218 setup_raid_path(_session_dir->root_path().to_string());
1220 if ((prop = node.property (X_("id-counter"))) != 0) {
1222 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1223 ID::init_counter (x);
1225 /* old sessions used a timebased counter, so fake
1226 the startup ID counter based on a standard
1231 ID::init_counter (now);
1234 if ((prop = node.property (X_("event-counter"))) != 0) {
1235 Evoral::init_event_id_counter (atoi (prop->value()));
1238 IO::disable_connecting ();
1240 /* Object loading order:
1245 MIDI Control // relies on data from Options/Config
1258 if ((child = find_named_node (node, "Extra")) != 0) {
1259 _extra_xml = new XMLNode (*child);
1262 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1263 load_options (*child);
1264 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1265 load_options (*child);
1267 error << _("Session: XML state has no options section") << endmsg;
1270 if (version >= 3000) {
1271 if ((child = find_named_node (node, "Metadata")) == 0) {
1272 warning << _("Session: XML state has no metadata section") << endmsg;
1273 } else if (_metadata->set_state (*child, version)) {
1278 if ((child = find_named_node (node, "Locations")) == 0) {
1279 error << _("Session: XML state has no locations section") << endmsg;
1281 } else if (_locations.set_state (*child, version)) {
1287 if ((location = _locations.auto_loop_location()) != 0) {
1288 set_auto_loop_location (location);
1291 if ((location = _locations.auto_punch_location()) != 0) {
1292 set_auto_punch_location (location);
1295 if ((location = _locations.session_range_location()) != 0) {
1296 delete _session_range_location;
1297 _session_range_location = location;
1300 if (_session_range_location) {
1301 AudioFileSource::set_header_position_offset (_session_range_location->start());
1304 if ((child = find_named_node (node, "Sources")) == 0) {
1305 error << _("Session: XML state has no sources section") << endmsg;
1307 } else if (load_sources (*child)) {
1311 if ((child = find_named_node (node, "Regions")) == 0) {
1312 error << _("Session: XML state has no Regions section") << endmsg;
1314 } else if (load_regions (*child)) {
1318 if ((child = find_named_node (node, "Playlists")) == 0) {
1319 error << _("Session: XML state has no playlists section") << endmsg;
1321 } else if (playlists->load (*this, *child)) {
1325 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1327 } else if (playlists->load_unused (*this, *child)) {
1331 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1332 if (load_named_selections (*child)) {
1337 if (version >= 3000) {
1338 if ((child = find_named_node (node, "Bundles")) == 0) {
1339 warning << _("Session: XML state has no bundles section") << endmsg;
1342 /* We can't load Bundles yet as they need to be able
1343 to convert from port names to Port objects, which can't happen until
1345 _bundle_xml_node = new XMLNode (*child);
1349 if ((child = find_named_node (node, "TempoMap")) == 0) {
1350 error << _("Session: XML state has no Tempo Map section") << endmsg;
1352 } else if (_tempo_map->set_state (*child, version)) {
1356 if (version < 3000) {
1357 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1358 error << _("Session: XML state has no diskstreams section") << endmsg;
1360 } else if (load_diskstreams_2X (*child, version)) {
1365 if ((child = find_named_node (node, "Routes")) == 0) {
1366 error << _("Session: XML state has no routes section") << endmsg;
1368 } else if (load_routes (*child, version)) {
1372 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1373 _diskstreams_2X.clear ();
1375 if (version >= 3000) {
1377 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1378 error << _("Session: XML state has no route groups section") << endmsg;
1380 } else if (load_route_groups (*child, version)) {
1384 } else if (version < 3000) {
1386 if ((child = find_named_node (node, "EditGroups")) == 0) {
1387 error << _("Session: XML state has no edit groups section") << endmsg;
1389 } else if (load_route_groups (*child, version)) {
1393 if ((child = find_named_node (node, "MixGroups")) == 0) {
1394 error << _("Session: XML state has no mix groups section") << endmsg;
1396 } else if (load_route_groups (*child, version)) {
1401 if ((child = find_named_node (node, "Click")) == 0) {
1402 warning << _("Session: XML state has no click section") << endmsg;
1403 } else if (_click_io) {
1404 _click_io->set_state (*child, version);
1407 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1408 ControlProtocolManager::instance().set_protocol_states (*child);
1411 /* here beginneth the second phase ... */
1413 StateReady (); /* EMIT SIGNAL */
1422 Session::load_routes (const XMLNode& node, int version)
1425 XMLNodeConstIterator niter;
1426 RouteList new_routes;
1428 nlist = node.children();
1432 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1434 boost::shared_ptr<Route> route;
1435 if (version < 3000) {
1436 route = XMLRouteFactory_2X (**niter, version);
1438 route = XMLRouteFactory (**niter, version);
1442 error << _("Session: cannot create Route from XML description.") << endmsg;
1446 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1448 new_routes.push_back (route);
1451 add_routes (new_routes, false);
1456 boost::shared_ptr<Route>
1457 Session::XMLRouteFactory (const XMLNode& node, int version)
1459 boost::shared_ptr<Route> ret;
1461 if (node.name() != "Route") {
1465 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1467 DataType type = DataType::AUDIO;
1468 const XMLProperty* prop = node.property("default-type");
1471 type = DataType (prop->value());
1474 assert (type != DataType::NIL);
1480 if (type == DataType::AUDIO) {
1481 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1484 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1487 if (track->init()) {
1492 if (track->set_state (node, version)) {
1497 boost_debug_shared_ptr_mark_interesting (track, "Track");
1501 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1503 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1504 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1514 boost::shared_ptr<Route>
1515 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1517 boost::shared_ptr<Route> ret;
1519 if (node.name() != "Route") {
1523 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1525 ds_prop = node.property (X_("diskstream"));
1528 DataType type = DataType::AUDIO;
1529 const XMLProperty* prop = node.property("default-type");
1532 type = DataType (prop->value());
1535 assert (type != DataType::NIL);
1539 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1540 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1544 if (i == _diskstreams_2X.end()) {
1545 error << _("Could not find diskstream for route") << endmsg;
1546 return boost::shared_ptr<Route> ();
1551 if (type == DataType::AUDIO) {
1552 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1555 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1558 if (track->init()) {
1563 if (track->set_state (node, version)) {
1568 track->set_diskstream (*i);
1570 boost_debug_shared_ptr_mark_interesting (track, "Track");
1574 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1576 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1577 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1588 Session::load_regions (const XMLNode& node)
1591 XMLNodeConstIterator niter;
1592 boost::shared_ptr<Region> region;
1594 nlist = node.children();
1598 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1599 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1600 error << _("Session: cannot create Region from XML description.");
1601 const XMLProperty *name = (**niter).property("name");
1604 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1614 boost::shared_ptr<Region>
1615 Session::XMLRegionFactory (const XMLNode& node, bool full)
1617 const XMLProperty* type = node.property("type");
1621 if (!type || type->value() == "audio") {
1622 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1623 } else if (type->value() == "midi") {
1624 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1627 } catch (failed_constructor& err) {
1628 return boost::shared_ptr<Region> ();
1631 return boost::shared_ptr<Region> ();
1634 boost::shared_ptr<AudioRegion>
1635 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1637 const XMLProperty* prop;
1638 boost::shared_ptr<Source> source;
1639 boost::shared_ptr<AudioSource> as;
1641 SourceList master_sources;
1642 uint32_t nchans = 1;
1645 if (node.name() != X_("Region")) {
1646 return boost::shared_ptr<AudioRegion>();
1649 if ((prop = node.property (X_("channels"))) != 0) {
1650 nchans = atoi (prop->value().c_str());
1653 if ((prop = node.property ("name")) == 0) {
1654 cerr << "no name for this region\n";
1658 if ((prop = node.property (X_("source-0"))) == 0) {
1659 if ((prop = node.property ("source")) == 0) {
1660 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1661 return boost::shared_ptr<AudioRegion>();
1665 PBD::ID s_id (prop->value());
1667 if ((source = source_by_id (s_id)) == 0) {
1668 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1669 return boost::shared_ptr<AudioRegion>();
1672 as = boost::dynamic_pointer_cast<AudioSource>(source);
1674 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1675 return boost::shared_ptr<AudioRegion>();
1678 sources.push_back (as);
1680 /* pickup other channels */
1682 for (uint32_t n=1; n < nchans; ++n) {
1683 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1684 if ((prop = node.property (buf)) != 0) {
1686 PBD::ID id2 (prop->value());
1688 if ((source = source_by_id (id2)) == 0) {
1689 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1690 return boost::shared_ptr<AudioRegion>();
1693 as = boost::dynamic_pointer_cast<AudioSource>(source);
1695 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1696 return boost::shared_ptr<AudioRegion>();
1698 sources.push_back (as);
1702 for (uint32_t n = 0; n < nchans; ++n) {
1703 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1704 if ((prop = node.property (buf)) != 0) {
1706 PBD::ID id2 (prop->value());
1708 if ((source = source_by_id (id2)) == 0) {
1709 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1710 return boost::shared_ptr<AudioRegion>();
1713 as = boost::dynamic_pointer_cast<AudioSource>(source);
1715 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1716 return boost::shared_ptr<AudioRegion>();
1718 master_sources.push_back (as);
1723 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1725 /* a final detail: this is the one and only place that we know how long missing files are */
1727 if (region->whole_file()) {
1728 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1729 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1731 sfp->set_length (region->length());
1736 if (!master_sources.empty()) {
1737 if (master_sources.size() != nchans) {
1738 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1740 region->set_master_sources (master_sources);
1748 catch (failed_constructor& err) {
1749 return boost::shared_ptr<AudioRegion>();
1753 boost::shared_ptr<MidiRegion>
1754 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1756 const XMLProperty* prop;
1757 boost::shared_ptr<Source> source;
1758 boost::shared_ptr<MidiSource> ms;
1761 if (node.name() != X_("Region")) {
1762 return boost::shared_ptr<MidiRegion>();
1765 if ((prop = node.property ("name")) == 0) {
1766 cerr << "no name for this region\n";
1770 if ((prop = node.property (X_("source-0"))) == 0) {
1771 if ((prop = node.property ("source")) == 0) {
1772 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1773 return boost::shared_ptr<MidiRegion>();
1777 PBD::ID s_id (prop->value());
1779 if ((source = source_by_id (s_id)) == 0) {
1780 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1781 return boost::shared_ptr<MidiRegion>();
1784 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1786 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1787 return boost::shared_ptr<MidiRegion>();
1790 sources.push_back (ms);
1793 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1794 /* a final detail: this is the one and only place that we know how long missing files are */
1796 if (region->whole_file()) {
1797 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1798 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1800 sfp->set_length (region->length());
1808 catch (failed_constructor& err) {
1809 return boost::shared_ptr<MidiRegion>();
1814 Session::get_sources_as_xml ()
1817 XMLNode* node = new XMLNode (X_("Sources"));
1818 Glib::Mutex::Lock lm (source_lock);
1820 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1821 node->add_child_nocopy (i->second->get_state());
1828 Session::path_from_region_name (DataType type, string name, string identifier)
1830 char buf[PATH_MAX+1];
1832 SessionDirectory sdir(get_best_session_directory_for_new_source());
1833 sys::path source_dir = ((type == DataType::AUDIO)
1834 ? sdir.sound_path() : sdir.midi_path());
1836 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1838 for (n = 0; n < 999999; ++n) {
1839 if (identifier.length()) {
1840 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1841 identifier.c_str(), n, ext.c_str());
1843 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1847 sys::path source_path = source_dir / buf;
1849 if (!sys::exists (source_path)) {
1850 return source_path.to_string();
1854 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1863 Session::load_sources (const XMLNode& node)
1866 XMLNodeConstIterator niter;
1867 boost::shared_ptr<Source> source;
1869 nlist = node.children();
1873 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1875 if ((source = XMLSourceFactory (**niter)) == 0) {
1876 error << _("Session: cannot create Source from XML description.") << endmsg;
1878 } catch (MissingSource& err) {
1879 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1880 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1887 boost::shared_ptr<Source>
1888 Session::XMLSourceFactory (const XMLNode& node)
1890 if (node.name() != "Source") {
1891 return boost::shared_ptr<Source>();
1895 /* note: do peak building in another thread when loading session state */
1896 return SourceFactory::create (*this, node, true);
1899 catch (failed_constructor& err) {
1900 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1901 return boost::shared_ptr<Source>();
1906 Session::save_template (string template_name)
1910 if (_state_of_the_state & CannotSave) {
1914 sys::path user_template_dir(user_template_directory());
1918 sys::create_directories (user_template_dir);
1920 catch(sys::filesystem_error& ex)
1922 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1923 user_template_dir.to_string(), ex.what()) << endmsg;
1927 tree.set_root (&get_template());
1929 sys::path template_file_path(user_template_dir);
1930 template_file_path /= template_name + template_suffix;
1932 if (sys::exists (template_file_path))
1934 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1935 template_file_path.to_string()) << endmsg;
1939 if (!tree.write (template_file_path.to_string())) {
1940 error << _("mix template not saved") << endmsg;
1948 Session::rename_template (string old_name, string new_name)
1950 sys::path old_path (user_template_directory());
1951 old_path /= old_name + template_suffix;
1953 sys::path new_path(user_template_directory());
1954 new_path /= new_name + template_suffix;
1956 if (sys::exists (new_path)) {
1957 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1958 new_path.to_string()) << endmsg;
1963 sys::rename (old_path, new_path);
1971 Session::delete_template (string name)
1973 sys::path path = user_template_directory();
1974 path /= name + template_suffix;
1985 Session::refresh_disk_space ()
1988 struct statfs statfsbuf;
1989 vector<space_and_path>::iterator i;
1990 Glib::Mutex::Lock lm (space_lock);
1993 /* get freespace on every FS that is part of the session path */
1995 _total_free_4k_blocks = 0;
1997 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1998 statfs ((*i).path.c_str(), &statfsbuf);
2000 scale = statfsbuf.f_bsize/4096.0;
2002 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2003 _total_free_4k_blocks += (*i).blocks;
2009 Session::get_best_session_directory_for_new_source ()
2011 vector<space_and_path>::iterator i;
2012 string result = _session_dir->root_path().to_string();
2014 /* handle common case without system calls */
2016 if (session_dirs.size() == 1) {
2020 /* OK, here's the algorithm we're following here:
2022 We want to select which directory to use for
2023 the next file source to be created. Ideally,
2024 we'd like to use a round-robin process so as to
2025 get maximum performance benefits from splitting
2026 the files across multiple disks.
2028 However, in situations without much diskspace, an
2029 RR approach may end up filling up a filesystem
2030 with new files while others still have space.
2031 Its therefore important to pay some attention to
2032 the freespace in the filesystem holding each
2033 directory as well. However, if we did that by
2034 itself, we'd keep creating new files in the file
2035 system with the most space until it was as full
2036 as all others, thus negating any performance
2037 benefits of this RAID-1 like approach.
2039 So, we use a user-configurable space threshold. If
2040 there are at least 2 filesystems with more than this
2041 much space available, we use RR selection between them.
2042 If not, then we pick the filesystem with the most space.
2044 This gets a good balance between the two
2048 refresh_disk_space ();
2050 int free_enough = 0;
2052 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2053 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2058 if (free_enough >= 2) {
2059 /* use RR selection process, ensuring that the one
2063 i = last_rr_session_dir;
2066 if (++i == session_dirs.end()) {
2067 i = session_dirs.begin();
2070 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2071 if (create_session_directory ((*i).path)) {
2073 last_rr_session_dir = i;
2078 } while (i != last_rr_session_dir);
2082 /* pick FS with the most freespace (and that
2083 seems to actually work ...)
2086 vector<space_and_path> sorted;
2087 space_and_path_ascending_cmp cmp;
2089 sorted = session_dirs;
2090 sort (sorted.begin(), sorted.end(), cmp);
2092 for (i = sorted.begin(); i != sorted.end(); ++i) {
2093 if (create_session_directory ((*i).path)) {
2095 last_rr_session_dir = i;
2105 Session::load_named_selections (const XMLNode& node)
2108 XMLNodeConstIterator niter;
2111 nlist = node.children();
2115 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2117 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2118 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2126 Session::XMLNamedSelectionFactory (const XMLNode& node)
2129 return new NamedSelection (*this, node);
2132 catch (failed_constructor& err) {
2138 Session::automation_dir () const
2140 return Glib::build_filename (_path, "automation");
2144 Session::analysis_dir () const
2146 return Glib::build_filename (_path, "analysis");
2150 Session::load_bundles (XMLNode const & node)
2152 XMLNodeList nlist = node.children();
2153 XMLNodeConstIterator niter;
2157 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2158 if ((*niter)->name() == "InputBundle") {
2159 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2160 } else if ((*niter)->name() == "OutputBundle") {
2161 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2163 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2172 Session::load_route_groups (const XMLNode& node, int version)
2174 XMLNodeList nlist = node.children();
2175 XMLNodeConstIterator niter;
2179 if (version >= 3000) {
2181 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2182 if ((*niter)->name() == "RouteGroup") {
2183 RouteGroup* rg = new RouteGroup (*this, "");
2184 add_route_group (rg);
2185 rg->set_state (**niter, version);
2189 } else if (version < 3000) {
2191 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2192 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2193 RouteGroup* rg = new RouteGroup (*this, "");
2194 add_route_group (rg);
2195 rg->set_state (**niter, version);
2204 Session::auto_save()
2206 save_state (_current_snapshot_name);
2210 state_file_filter (const string &str, void */*arg*/)
2212 return (str.length() > strlen(statefile_suffix) &&
2213 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2217 bool operator()(const string* a, const string* b) {
2223 remove_end(string* state)
2225 string statename(*state);
2227 string::size_type start,end;
2228 if ((start = statename.find_last_of ('/')) != string::npos) {
2229 statename = statename.substr (start+1);
2232 if ((end = statename.rfind(".ardour")) == string::npos) {
2233 end = statename.length();
2236 return new string(statename.substr (0, end));
2240 Session::possible_states (string path)
2242 PathScanner scanner;
2243 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2245 transform(states->begin(), states->end(), states->begin(), remove_end);
2248 sort (states->begin(), states->end(), cmp);
2254 Session::possible_states () const
2256 return possible_states(_path);
2260 Session::add_route_group (RouteGroup* g)
2262 _route_groups.push_back (g);
2263 route_group_added (g); /* EMIT SIGNAL */
2265 g->MembershipChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2266 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2272 Session::remove_route_group (RouteGroup& rg)
2274 list<RouteGroup*>::iterator i;
2276 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2277 _route_groups.erase (i);
2280 route_group_removed (); /* EMIT SIGNAL */
2286 Session::route_group_by_name (string name)
2288 list<RouteGroup *>::iterator i;
2290 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2291 if ((*i)->name() == name) {
2299 Session::start_reversible_command (const string& name)
2301 UndoTransaction* trans = new UndoTransaction();
2302 trans->set_name(name);
2307 Session::finish_reversible_command (UndoTransaction& ut)
2310 gettimeofday(&now, 0);
2311 ut.set_timestamp(now);
2316 Session::begin_reversible_command(const string& name)
2318 UndoTransaction* trans = new UndoTransaction();
2319 trans->set_name(name);
2321 if (!_current_trans.empty()) {
2322 _current_trans.top()->add_command (trans);
2324 _current_trans.push(trans);
2329 Session::commit_reversible_command(Command *cmd)
2331 assert(!_current_trans.empty());
2335 _current_trans.top()->add_command(cmd);
2338 if (_current_trans.top()->empty()) {
2339 _current_trans.pop();
2343 gettimeofday(&now, 0);
2344 _current_trans.top()->set_timestamp(now);
2346 _history.add(_current_trans.top());
2347 _current_trans.pop();
2351 accept_all_non_peak_files (const string& path, void */*arg*/)
2353 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2357 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2361 accept_all_state_files (const string& path, void */*arg*/)
2363 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2367 Session::find_all_sources (string path, set<string>& result)
2372 if (!tree.read (path)) {
2376 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2381 XMLNodeConstIterator niter;
2383 nlist = node->children();
2387 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2391 if ((prop = (*niter)->property (X_("type"))) == 0) {
2395 DataType type (prop->value());
2397 if ((prop = (*niter)->property (X_("name"))) == 0) {
2401 if (prop->value()[0] == '/') {
2402 /* external file, ignore */
2406 Glib::ustring found_path;
2410 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2411 result.insert (found_path);
2419 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2421 PathScanner scanner;
2422 vector<string*>* state_files;
2424 string this_snapshot_path;
2430 if (ripped[ripped.length()-1] == '/') {
2431 ripped = ripped.substr (0, ripped.length() - 1);
2434 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2436 if (state_files == 0) {
2441 this_snapshot_path = _path;
2442 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2443 this_snapshot_path += statefile_suffix;
2445 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2447 if (exclude_this_snapshot && **i == this_snapshot_path) {
2451 if (find_all_sources (**i, result) < 0) {
2459 struct RegionCounter {
2460 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2461 AudioSourceList::iterator iter;
2462 boost::shared_ptr<Region> region;
2465 RegionCounter() : count (0) {}
2469 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2471 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2472 return r.get_value_or (1);
2476 Session::cleanup_sources (CleanupReport& rep)
2478 // FIXME: needs adaptation to midi
2480 vector<boost::shared_ptr<Source> > dead_sources;
2481 PathScanner scanner;
2483 vector<space_and_path>::iterator i;
2484 vector<space_and_path>::iterator nexti;
2485 vector<string*>* soundfiles;
2486 vector<string> unused;
2487 set<string> all_sources;
2492 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2494 /* step 1: consider deleting all unused playlists */
2496 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2501 /* step 2: find all un-used sources */
2506 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2508 SourceMap::iterator tmp;
2513 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2517 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2518 dead_sources.push_back (i->second);
2519 i->second->drop_references ();
2525 /* build a list of all the possible sound directories for the session */
2527 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2532 SessionDirectory sdir ((*i).path);
2533 sound_path += sdir.sound_path().to_string();
2535 if (nexti != session_dirs.end()) {
2542 /* now do the same thing for the files that ended up in the sounds dir(s)
2543 but are not referenced as sources in any snapshot.
2546 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2548 if (soundfiles == 0) {
2552 /* find all sources, but don't use this snapshot because the
2553 state file on disk still references sources we may have already
2557 find_all_sources_across_snapshots (all_sources, true);
2559 /* add our current source list
2562 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2563 boost::shared_ptr<FileSource> fs;
2565 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2566 all_sources.insert (fs->path());
2570 char tmppath1[PATH_MAX+1];
2571 char tmppath2[PATH_MAX+1];
2573 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2578 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2580 if (realpath(spath.c_str(), tmppath1) == 0) {
2581 error << string_compose (_("Cannot expand path %1 (%2)"),
2582 spath, strerror (errno)) << endmsg;
2586 if (realpath((*i).c_str(), tmppath2) == 0) {
2587 error << string_compose (_("Cannot expand path %1 (%2)"),
2588 (*i), strerror (errno)) << endmsg;
2592 if (strcmp(tmppath1, tmppath2) == 0) {
2599 unused.push_back (spath);
2603 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2605 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2606 struct stat statbuf;
2608 rep.paths.push_back (*x);
2609 if (stat ((*x).c_str(), &statbuf) == 0) {
2610 rep.space += statbuf.st_size;
2615 /* don't move the file across filesystems, just
2616 stick it in the `dead_sound_dir_name' directory
2617 on whichever filesystem it was already on.
2620 if ((*x).find ("/sounds/") != string::npos) {
2622 /* old school, go up 1 level */
2624 newpath = Glib::path_get_dirname (*x); // "sounds"
2625 newpath = Glib::path_get_dirname (newpath); // "session-name"
2629 /* new school, go up 4 levels */
2631 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2632 newpath = Glib::path_get_dirname (newpath); // "session-name"
2633 newpath = Glib::path_get_dirname (newpath); // "interchange"
2634 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2638 newpath += dead_sound_dir_name;
2640 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2641 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2646 newpath += Glib::path_get_basename ((*x));
2648 if (access (newpath.c_str(), F_OK) == 0) {
2650 /* the new path already exists, try versioning */
2652 char buf[PATH_MAX+1];
2656 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2659 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2660 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2664 if (version == 999) {
2665 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2669 newpath = newpath_v;
2674 /* it doesn't exist, or we can't read it or something */
2678 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2679 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2680 (*x), newpath, strerror (errno))
2685 /* see if there an easy to find peakfile for this file, and remove it.
2688 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2689 peakpath += peakfile_suffix;
2691 if (access (peakpath.c_str(), W_OK) == 0) {
2692 if (::unlink (peakpath.c_str()) != 0) {
2693 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2694 peakpath, _path, strerror (errno))
2696 /* try to back out */
2697 rename (newpath.c_str(), _path.c_str());
2705 /* dump the history list */
2709 /* save state so we don't end up a session file
2710 referring to non-existent sources.
2716 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2722 Session::cleanup_trash_sources (CleanupReport& rep)
2724 // FIXME: needs adaptation for MIDI
2726 vector<space_and_path>::iterator i;
2727 string dead_sound_dir;
2732 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2734 dead_sound_dir = (*i).path;
2735 dead_sound_dir += dead_sound_dir_name;
2737 clear_directory (dead_sound_dir, &rep.space, &rep.paths);
2744 Session::cleanup_stubfiles ()
2746 vector<space_and_path>::iterator i;
2748 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2751 string lname = legalize_for_path (_name);
2755 /* XXX this is a hack caused by semantic conflicts
2756 between space_and_path and the SessionDirectory concept.
2759 v.push_back ((*i).path);
2760 v.push_back ("interchange");
2761 v.push_back (lname);
2762 v.push_back ("audiofiles");
2763 v.push_back (stub_dir_name);
2765 dir = Glib::build_filename (v);
2767 clear_directory (dir);
2770 v.push_back ((*i).path);
2771 v.push_back ("interchange");
2772 v.push_back (lname);
2773 v.push_back ("midifiles");
2774 v.push_back (stub_dir_name);
2776 dir = Glib::build_filename (v);
2778 clear_directory (dir);
2783 Session::set_dirty ()
2785 bool was_dirty = dirty();
2787 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2791 DirtyChanged(); /* EMIT SIGNAL */
2797 Session::set_clean ()
2799 bool was_dirty = dirty();
2801 _state_of_the_state = Clean;
2805 DirtyChanged(); /* EMIT SIGNAL */
2810 Session::set_deletion_in_progress ()
2812 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2816 Session::clear_deletion_in_progress ()
2818 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2822 Session::add_controllable (boost::shared_ptr<Controllable> c)
2824 /* this adds a controllable to the list managed by the Session.
2825 this is a subset of those managed by the Controllable class
2826 itself, and represents the only ones whose state will be saved
2827 as part of the session.
2830 Glib::Mutex::Lock lm (controllables_lock);
2831 controllables.insert (c);
2834 struct null_deleter { void operator()(void const *) const {} };
2837 Session::remove_controllable (Controllable* c)
2839 if (_state_of_the_state | Deletion) {
2843 Glib::Mutex::Lock lm (controllables_lock);
2845 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2847 if (x != controllables.end()) {
2848 controllables.erase (x);
2852 boost::shared_ptr<Controllable>
2853 Session::controllable_by_id (const PBD::ID& id)
2855 Glib::Mutex::Lock lm (controllables_lock);
2857 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2858 if ((*i)->id() == id) {
2863 return boost::shared_ptr<Controllable>();
2866 boost::shared_ptr<Controllable>
2867 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2869 boost::shared_ptr<Controllable> c;
2870 boost::shared_ptr<Route> r;
2872 switch (desc.top_level_type()) {
2873 case ControllableDescriptor::NamedRoute:
2875 std::string str = desc.top_level_name();
2876 if (str == "master") {
2878 } else if (str == "control" || str == "listen") {
2881 r = route_by_name (desc.top_level_name());
2886 case ControllableDescriptor::RemoteControlID:
2887 r = route_by_remote_id (desc.rid());
2895 switch (desc.subtype()) {
2896 case ControllableDescriptor::Gain:
2897 c = r->gain_control ();
2900 case ControllableDescriptor::Solo:
2901 c = r->solo_control();
2904 case ControllableDescriptor::Mute:
2905 c = r->mute_control();
2908 case ControllableDescriptor::Recenable:
2910 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2913 c = t->rec_enable_control ();
2918 case ControllableDescriptor::Pan:
2919 /* XXX pan control */
2922 case ControllableDescriptor::Balance:
2923 /* XXX simple pan control */
2926 case ControllableDescriptor::PluginParameter:
2928 uint32_t plugin = desc.target (0);
2929 uint32_t parameter_index = desc.target (1);
2931 /* revert to zero based counting */
2937 if (parameter_index > 0) {
2941 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
2944 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
2945 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
2950 case ControllableDescriptor::SendGain:
2952 uint32_t send = desc.target (0);
2954 /* revert to zero-based counting */
2960 boost::shared_ptr<Processor> p = r->nth_send (send);
2963 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
2964 boost::shared_ptr<Amp> a = s->amp();
2967 c = s->amp()->gain_control();
2974 /* relax and return a null pointer */
2982 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2985 Stateful::add_instant_xml (node, _path);
2988 if (write_to_config) {
2989 Config->add_instant_xml (node);
2994 Session::instant_xml (const string& node_name)
2996 return Stateful::instant_xml (node_name, _path);
3000 Session::save_history (string snapshot_name)
3008 if (snapshot_name.empty()) {
3009 snapshot_name = _current_snapshot_name;
3012 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3013 const string backup_filename = history_filename + backup_suffix;
3014 const sys::path xml_path = _session_dir->root_path() / history_filename;
3015 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3017 if (sys::exists (xml_path)) {
3020 sys::rename (xml_path, backup_path);
3022 catch (const sys::filesystem_error& err)
3024 error << _("could not backup old history file, current history not saved") << endmsg;
3029 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3033 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3035 if (!tree.write (xml_path.to_string()))
3037 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3041 sys::remove (xml_path);
3042 sys::rename (backup_path, xml_path);
3044 catch (const sys::filesystem_error& err)
3046 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3047 backup_path.to_string(), err.what()) << endmsg;
3057 Session::restore_history (string snapshot_name)
3061 if (snapshot_name.empty()) {
3062 snapshot_name = _current_snapshot_name;
3065 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3066 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3068 info << "Loading history from " << xml_path.to_string() << endmsg;
3070 if (!sys::exists (xml_path)) {
3071 info << string_compose (_("%1: no history file \"%2\" for this session."),
3072 _name, xml_path.to_string()) << endmsg;
3076 if (!tree.read (xml_path.to_string())) {
3077 error << string_compose (_("Could not understand session history file \"%1\""),
3078 xml_path.to_string()) << endmsg;
3085 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3088 UndoTransaction* ut = new UndoTransaction ();
3091 ut->set_name(t->property("name")->value());
3092 stringstream ss(t->property("tv-sec")->value());
3094 ss.str(t->property("tv-usec")->value());
3096 ut->set_timestamp(tv);
3098 for (XMLNodeConstIterator child_it = t->children().begin();
3099 child_it != t->children().end(); child_it++)
3101 XMLNode *n = *child_it;
3104 if (n->name() == "MementoCommand" ||
3105 n->name() == "MementoUndoCommand" ||
3106 n->name() == "MementoRedoCommand") {
3108 if ((c = memento_command_factory(n))) {
3112 } else if (n->name() == "DiffCommand") {
3113 PBD::ID id(n->property("midi-source")->value());
3114 boost::shared_ptr<MidiSource> midi_source =
3115 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3117 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
3119 error << _("Failed to downcast MidiSource for DiffCommand") << endmsg;
3122 } else if (n->name() == "StatefulDiffCommand") {
3123 if ((c = stateful_diff_command_factory (n))) {
3124 ut->add_command (c);
3127 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3138 Session::config_changed (std::string p, bool ours)
3144 if (p == "seamless-loop") {
3146 } else if (p == "rf-speed") {
3148 } else if (p == "auto-loop") {
3150 } else if (p == "auto-input") {
3152 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3153 /* auto-input only makes a difference if we're rolling */
3155 boost::shared_ptr<RouteList> rl = routes.reader ();
3156 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3157 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3158 if (tr && tr->record_enabled ()) {
3159 tr->monitor_input (!config.get_auto_input());
3164 } else if (p == "punch-in") {
3168 if ((location = _locations.auto_punch_location()) != 0) {
3170 if (config.get_punch_in ()) {
3171 replace_event (SessionEvent::PunchIn, location->start());
3173 remove_event (location->start(), SessionEvent::PunchIn);
3177 } else if (p == "punch-out") {
3181 if ((location = _locations.auto_punch_location()) != 0) {
3183 if (config.get_punch_out()) {
3184 replace_event (SessionEvent::PunchOut, location->end());
3186 clear_events (SessionEvent::PunchOut);
3190 } else if (p == "edit-mode") {
3192 Glib::Mutex::Lock lm (playlists->lock);
3194 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3195 (*i)->set_edit_mode (Config->get_edit_mode ());
3198 } else if (p == "use-video-sync") {
3200 waiting_for_sync_offset = config.get_use_video_sync();
3202 } else if (p == "mmc-control") {
3204 //poke_midi_thread ();
3206 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3208 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3210 } else if (p == "mmc-send-id") {
3212 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3214 } else if (p == "midi-control") {
3216 //poke_midi_thread ();
3218 } else if (p == "raid-path") {
3220 setup_raid_path (config.get_raid_path());
3222 } else if (p == "timecode-format") {
3226 } else if (p == "video-pullup") {
3230 } else if (p == "seamless-loop") {
3232 if (play_loop && transport_rolling()) {
3233 // to reset diskstreams etc
3234 request_play_loop (true);
3237 } else if (p == "rf-speed") {
3239 cumulative_rf_motion = 0;
3242 } else if (p == "click-sound") {
3244 setup_click_sounds (1);
3246 } else if (p == "click-emphasis-sound") {
3248 setup_click_sounds (-1);
3250 } else if (p == "clicking") {
3252 if (Config->get_clicking()) {
3253 if (_click_io && click_data) { // don't require emphasis data
3260 } else if (p == "send-mtc") {
3262 session_send_mtc = Config->get_send_mtc();
3263 if (session_send_mtc) {
3264 /* mark us ready to send */
3265 next_quarter_frame_to_send = 0;
3268 } else if (p == "send-mmc") {
3270 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3272 } else if (p == "midi-feedback") {
3274 session_midi_feedback = Config->get_midi_feedback();
3276 } else if (p == "jack-time-master") {
3278 engine().reset_timebase ();
3280 } else if (p == "native-file-header-format") {
3282 if (!first_file_header_format_reset) {
3283 reset_native_file_format ();
3286 first_file_header_format_reset = false;
3288 } else if (p == "native-file-data-format") {
3290 if (!first_file_data_format_reset) {
3291 reset_native_file_format ();
3294 first_file_data_format_reset = false;
3296 } else if (p == "external-sync") {
3297 if (!config.get_external_sync()) {
3298 drop_sync_source ();
3300 switch_to_sync_source (config.get_sync_source());
3302 } else if (p == "remote-model") {
3303 set_remote_control_ids ();
3304 } else if (p == "denormal-model") {
3306 } else if (p == "history-depth") {
3307 set_history_depth (Config->get_history_depth());
3308 } else if (p == "sync-all-route-ordering") {
3309 sync_order_keys ("session");
3310 } else if (p == "initial-program-change") {
3312 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3315 buf[0] = MIDI::program; // channel zero by default
3316 buf[1] = (Config->get_initial_program_change() & 0x7f);
3318 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3320 } else if (p == "solo-mute-override") {
3321 // catch_up_on_solo_mute_override ();
3322 } else if (p == "listen-position") {
3323 listen_position_changed ();
3324 } else if (p == "solo-control-is-listen-control") {
3325 solo_control_mode_changed ();
3333 Session::set_history_depth (uint32_t d)
3335 _history.set_depth (d);
3339 Session::load_diskstreams_2X (XMLNode const & node, int)
3342 XMLNodeConstIterator citer;
3344 clist = node.children();
3346 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3349 /* diskstreams added automatically by DiskstreamCreated handler */
3350 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3351 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3352 _diskstreams_2X.push_back (dsp);
3354 error << _("Session: unknown diskstream type in XML") << endmsg;
3358 catch (failed_constructor& err) {
3359 error << _("Session: could not load diskstream via XML state") << endmsg;
3367 /** Connect things to the MMC object */
3369 Session::setup_midi_machine_control ()
3371 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3373 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3374 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3375 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3376 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3377 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3378 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3379 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3380 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3381 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3382 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3383 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3384 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3385 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3387 /* also handle MIDI SPP because its so common */
3389 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3390 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3391 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));