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 */
49 #include <sys/param.h>
50 #include <sys/mount.h>
54 #include <glibmm/thread.h>
56 #include "midi++/mmc.h"
57 #include "midi++/port.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"
69 #include "ardour/amp.h"
70 #include "ardour/audio_diskstream.h"
71 #include "ardour/audio_track.h"
72 #include "ardour/audioengine.h"
73 #include "ardour/audiofilesource.h"
74 #include "ardour/audioplaylist.h"
75 #include "ardour/audioregion.h"
76 #include "ardour/auditioner.h"
77 #include "ardour/buffer.h"
78 #include "ardour/butler.h"
79 #include "ardour/configuration.h"
80 #include "ardour/control_protocol_manager.h"
81 #include "ardour/crossfade.h"
82 #include "ardour/cycle_timer.h"
83 #include "ardour/directory_names.h"
84 #include "ardour/filename_extensions.h"
85 #include "ardour/io_processor.h"
86 #include "ardour/location.h"
87 #include "ardour/midi_diskstream.h"
88 #include "ardour/midi_patch_manager.h"
89 #include "ardour/midi_playlist.h"
90 #include "ardour/midi_region.h"
91 #include "ardour/midi_source.h"
92 #include "ardour/midi_track.h"
93 #include "ardour/named_selection.h"
94 #include "ardour/processor.h"
95 #include "ardour/region_factory.h"
96 #include "ardour/route_group.h"
97 #include "ardour/send.h"
98 #include "ardour/session.h"
99 #include "ardour/session_directory.h"
100 #include "ardour/session_metadata.h"
101 #include "ardour/session_state_utils.h"
102 #include "ardour/session_playlists.h"
103 #include "ardour/session_utils.h"
104 #include "ardour/silentfilesource.h"
105 #include "ardour/slave.h"
106 #include "ardour/smf_source.h"
107 #include "ardour/sndfile_helpers.h"
108 #include "ardour/sndfilesource.h"
109 #include "ardour/source_factory.h"
110 #include "ardour/template_utils.h"
111 #include "ardour/tempo.h"
112 #include "ardour/ticker.h"
113 #include "ardour/user_bundle.h"
114 #include "ardour/utils.h"
115 #include "ardour/utils.h"
116 #include "ardour/version.h"
117 #include "ardour/playlist_factory.h"
119 #include "control_protocol/control_protocol.h"
125 using namespace ARDOUR;
129 Session::first_stage_init (string fullpath, string snapshot_name)
131 if (fullpath.length() == 0) {
133 throw failed_constructor();
136 char buf[PATH_MAX+1];
137 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
138 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
140 throw failed_constructor();
145 if (_path[_path.length()-1] != '/') {
149 if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
155 /* these two are just provisional settings. set_state()
156 will likely override them.
159 _name = _current_snapshot_name = snapshot_name;
161 set_history_depth (Config->get_history_depth());
163 _current_frame_rate = _engine.frame_rate ();
164 _nominal_frame_rate = _current_frame_rate;
165 _base_frame_rate = _current_frame_rate;
167 _tempo_map = new TempoMap (_current_frame_rate);
168 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
171 _non_soloed_outs_muted = false;
173 g_atomic_int_set (&processing_prohibited, 0);
174 _transport_speed = 0;
175 _last_transport_speed = 0;
176 _target_transport_speed = 0;
177 auto_play_legal = false;
178 transport_sub_state = 0;
179 _transport_frame = 0;
180 _requested_return_frame = -1;
181 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
182 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
183 g_atomic_int_set (&_record_status, Disabled);
184 loop_changing = false;
187 _last_roll_location = 0;
188 _last_record_location = 0;
189 pending_locate_frame = 0;
190 pending_locate_roll = false;
191 pending_locate_flush = false;
192 state_was_pending = false;
194 outbound_mtc_timecode_frame = 0;
195 next_quarter_frame_to_send = -1;
196 current_block_size = 0;
197 solo_update_disabled = false;
198 _have_captured = false;
199 _worst_output_latency = 0;
200 _worst_input_latency = 0;
201 _worst_track_latency = 0;
202 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
203 _was_seamless = Config->get_seamless_loop ();
205 session_send_mmc = false;
206 session_send_mtc = false;
207 g_atomic_int_set (&_playback_load, 100);
208 g_atomic_int_set (&_capture_load, 100);
209 g_atomic_int_set (&_playback_load_min, 100);
210 g_atomic_int_set (&_capture_load_min, 100);
213 _gain_automation_buffer = 0;
214 _pan_automation_buffer = 0;
216 pending_abort = false;
217 destructive_index = 0;
218 first_file_data_format_reset = true;
219 first_file_header_format_reset = true;
220 post_export_sync = false;
223 AudioDiskstream::allocate_working_buffers();
225 /* default short fade = 15ms */
227 Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
228 SndFileSource::setup_standard_crossfades (*this, frame_rate());
230 last_mmc_step.tv_sec = 0;
231 last_mmc_step.tv_usec = 0;
234 /* click sounds are unset by default, which causes us to internal
235 waveforms for clicks.
239 click_emphasis_length = 0;
242 process_function = &Session::process_with_events;
244 if (config.get_use_video_sync()) {
245 waiting_for_sync_offset = true;
247 waiting_for_sync_offset = false;
250 last_timecode_when = 0;
251 _timecode_offset = 0;
252 _timecode_offset_negative = true;
253 last_timecode_valid = false;
257 last_rr_session_dir = session_dirs.begin();
258 refresh_disk_space ();
260 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
264 average_slave_delta = 1800; // !!! why 1800 ????
265 have_first_delta_accumulator = false;
266 delta_accumulator_cnt = 0;
267 _slave_state = Stopped;
269 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
271 /* These are all static "per-class" signals */
273 RegionFactory::CheckNewRegion.connect_same_thread (*this, boost::bind (&Session::add_region, this, _1));
274 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
275 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
276 Processor::ProcessorCreated.connect_same_thread (*this, boost::bind (&Session::add_processor, this, _1));
277 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
278 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
279 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
281 /* stop IO objects from doing stuff until we're ready for them */
283 Delivery::disable_panners ();
284 IO::disable_connecting ();
288 Session::second_stage_init ()
290 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
293 if (load_state (_current_snapshot_name)) {
296 remove_empty_sounds ();
299 if (_butler->start_thread()) {
303 if (start_midi_thread ()) {
307 // set_state() will call setup_raid_path(), but if it's a new session we need
308 // to call setup_raid_path() here.
311 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
315 setup_raid_path(_path);
318 /* we can't save till after ::when_engine_running() is called,
319 because otherwise we save state with no connections made.
320 therefore, we reset _state_of_the_state because ::set_state()
321 will have cleared it.
323 we also have to include Loading so that any events that get
324 generated between here and the end of ::when_engine_running()
325 will be processed directly rather than queued.
328 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
331 _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
332 _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
333 setup_click_sounds (0);
334 setup_midi_control ();
336 /* Pay attention ... */
338 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
339 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
342 when_engine_running ();
345 /* handle this one in a different way than all others, so that its clear what happened */
347 catch (AudioEngine::PortRegistrationFailure& err) {
348 error << err.what() << endmsg;
356 BootMessage (_("Reset Remote Controls"));
358 send_full_time_code (0);
359 _engine.transport_locate (0);
360 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
361 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
363 MidiClockTicker::instance().set_session (this);
364 MIDI::Name::MidiPatchManager::instance().set_session (this);
366 /* initial program change will be delivered later; see ::config_changed() */
368 BootMessage (_("Reset Control Protocols"));
370 ControlProtocolManager::instance().set_session (this);
372 config.set_end_marker_is_free (_is_new);
374 _state_of_the_state = Clean;
376 DirtyChanged (); /* EMIT SIGNAL */
378 if (state_was_pending) {
379 save_state (_current_snapshot_name);
380 remove_pending_capture_state ();
381 state_was_pending = false;
384 BootMessage (_("Session loading complete"));
390 Session::raid_path () const
392 SearchPath raid_search_path;
394 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
395 raid_search_path += sys::path((*i).path);
398 return raid_search_path.to_string ();
402 Session::setup_raid_path (string path)
411 session_dirs.clear ();
413 SearchPath search_path(path);
414 SearchPath sound_search_path;
415 SearchPath midi_search_path;
417 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
418 sp.path = (*i).to_string ();
419 sp.blocks = 0; // not needed
420 session_dirs.push_back (sp);
422 SessionDirectory sdir(sp.path);
424 sound_search_path += sdir.sound_path ();
425 midi_search_path += sdir.midi_path ();
428 // set the search path for each data type
429 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
430 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
432 // reset the round-robin soundfile path thingie
433 last_rr_session_dir = session_dirs.begin();
437 Session::path_is_within_session (const std::string& path)
439 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
440 if (path.find ((*i).path) == 0) {
448 Session::ensure_subdirs ()
452 dir = session_directory().peak_path().to_string();
454 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
455 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
459 dir = session_directory().sound_path().to_string();
461 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
462 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
466 dir = session_directory().midi_path().to_string();
468 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
469 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
473 dir = session_directory().dead_sound_path().to_string();
475 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
476 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
480 dir = session_directory().export_path().to_string();
482 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
483 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
487 dir = analysis_dir ();
489 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
490 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
498 Session::create (const string& mix_template, nframes_t initial_length, BusProfile* bus_profile)
501 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
502 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
506 if (ensure_subdirs ()) {
510 if (!mix_template.empty()) {
511 std::string in_path = mix_template;
513 ifstream in(in_path.c_str());
516 string out_path = _path;
518 out_path += statefile_suffix;
520 ofstream out(out_path.c_str());
527 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
533 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
540 /* Instantiate metadata */
542 _metadata = new SessionMetadata ();
544 /* set initial start + end point */
546 start_location->set_end (0);
547 _locations.add (start_location);
549 end_location->set_end (initial_length);
550 _locations.add (end_location);
552 _state_of_the_state = Clean;
554 /* set up Master Out and Control Out if necessary */
560 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
562 if (bus_profile->master_out_channels) {
563 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
564 boost_debug_shared_ptr_mark_interesting (rt, "Route");
565 boost::shared_ptr<Route> r (rt);
566 r->input()->ensure_io (count, false, this);
567 r->output()->ensure_io (count, false, this);
568 r->set_remote_control_id (control_id++);
572 if (Config->get_use_monitor_bus()) {
573 Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, 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);
584 /* prohibit auto-connect to master, because there isn't one */
585 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
589 add_routes (rl, false);
592 /* this allows the user to override settings with an environment variable.
595 if (no_auto_connect()) {
596 bus_profile->input_ac = AutoConnectOption (0);
597 bus_profile->output_ac = AutoConnectOption (0);
600 Config->set_input_auto_connect (bus_profile->input_ac);
601 Config->set_output_auto_connect (bus_profile->output_ac);
611 Session::load_diskstreams (const XMLNode& node)
614 XMLNodeConstIterator citer;
616 clist = node.children();
618 for (citer = clist.begin(); citer != clist.end(); ++citer) {
621 /* diskstreams added automatically by DiskstreamCreated handler */
622 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
623 AudioDiskstream* dsp (new AudioDiskstream (*this, **citer));
624 boost::shared_ptr<AudioDiskstream> dstream (dsp);
625 add_diskstream (dstream);
626 } else if ((*citer)->name() == "MidiDiskstream") {
627 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
628 add_diskstream (dstream);
630 error << _("Session: unknown diskstream type in XML") << endmsg;
634 catch (failed_constructor& err) {
635 error << _("Session: could not load diskstream via XML state") << endmsg;
644 Session::maybe_write_autosave()
646 if (dirty() && record_status() != Recording) {
647 save_state("", true);
652 Session::remove_pending_capture_state ()
654 sys::path pending_state_file_path(_session_dir->root_path());
656 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
660 sys::remove (pending_state_file_path);
662 catch(sys::filesystem_error& ex)
664 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
665 pending_state_file_path.to_string(), ex.what()) << endmsg;
669 /** Rename a state file.
670 * @param snapshot_name Snapshot name.
673 Session::rename_state (string old_name, string new_name)
675 if (old_name == _current_snapshot_name || old_name == _name) {
676 /* refuse to rename the current snapshot or the "main" one */
680 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
681 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
683 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
684 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
688 sys::rename (old_xml_path, new_xml_path);
690 catch (const sys::filesystem_error& err)
692 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
693 old_name, new_name, err.what()) << endmsg;
697 /** Remove a state file.
698 * @param snapshot_name Snapshot name.
701 Session::remove_state (string snapshot_name)
703 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
704 // refuse to remove the current snapshot or the "main" one
708 sys::path xml_path(_session_dir->root_path());
710 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
712 if (!create_backup_file (xml_path)) {
713 // don't remove it if a backup can't be made
714 // create_backup_file will log the error.
719 sys::remove (xml_path);
723 Session::save_state (string snapshot_name, bool pending)
726 sys::path xml_path(_session_dir->root_path());
728 if (!_writable || (_state_of_the_state & CannotSave)) {
732 if (!_engine.connected ()) {
733 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
739 /* tell sources we're saving first, in case they write out to a new file
740 * which should be saved with the state rather than the old one */
741 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
742 i->second->session_saved();
744 tree.set_root (&get_state());
746 if (snapshot_name.empty()) {
747 snapshot_name = _current_snapshot_name;
752 /* proper save: use statefile_suffix (.ardour in English) */
754 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
756 /* make a backup copy of the old file */
758 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
759 // create_backup_file will log the error
765 /* pending save: use pending_suffix (.pending in English) */
766 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
769 sys::path tmp_path(_session_dir->root_path());
771 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
773 // cerr << "actually writing state to " << xml_path.to_string() << endl;
775 if (!tree.write (tmp_path.to_string())) {
776 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
777 sys::remove (tmp_path);
782 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
783 error << string_compose (_("could not rename temporary session file %1 to %2"),
784 tmp_path.to_string(), xml_path.to_string()) << endmsg;
785 sys::remove (tmp_path);
792 save_history (snapshot_name);
794 bool was_dirty = dirty();
796 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
800 DirtyChanged (); /* EMIT SIGNAL */
803 StateSaved (snapshot_name); /* EMIT SIGNAL */
810 Session::restore_state (string snapshot_name)
812 if (load_state (snapshot_name) == 0) {
813 set_state (*state_tree->root(), Stateful::loading_state_version);
820 Session::load_state (string snapshot_name)
825 state_was_pending = false;
827 /* check for leftover pending state from a crashed capture attempt */
829 sys::path xmlpath(_session_dir->root_path());
830 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
832 if (sys::exists (xmlpath)) {
834 /* there is pending state from a crashed capture attempt */
836 if (*AskAboutPendingState()) {
837 state_was_pending = true;
841 if (!state_was_pending) {
842 xmlpath = _session_dir->root_path();
843 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
846 if (!sys::exists (xmlpath)) {
847 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
851 state_tree = new XMLTree;
855 /* writable() really reflects the whole folder, but if for any
856 reason the session state file can't be written to, still
860 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
864 if (!state_tree->read (xmlpath.to_string())) {
865 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
871 XMLNode& root (*state_tree->root());
873 if (root.name() != X_("Session")) {
874 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
880 const XMLProperty* prop;
882 if ((prop = root.property ("version")) == 0) {
883 /* no version implies very old version of Ardour */
884 Stateful::loading_state_version = 1000;
890 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
891 Stateful::loading_state_version = (major * 1000) + minor;
894 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
896 sys::path backup_path(_session_dir->root_path());
898 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
900 // only create a backup once
901 if (sys::exists (backup_path)) {
905 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
906 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
911 sys::copy_file (xmlpath, backup_path);
913 catch(sys::filesystem_error& ex)
915 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
916 xmlpath.to_string(), ex.what())
926 Session::load_options (const XMLNode& node)
928 LocaleGuard lg (X_("POSIX"));
929 config.set_variables (node);
940 Session::get_template()
942 /* if we don't disable rec-enable, diskstreams
943 will believe they need to store their capture
944 sources in their state node.
947 disable_record (false);
953 Session::state(bool full_state)
955 XMLNode* node = new XMLNode("Session");
958 // store libardour version, just in case
960 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
961 node->add_property("version", string(buf));
963 /* store configuration settings */
967 node->add_property ("name", _name);
968 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
969 node->add_property ("sample-rate", buf);
971 if (session_dirs.size() > 1) {
975 vector<space_and_path>::iterator i = session_dirs.begin();
976 vector<space_and_path>::iterator next;
978 ++i; /* skip the first one */
982 while (i != session_dirs.end()) {
986 if (next != session_dirs.end()) {
996 child = node->add_child ("Path");
997 child->add_content (p);
1001 /* save the ID counter */
1003 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1004 node->add_property ("id-counter", buf);
1006 /* various options */
1008 node->add_child_nocopy (config.get_variables ());
1010 node->add_child_nocopy (_metadata->get_state());
1012 child = node->add_child ("Sources");
1015 Glib::Mutex::Lock sl (source_lock);
1017 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1019 /* Don't save information about non-destructive file sources that are empty */
1020 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
1022 boost::shared_ptr<AudioFileSource> fs;
1023 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
1024 if (!fs->destructive()) {
1025 if (fs->length(fs->timeline_position()) == 0) {
1031 child->add_child_nocopy (siter->second->get_state());
1035 child = node->add_child ("Regions");
1038 Glib::Mutex::Lock rl (region_lock);
1039 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1040 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1041 boost::shared_ptr<Region> r = i->second;
1042 /* only store regions not attached to playlists */
1043 if (r->playlist() == 0) {
1044 child->add_child_nocopy (r->state (true));
1049 child = node->add_child ("DiskStreams");
1052 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1053 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1054 if (!(*i)->hidden()) {
1055 child->add_child_nocopy ((*i)->get_state());
1061 node->add_child_nocopy (_locations.get_state());
1063 // for a template, just create a new Locations, populate it
1064 // with the default start and end, and get the state for that.
1066 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1067 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1070 end->set_end(compute_initial_length());
1072 node->add_child_nocopy (loc.get_state());
1075 child = node->add_child ("Bundles");
1077 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1078 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1079 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1081 child->add_child_nocopy (b->get_state());
1086 child = node->add_child ("Routes");
1088 boost::shared_ptr<RouteList> r = routes.reader ();
1090 RoutePublicOrderSorter cmp;
1091 RouteList public_order (*r);
1092 public_order.sort (cmp);
1094 /* the sort should have put control outs first */
1097 assert (_monitor_out == public_order.front());
1100 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1101 if (!(*i)->is_hidden()) {
1103 child->add_child_nocopy ((*i)->get_state());
1105 child->add_child_nocopy ((*i)->get_template());
1111 playlists->add_state (node, full_state);
1113 child = node->add_child ("RouteGroups");
1114 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1115 child->add_child_nocopy ((*i)->get_state());
1119 child = node->add_child ("Click");
1120 child->add_child_nocopy (_click_io->state (full_state));
1124 child = node->add_child ("NamedSelections");
1125 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1127 child->add_child_nocopy ((*i)->get_state());
1132 node->add_child_nocopy (_tempo_map->get_state());
1134 node->add_child_nocopy (get_control_protocol_state());
1137 node->add_child_copy (*_extra_xml);
1144 Session::get_control_protocol_state ()
1146 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1147 return cpm.get_state();
1151 Session::set_state (const XMLNode& node, int version)
1155 const XMLProperty* prop;
1158 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1160 if (node.name() != X_("Session")){
1161 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1165 if ((prop = node.property ("version")) != 0) {
1166 version = atoi (prop->value ()) * 1000;
1169 if ((prop = node.property ("name")) != 0) {
1170 _name = prop->value ();
1173 if ((prop = node.property (X_("sample-rate"))) != 0) {
1175 _nominal_frame_rate = atoi (prop->value());
1177 if (_nominal_frame_rate != _current_frame_rate) {
1178 if (*AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1184 setup_raid_path(_session_dir->root_path().to_string());
1186 if ((prop = node.property (X_("id-counter"))) != 0) {
1188 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1189 ID::init_counter (x);
1191 /* old sessions used a timebased counter, so fake
1192 the startup ID counter based on a standard
1197 ID::init_counter (now);
1201 IO::disable_connecting ();
1203 /* Object loading order:
1208 MIDI Control // relies on data from Options/Config
1222 if ((child = find_named_node (node, "Extra")) != 0) {
1223 _extra_xml = new XMLNode (*child);
1226 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1227 load_options (*child);
1228 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1229 load_options (*child);
1231 error << _("Session: XML state has no options section") << endmsg;
1234 if (use_config_midi_ports ()) {
1237 if (version >= 3000) {
1238 if ((child = find_named_node (node, "Metadata")) == 0) {
1239 warning << _("Session: XML state has no metadata section") << endmsg;
1240 } else if (_metadata->set_state (*child, version)) {
1245 if ((child = find_named_node (node, "Locations")) == 0) {
1246 error << _("Session: XML state has no locations section") << endmsg;
1248 } else if (_locations.set_state (*child, version)) {
1254 if ((location = _locations.auto_loop_location()) != 0) {
1255 set_auto_loop_location (location);
1258 if ((location = _locations.auto_punch_location()) != 0) {
1259 set_auto_punch_location (location);
1262 if ((location = _locations.end_location()) == 0) {
1263 _locations.add (end_location);
1265 delete end_location;
1266 end_location = location;
1269 if ((location = _locations.start_location()) == 0) {
1270 _locations.add (start_location);
1272 delete start_location;
1273 start_location = location;
1276 AudioFileSource::set_header_position_offset (start_location->start());
1278 if ((child = find_named_node (node, "Sources")) == 0) {
1279 error << _("Session: XML state has no sources section") << endmsg;
1281 } else if (load_sources (*child)) {
1285 if ((child = find_named_node (node, "Regions")) == 0) {
1286 error << _("Session: XML state has no Regions section") << endmsg;
1288 } else if (load_regions (*child)) {
1292 if ((child = find_named_node (node, "Playlists")) == 0) {
1293 error << _("Session: XML state has no playlists section") << endmsg;
1295 } else if (playlists->load (*this, *child)) {
1299 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1301 } else if (playlists->load_unused (*this, *child)) {
1305 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1306 if (load_named_selections (*child)) {
1311 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1312 error << _("Session: XML state has no diskstreams section") << endmsg;
1314 } else if (load_diskstreams (*child)) {
1318 if (version >= 3000) {
1319 if ((child = find_named_node (node, "Bundles")) == 0) {
1320 warning << _("Session: XML state has no bundles section") << endmsg;
1323 /* We can't load Bundles yet as they need to be able
1324 to convert from port names to Port objects, which can't happen until
1326 _bundle_xml_node = new XMLNode (*child);
1330 if ((child = find_named_node (node, "TempoMap")) == 0) {
1331 error << _("Session: XML state has no Tempo Map section") << endmsg;
1333 } else if (_tempo_map->set_state (*child, version)) {
1337 if ((child = find_named_node (node, "Routes")) == 0) {
1338 error << _("Session: XML state has no routes section") << endmsg;
1340 } else if (load_routes (*child, version)) {
1344 if (version >= 3000) {
1346 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1347 error << _("Session: XML state has no route groups section") << endmsg;
1349 } else if (load_route_groups (*child, version)) {
1353 } else if (version < 3000) {
1355 if ((child = find_named_node (node, "EditGroups")) == 0) {
1356 error << _("Session: XML state has no edit groups section") << endmsg;
1358 } else if (load_route_groups (*child, version)) {
1362 if ((child = find_named_node (node, "MixGroups")) == 0) {
1363 error << _("Session: XML state has no mix groups section") << endmsg;
1365 } else if (load_route_groups (*child, version)) {
1370 if ((child = find_named_node (node, "Click")) == 0) {
1371 warning << _("Session: XML state has no click section") << endmsg;
1372 } else if (_click_io) {
1373 _click_io->set_state (*child, version);
1376 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1377 ControlProtocolManager::instance().set_protocol_states (*child);
1380 /* here beginneth the second phase ... */
1382 StateReady (); /* EMIT SIGNAL */
1391 Session::load_routes (const XMLNode& node, int version)
1394 XMLNodeConstIterator niter;
1395 RouteList new_routes;
1397 nlist = node.children();
1401 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1403 boost::shared_ptr<Route> route (XMLRouteFactory (**niter, version));
1406 error << _("Session: cannot create Route from XML description.") << endmsg;
1410 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1412 new_routes.push_back (route);
1415 add_routes (new_routes, false);
1420 boost::shared_ptr<Route>
1421 Session::XMLRouteFactory (const XMLNode& node, int version)
1423 if (node.name() != "Route") {
1424 return boost::shared_ptr<Route> ((Route*) 0);
1427 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1429 DataType type = DataType::AUDIO;
1430 const XMLProperty* prop = node.property("default-type");
1431 boost::shared_ptr<Route> ret;
1434 type = DataType(prop->value());
1437 assert(type != DataType::NIL);
1439 if (has_diskstream) {
1440 if (type == DataType::AUDIO) {
1441 AudioTrack* at = new AudioTrack (*this, node, version);
1442 boost_debug_shared_ptr_mark_interesting (at, "Track");
1446 ret.reset (new MidiTrack (*this, node, version));
1449 Route* rt = new Route (*this, node);
1450 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1458 Session::load_regions (const XMLNode& node)
1461 XMLNodeConstIterator niter;
1462 boost::shared_ptr<Region> region;
1464 nlist = node.children();
1468 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1469 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1470 error << _("Session: cannot create Region from XML description.");
1471 const XMLProperty *name = (**niter).property("name");
1474 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1484 boost::shared_ptr<Region>
1485 Session::XMLRegionFactory (const XMLNode& node, bool full)
1487 const XMLProperty* type = node.property("type");
1491 if ( !type || type->value() == "audio" ) {
1493 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1495 } else if (type->value() == "midi") {
1497 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1501 } catch (failed_constructor& err) {
1502 return boost::shared_ptr<Region> ();
1505 return boost::shared_ptr<Region> ();
1508 boost::shared_ptr<AudioRegion>
1509 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1511 const XMLProperty* prop;
1512 boost::shared_ptr<Source> source;
1513 boost::shared_ptr<AudioSource> as;
1515 SourceList master_sources;
1516 uint32_t nchans = 1;
1519 if (node.name() != X_("Region")) {
1520 return boost::shared_ptr<AudioRegion>();
1523 if ((prop = node.property (X_("channels"))) != 0) {
1524 nchans = atoi (prop->value().c_str());
1527 if ((prop = node.property ("name")) == 0) {
1528 cerr << "no name for this region\n";
1532 if ((prop = node.property (X_("source-0"))) == 0) {
1533 if ((prop = node.property ("source")) == 0) {
1534 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1535 return boost::shared_ptr<AudioRegion>();
1539 PBD::ID s_id (prop->value());
1541 if ((source = source_by_id (s_id)) == 0) {
1542 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1543 return boost::shared_ptr<AudioRegion>();
1546 as = boost::dynamic_pointer_cast<AudioSource>(source);
1548 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1549 return boost::shared_ptr<AudioRegion>();
1552 sources.push_back (as);
1554 /* pickup other channels */
1556 for (uint32_t n=1; n < nchans; ++n) {
1557 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1558 if ((prop = node.property (buf)) != 0) {
1560 PBD::ID id2 (prop->value());
1562 if ((source = source_by_id (id2)) == 0) {
1563 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1564 return boost::shared_ptr<AudioRegion>();
1567 as = boost::dynamic_pointer_cast<AudioSource>(source);
1569 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1570 return boost::shared_ptr<AudioRegion>();
1572 sources.push_back (as);
1576 for (uint32_t n = 0; n < nchans; ++n) {
1577 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1578 if ((prop = node.property (buf)) != 0) {
1580 PBD::ID id2 (prop->value());
1582 if ((source = source_by_id (id2)) == 0) {
1583 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1584 return boost::shared_ptr<AudioRegion>();
1587 as = boost::dynamic_pointer_cast<AudioSource>(source);
1589 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1590 return boost::shared_ptr<AudioRegion>();
1592 master_sources.push_back (as);
1597 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1599 /* a final detail: this is the one and only place that we know how long missing files are */
1601 if (region->whole_file()) {
1602 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1603 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1605 sfp->set_length (region->length());
1610 if (!master_sources.empty()) {
1611 if (master_sources.size() != nchans) {
1612 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1614 region->set_master_sources (master_sources);
1622 catch (failed_constructor& err) {
1623 return boost::shared_ptr<AudioRegion>();
1627 boost::shared_ptr<MidiRegion>
1628 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1630 const XMLProperty* prop;
1631 boost::shared_ptr<Source> source;
1632 boost::shared_ptr<MidiSource> ms;
1634 uint32_t nchans = 1;
1636 if (node.name() != X_("Region")) {
1637 return boost::shared_ptr<MidiRegion>();
1640 if ((prop = node.property (X_("channels"))) != 0) {
1641 nchans = atoi (prop->value().c_str());
1644 if ((prop = node.property ("name")) == 0) {
1645 cerr << "no name for this region\n";
1649 // Multiple midi channels? that's just crazy talk
1650 assert(nchans == 1);
1652 if ((prop = node.property (X_("source-0"))) == 0) {
1653 if ((prop = node.property ("source")) == 0) {
1654 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1655 return boost::shared_ptr<MidiRegion>();
1659 PBD::ID s_id (prop->value());
1661 if ((source = source_by_id (s_id)) == 0) {
1662 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1663 return boost::shared_ptr<MidiRegion>();
1666 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1668 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1669 return boost::shared_ptr<MidiRegion>();
1672 sources.push_back (ms);
1675 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1676 /* a final detail: this is the one and only place that we know how long missing files are */
1678 if (region->whole_file()) {
1679 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1680 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1682 sfp->set_length (region->length());
1690 catch (failed_constructor& err) {
1691 return boost::shared_ptr<MidiRegion>();
1696 Session::get_sources_as_xml ()
1699 XMLNode* node = new XMLNode (X_("Sources"));
1700 Glib::Mutex::Lock lm (source_lock);
1702 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1703 node->add_child_nocopy (i->second->get_state());
1710 Session::path_from_region_name (DataType type, string name, string identifier)
1712 char buf[PATH_MAX+1];
1714 SessionDirectory sdir(get_best_session_directory_for_new_source());
1715 sys::path source_dir = ((type == DataType::AUDIO)
1716 ? sdir.sound_path() : sdir.midi_path());
1718 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1720 for (n = 0; n < 999999; ++n) {
1721 if (identifier.length()) {
1722 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1723 identifier.c_str(), n, ext.c_str());
1725 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1729 sys::path source_path = source_dir / buf;
1731 if (!sys::exists (source_path)) {
1732 return source_path.to_string();
1736 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1745 Session::load_sources (const XMLNode& node)
1748 XMLNodeConstIterator niter;
1749 boost::shared_ptr<Source> source;
1751 nlist = node.children();
1755 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1757 if ((source = XMLSourceFactory (**niter)) == 0) {
1758 error << _("Session: cannot create Source from XML description.") << endmsg;
1760 } catch (MissingSource& err) {
1761 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1762 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1769 boost::shared_ptr<Source>
1770 Session::XMLSourceFactory (const XMLNode& node)
1772 if (node.name() != "Source") {
1773 return boost::shared_ptr<Source>();
1777 /* note: do peak building in another thread when loading session state */
1778 return SourceFactory::create (*this, node, true);
1781 catch (failed_constructor& err) {
1782 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1783 return boost::shared_ptr<Source>();
1788 Session::save_template (string template_name)
1792 if (_state_of_the_state & CannotSave) {
1796 sys::path user_template_dir(user_template_directory());
1800 sys::create_directories (user_template_dir);
1802 catch(sys::filesystem_error& ex)
1804 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1805 user_template_dir.to_string(), ex.what()) << endmsg;
1809 tree.set_root (&get_template());
1811 sys::path template_file_path(user_template_dir);
1812 template_file_path /= template_name + template_suffix;
1814 if (sys::exists (template_file_path))
1816 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1817 template_file_path.to_string()) << endmsg;
1821 if (!tree.write (template_file_path.to_string())) {
1822 error << _("mix template not saved") << endmsg;
1830 Session::rename_template (string old_name, string new_name)
1832 sys::path old_path (user_template_directory());
1833 old_path /= old_name + template_suffix;
1835 sys::path new_path(user_template_directory());
1836 new_path /= new_name + template_suffix;
1838 if (sys::exists (new_path)) {
1839 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1840 new_path.to_string()) << endmsg;
1845 sys::rename (old_path, new_path);
1853 Session::delete_template (string name)
1855 sys::path path = user_template_directory();
1856 path /= name + template_suffix;
1867 Session::refresh_disk_space ()
1870 struct statfs statfsbuf;
1871 vector<space_and_path>::iterator i;
1872 Glib::Mutex::Lock lm (space_lock);
1875 /* get freespace on every FS that is part of the session path */
1877 _total_free_4k_blocks = 0;
1879 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1880 statfs ((*i).path.c_str(), &statfsbuf);
1882 scale = statfsbuf.f_bsize/4096.0;
1884 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1885 _total_free_4k_blocks += (*i).blocks;
1891 Session::get_best_session_directory_for_new_source ()
1893 vector<space_and_path>::iterator i;
1894 string result = _session_dir->root_path().to_string();
1896 /* handle common case without system calls */
1898 if (session_dirs.size() == 1) {
1902 /* OK, here's the algorithm we're following here:
1904 We want to select which directory to use for
1905 the next file source to be created. Ideally,
1906 we'd like to use a round-robin process so as to
1907 get maximum performance benefits from splitting
1908 the files across multiple disks.
1910 However, in situations without much diskspace, an
1911 RR approach may end up filling up a filesystem
1912 with new files while others still have space.
1913 Its therefore important to pay some attention to
1914 the freespace in the filesystem holding each
1915 directory as well. However, if we did that by
1916 itself, we'd keep creating new files in the file
1917 system with the most space until it was as full
1918 as all others, thus negating any performance
1919 benefits of this RAID-1 like approach.
1921 So, we use a user-configurable space threshold. If
1922 there are at least 2 filesystems with more than this
1923 much space available, we use RR selection between them.
1924 If not, then we pick the filesystem with the most space.
1926 This gets a good balance between the two
1930 refresh_disk_space ();
1932 int free_enough = 0;
1934 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1935 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1940 if (free_enough >= 2) {
1941 /* use RR selection process, ensuring that the one
1945 i = last_rr_session_dir;
1948 if (++i == session_dirs.end()) {
1949 i = session_dirs.begin();
1952 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1953 if (create_session_directory ((*i).path)) {
1955 last_rr_session_dir = i;
1960 } while (i != last_rr_session_dir);
1964 /* pick FS with the most freespace (and that
1965 seems to actually work ...)
1968 vector<space_and_path> sorted;
1969 space_and_path_ascending_cmp cmp;
1971 sorted = session_dirs;
1972 sort (sorted.begin(), sorted.end(), cmp);
1974 for (i = sorted.begin(); i != sorted.end(); ++i) {
1975 if (create_session_directory ((*i).path)) {
1977 last_rr_session_dir = i;
1987 Session::load_named_selections (const XMLNode& node)
1990 XMLNodeConstIterator niter;
1993 nlist = node.children();
1997 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1999 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2000 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2008 Session::XMLNamedSelectionFactory (const XMLNode& node)
2011 return new NamedSelection (*this, node);
2014 catch (failed_constructor& err) {
2020 Session::automation_dir () const
2022 return Glib::build_filename (_path, "automation");
2026 Session::analysis_dir () const
2028 return Glib::build_filename (_path, "analysis");
2032 Session::load_bundles (XMLNode const & node)
2034 XMLNodeList nlist = node.children();
2035 XMLNodeConstIterator niter;
2039 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2040 if ((*niter)->name() == "InputBundle") {
2041 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2042 } else if ((*niter)->name() == "OutputBundle") {
2043 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2045 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2054 Session::load_route_groups (const XMLNode& node, int version)
2056 XMLNodeList nlist = node.children();
2057 XMLNodeConstIterator niter;
2061 if (version >= 3000) {
2063 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2064 if ((*niter)->name() == "RouteGroup") {
2065 RouteGroup* rg = new RouteGroup (*this, "");
2066 add_route_group (rg);
2067 rg->set_state (**niter, version);
2071 } else if (version < 3000) {
2073 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2074 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2075 RouteGroup* rg = new RouteGroup (*this, "");
2076 add_route_group (rg);
2077 rg->set_state (**niter, version);
2086 Session::auto_save()
2088 save_state (_current_snapshot_name);
2092 state_file_filter (const string &str, void */*arg*/)
2094 return (str.length() > strlen(statefile_suffix) &&
2095 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2099 bool operator()(const string* a, const string* b) {
2105 remove_end(string* state)
2107 string statename(*state);
2109 string::size_type start,end;
2110 if ((start = statename.find_last_of ('/')) != string::npos) {
2111 statename = statename.substr (start+1);
2114 if ((end = statename.rfind(".ardour")) == string::npos) {
2115 end = statename.length();
2118 return new string(statename.substr (0, end));
2122 Session::possible_states (string path)
2124 PathScanner scanner;
2125 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2127 transform(states->begin(), states->end(), states->begin(), remove_end);
2130 sort (states->begin(), states->end(), cmp);
2136 Session::possible_states () const
2138 return possible_states(_path);
2142 Session::add_route_group (RouteGroup* g)
2144 _route_groups.push_back (g);
2145 route_group_added (g); /* EMIT SIGNAL */
2150 Session::remove_route_group (RouteGroup& rg)
2152 list<RouteGroup*>::iterator i;
2154 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2155 _route_groups.erase (i);
2158 route_group_removed (); /* EMIT SIGNAL */
2164 Session::route_group_by_name (string name)
2166 list<RouteGroup *>::iterator i;
2168 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2169 if ((*i)->name() == name) {
2177 Session::start_reversible_command (const string& name)
2179 UndoTransaction* trans = new UndoTransaction();
2180 trans->set_name(name);
2185 Session::finish_reversible_command (UndoTransaction& ut)
2188 gettimeofday(&now, 0);
2189 ut.set_timestamp(now);
2194 Session::begin_reversible_command(const string& name)
2196 UndoTransaction* trans = new UndoTransaction();
2197 trans->set_name(name);
2199 if (!_current_trans.empty()) {
2200 _current_trans.top()->add_command (trans);
2202 _current_trans.push(trans);
2207 Session::commit_reversible_command(Command *cmd)
2209 assert(!_current_trans.empty());
2213 _current_trans.top()->add_command(cmd);
2216 if (_current_trans.top()->empty()) {
2217 _current_trans.pop();
2221 gettimeofday(&now, 0);
2222 _current_trans.top()->set_timestamp(now);
2224 _history.add(_current_trans.top());
2225 _current_trans.pop();
2229 accept_all_non_peak_files (const string& path, void */*arg*/)
2231 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2235 accept_all_state_files (const string& path, void */*arg*/)
2237 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2241 Session::find_all_sources (string path, set<string>& result)
2246 if (!tree.read (path)) {
2250 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2255 XMLNodeConstIterator niter;
2257 nlist = node->children();
2261 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2265 if ((prop = (*niter)->property (X_("type"))) == 0) {
2269 DataType type (prop->value());
2271 if ((prop = (*niter)->property (X_("name"))) == 0) {
2275 if (prop->value()[0] == '/') {
2276 /* external file, ignore */
2280 Glib::ustring found_path;
2284 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2285 result.insert (found_path);
2293 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2295 PathScanner scanner;
2296 vector<string*>* state_files;
2298 string this_snapshot_path;
2304 if (ripped[ripped.length()-1] == '/') {
2305 ripped = ripped.substr (0, ripped.length() - 1);
2308 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2310 if (state_files == 0) {
2315 this_snapshot_path = _path;
2316 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2317 this_snapshot_path += statefile_suffix;
2319 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2321 if (exclude_this_snapshot && **i == this_snapshot_path) {
2325 if (find_all_sources (**i, result) < 0) {
2333 struct RegionCounter {
2334 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2335 AudioSourceList::iterator iter;
2336 boost::shared_ptr<Region> region;
2339 RegionCounter() : count (0) {}
2343 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2345 return *AskAboutPlaylistDeletion (p);
2349 Session::cleanup_sources (CleanupReport& rep)
2351 // FIXME: needs adaptation to midi
2353 vector<boost::shared_ptr<Source> > dead_sources;
2354 PathScanner scanner;
2356 vector<space_and_path>::iterator i;
2357 vector<space_and_path>::iterator nexti;
2358 vector<string*>* soundfiles;
2359 vector<string> unused;
2360 set<string> all_sources;
2365 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2367 /* step 1: consider deleting all unused playlists */
2369 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2374 /* step 2: find all un-used sources */
2379 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2381 SourceMap::iterator tmp;
2386 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2390 if (!playlists->source_use_count(i->second) && i->second->length(i->second->timeline_position()) > 0) {
2391 dead_sources.push_back (i->second);
2392 i->second->drop_references ();
2398 /* build a list of all the possible sound directories for the session */
2400 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2405 SessionDirectory sdir ((*i).path);
2406 sound_path += sdir.sound_path().to_string();
2408 if (nexti != session_dirs.end()) {
2415 /* now do the same thing for the files that ended up in the sounds dir(s)
2416 but are not referenced as sources in any snapshot.
2419 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2421 if (soundfiles == 0) {
2425 /* find all sources, but don't use this snapshot because the
2426 state file on disk still references sources we may have already
2430 find_all_sources_across_snapshots (all_sources, true);
2432 /* add our current source list
2435 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2436 boost::shared_ptr<FileSource> fs;
2438 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2439 all_sources.insert (fs->path());
2443 char tmppath1[PATH_MAX+1];
2444 char tmppath2[PATH_MAX+1];
2446 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2451 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2453 realpath(spath.c_str(), tmppath1);
2454 realpath((*i).c_str(), tmppath2);
2456 if (strcmp(tmppath1, tmppath2) == 0) {
2463 unused.push_back (spath);
2467 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2469 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2470 struct stat statbuf;
2472 rep.paths.push_back (*x);
2473 if (stat ((*x).c_str(), &statbuf) == 0) {
2474 rep.space += statbuf.st_size;
2479 /* don't move the file across filesystems, just
2480 stick it in the `dead_sound_dir_name' directory
2481 on whichever filesystem it was already on.
2484 if ((*x).find ("/sounds/") != string::npos) {
2486 /* old school, go up 1 level */
2488 newpath = Glib::path_get_dirname (*x); // "sounds"
2489 newpath = Glib::path_get_dirname (newpath); // "session-name"
2493 /* new school, go up 4 levels */
2495 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2496 newpath = Glib::path_get_dirname (newpath); // "session-name"
2497 newpath = Glib::path_get_dirname (newpath); // "interchange"
2498 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2502 newpath += dead_sound_dir_name;
2504 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2505 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2510 newpath += Glib::path_get_basename ((*x));
2512 if (access (newpath.c_str(), F_OK) == 0) {
2514 /* the new path already exists, try versioning */
2516 char buf[PATH_MAX+1];
2520 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2523 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2524 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2528 if (version == 999) {
2529 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2533 newpath = newpath_v;
2538 /* it doesn't exist, or we can't read it or something */
2542 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2543 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2544 (*x), newpath, strerror (errno))
2549 /* see if there an easy to find peakfile for this file, and remove it.
2552 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2553 peakpath += peakfile_suffix;
2555 if (access (peakpath.c_str(), W_OK) == 0) {
2556 if (::unlink (peakpath.c_str()) != 0) {
2557 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2558 peakpath, _path, strerror (errno))
2560 /* try to back out */
2561 rename (newpath.c_str(), _path.c_str());
2569 /* dump the history list */
2573 /* save state so we don't end up a session file
2574 referring to non-existent sources.
2580 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2586 Session::cleanup_trash_sources (CleanupReport& rep)
2588 // FIXME: needs adaptation for MIDI
2590 vector<space_and_path>::iterator i;
2591 string dead_sound_dir;
2592 struct dirent* dentry;
2593 struct stat statbuf;
2599 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2601 dead_sound_dir = (*i).path;
2602 dead_sound_dir += dead_sound_dir_name;
2604 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2608 while ((dentry = readdir (dead)) != 0) {
2610 /* avoid '.' and '..' */
2612 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2613 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2619 fullpath = dead_sound_dir;
2621 fullpath += dentry->d_name;
2623 if (stat (fullpath.c_str(), &statbuf)) {
2627 if (!S_ISREG (statbuf.st_mode)) {
2631 if (unlink (fullpath.c_str())) {
2632 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2633 fullpath, strerror (errno))
2637 rep.paths.push_back (dentry->d_name);
2638 rep.space += statbuf.st_size;
2649 Session::set_dirty ()
2651 bool was_dirty = dirty();
2653 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2657 DirtyChanged(); /* EMIT SIGNAL */
2663 Session::set_clean ()
2665 bool was_dirty = dirty();
2667 _state_of_the_state = Clean;
2671 DirtyChanged(); /* EMIT SIGNAL */
2676 Session::set_deletion_in_progress ()
2678 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2682 Session::clear_deletion_in_progress ()
2684 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2688 Session::add_controllable (boost::shared_ptr<Controllable> c)
2690 /* this adds a controllable to the list managed by the Session.
2691 this is a subset of those managed by the Controllable class
2692 itself, and represents the only ones whose state will be saved
2693 as part of the session.
2696 Glib::Mutex::Lock lm (controllables_lock);
2697 controllables.insert (c);
2700 struct null_deleter { void operator()(void const *) const {} };
2703 Session::remove_controllable (Controllable* c)
2705 if (_state_of_the_state | Deletion) {
2709 Glib::Mutex::Lock lm (controllables_lock);
2711 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2713 if (x != controllables.end()) {
2714 controllables.erase (x);
2718 boost::shared_ptr<Controllable>
2719 Session::controllable_by_id (const PBD::ID& id)
2721 Glib::Mutex::Lock lm (controllables_lock);
2723 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2724 if ((*i)->id() == id) {
2729 return boost::shared_ptr<Controllable>();
2732 boost::shared_ptr<Controllable>
2733 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2735 boost::shared_ptr<Controllable> c;
2736 boost::shared_ptr<Route> r;
2738 switch (desc.top_level_type()) {
2739 case ControllableDescriptor::NamedRoute:
2741 std::string str = desc.top_level_name();
2742 if (str == "master") {
2744 } else if (str == "control" || str == "listen") {
2747 r = route_by_name (desc.top_level_name());
2752 case ControllableDescriptor::RemoteControlID:
2753 r = route_by_remote_id (desc.rid());
2761 switch (desc.subtype()) {
2762 case ControllableDescriptor::Gain:
2763 c = r->gain_control ();
2766 case ControllableDescriptor::Solo:
2767 c = r->solo_control();
2770 case ControllableDescriptor::Mute:
2771 c = r->mute_control();
2774 case ControllableDescriptor::Recenable:
2776 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2779 c = t->rec_enable_control ();
2784 case ControllableDescriptor::Pan:
2785 /* XXX pan control */
2788 case ControllableDescriptor::Balance:
2789 /* XXX simple pan control */
2792 case ControllableDescriptor::PluginParameter:
2794 uint32_t plugin = desc.target (0);
2795 uint32_t parameter_index = desc.target (1);
2797 /* revert to zero based counting */
2803 if (parameter_index > 0) {
2807 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
2810 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
2811 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
2816 case ControllableDescriptor::SendGain:
2818 uint32_t send = desc.target (0);
2820 /* revert to zero-based counting */
2826 boost::shared_ptr<Processor> p = r->nth_send (send);
2829 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
2830 boost::shared_ptr<Amp> a = s->amp();
2833 c = s->amp()->gain_control();
2840 /* relax and return a null pointer */
2848 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2851 Stateful::add_instant_xml (node, _path);
2854 if (write_to_config) {
2855 Config->add_instant_xml (node);
2860 Session::instant_xml (const string& node_name)
2862 return Stateful::instant_xml (node_name, _path);
2866 Session::save_history (string snapshot_name)
2874 if (snapshot_name.empty()) {
2875 snapshot_name = _current_snapshot_name;
2878 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2879 const string backup_filename = history_filename + backup_suffix;
2880 const sys::path xml_path = _session_dir->root_path() / history_filename;
2881 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2883 if (sys::exists (xml_path)) {
2886 sys::rename (xml_path, backup_path);
2888 catch (const sys::filesystem_error& err)
2890 error << _("could not backup old history file, current history not saved") << endmsg;
2895 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2899 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2901 if (!tree.write (xml_path.to_string()))
2903 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2907 sys::remove (xml_path);
2908 sys::rename (backup_path, xml_path);
2910 catch (const sys::filesystem_error& err)
2912 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2913 backup_path.to_string(), err.what()) << endmsg;
2923 Session::restore_history (string snapshot_name)
2927 if (snapshot_name.empty()) {
2928 snapshot_name = _current_snapshot_name;
2931 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
2932 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2934 info << "Loading history from " << xml_path.to_string() << endmsg;
2936 if (!sys::exists (xml_path)) {
2937 info << string_compose (_("%1: no history file \"%2\" for this session."),
2938 _name, xml_path.to_string()) << endmsg;
2942 if (!tree.read (xml_path.to_string())) {
2943 error << string_compose (_("Could not understand session history file \"%1\""),
2944 xml_path.to_string()) << endmsg;
2951 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2954 UndoTransaction* ut = new UndoTransaction ();
2957 ut->set_name(t->property("name")->value());
2958 stringstream ss(t->property("tv-sec")->value());
2960 ss.str(t->property("tv-usec")->value());
2962 ut->set_timestamp(tv);
2964 for (XMLNodeConstIterator child_it = t->children().begin();
2965 child_it != t->children().end(); child_it++)
2967 XMLNode *n = *child_it;
2970 if (n->name() == "MementoCommand" ||
2971 n->name() == "MementoUndoCommand" ||
2972 n->name() == "MementoRedoCommand") {
2974 if ((c = memento_command_factory(n))) {
2978 } else if (n->name() == "DeltaCommand") {
2979 PBD::ID id(n->property("midi-source")->value());
2980 boost::shared_ptr<MidiSource> midi_source =
2981 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2983 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
2985 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
2988 } else if (n->name() == "DiffCommand") {
2989 PBD::ID id(n->property("midi-source")->value());
2990 boost::shared_ptr<MidiSource> midi_source =
2991 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2993 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
2995 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
2998 } else if (n->name() == "StatefulDiffCommand") {
2999 if ((c = stateful_diff_command_factory (n))) {
3000 ut->add_command (c);
3003 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3014 Session::config_changed (std::string p, bool ours)
3020 if (p == "seamless-loop") {
3022 } else if (p == "rf-speed") {
3024 } else if (p == "auto-loop") {
3026 } else if (p == "auto-input") {
3028 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3029 /* auto-input only makes a difference if we're rolling */
3031 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3033 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3034 if ((*i)->record_enabled ()) {
3035 (*i)->monitor_input (!config.get_auto_input());
3040 } else if (p == "punch-in") {
3044 if ((location = _locations.auto_punch_location()) != 0) {
3046 if (config.get_punch_in ()) {
3047 replace_event (SessionEvent::PunchIn, location->start());
3049 remove_event (location->start(), SessionEvent::PunchIn);
3053 } else if (p == "punch-out") {
3057 if ((location = _locations.auto_punch_location()) != 0) {
3059 if (config.get_punch_out()) {
3060 replace_event (SessionEvent::PunchOut, location->end());
3062 clear_events (SessionEvent::PunchOut);
3066 } else if (p == "edit-mode") {
3068 Glib::Mutex::Lock lm (playlists->lock);
3070 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3071 (*i)->set_edit_mode (Config->get_edit_mode ());
3074 } else if (p == "use-video-sync") {
3076 waiting_for_sync_offset = config.get_use_video_sync();
3078 } else if (p == "mmc-control") {
3080 //poke_midi_thread ();
3082 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3085 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3088 } else if (p == "mmc-send-id") {
3091 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3094 } else if (p == "midi-control") {
3096 //poke_midi_thread ();
3098 } else if (p == "raid-path") {
3100 setup_raid_path (config.get_raid_path());
3102 } else if (p == "timecode-format") {
3106 } else if (p == "video-pullup") {
3110 } else if (p == "seamless-loop") {
3112 if (play_loop && transport_rolling()) {
3113 // to reset diskstreams etc
3114 request_play_loop (true);
3117 } else if (p == "rf-speed") {
3119 cumulative_rf_motion = 0;
3122 } else if (p == "click-sound") {
3124 setup_click_sounds (1);
3126 } else if (p == "click-emphasis-sound") {
3128 setup_click_sounds (-1);
3130 } else if (p == "clicking") {
3132 if (Config->get_clicking()) {
3133 if (_click_io && click_data) { // don't require emphasis data
3140 } else if (p == "send-mtc") {
3142 /* only set the internal flag if we have
3146 if (_mtc_port != 0) {
3147 session_send_mtc = Config->get_send_mtc();
3148 if (session_send_mtc) {
3149 /* mark us ready to send */
3150 next_quarter_frame_to_send = 0;
3153 session_send_mtc = false;
3156 } else if (p == "send-mmc") {
3158 /* only set the internal flag if we have
3162 if (_mmc_port != 0) {
3163 session_send_mmc = Config->get_send_mmc();
3166 session_send_mmc = false;
3169 } else if (p == "midi-feedback") {
3171 /* only set the internal flag if we have
3175 if (_mtc_port != 0) {
3176 session_midi_feedback = Config->get_midi_feedback();
3179 } else if (p == "jack-time-master") {
3181 engine().reset_timebase ();
3183 } else if (p == "native-file-header-format") {
3185 if (!first_file_header_format_reset) {
3186 reset_native_file_format ();
3189 first_file_header_format_reset = false;
3191 } else if (p == "native-file-data-format") {
3193 if (!first_file_data_format_reset) {
3194 reset_native_file_format ();
3197 first_file_data_format_reset = false;
3199 } else if (p == "external-sync") {
3200 if (!config.get_external_sync()) {
3201 drop_sync_source ();
3203 switch_to_sync_source (config.get_sync_source());
3205 } else if (p == "remote-model") {
3206 set_remote_control_ids ();
3207 } else if (p == "denormal-model") {
3209 } else if (p == "history-depth") {
3210 set_history_depth (Config->get_history_depth());
3211 } else if (p == "sync-all-route-ordering") {
3212 sync_order_keys ("session");
3213 } else if (p == "initial-program-change") {
3215 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3218 buf[0] = MIDI::program; // channel zero by default
3219 buf[1] = (Config->get_initial_program_change() & 0x7f);
3221 _mmc_port->midimsg (buf, sizeof (buf), 0);
3223 } else if (p == "initial-program-change") {
3225 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3226 MIDI::byte* buf = new MIDI::byte[2];
3228 buf[0] = MIDI::program; // channel zero by default
3229 buf[1] = (Config->get_initial_program_change() & 0x7f);
3230 // deliver_midi (_mmc_port, buf, 2);
3232 } else if (p == "solo-mute-override") {
3233 // catch_up_on_solo_mute_override ();
3234 } else if (p == "listen-position") {
3235 listen_position_changed ();
3236 } else if (p == "solo-control-is-listen-control") {
3237 solo_control_mode_changed ();
3245 Session::set_history_depth (uint32_t d)
3247 _history.set_depth (d);