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"
68 #include "ardour/amp.h"
69 #include "ardour/audio_diskstream.h"
70 #include "ardour/audio_track.h"
71 #include "ardour/audioengine.h"
72 #include "ardour/audiofilesource.h"
73 #include "ardour/audioplaylist.h"
74 #include "ardour/audioregion.h"
75 #include "ardour/auditioner.h"
76 #include "ardour/buffer.h"
77 #include "ardour/butler.h"
78 #include "ardour/configuration.h"
79 #include "ardour/control_protocol_manager.h"
80 #include "ardour/crossfade.h"
81 #include "ardour/cycle_timer.h"
82 #include "ardour/directory_names.h"
83 #include "ardour/filename_extensions.h"
84 #include "ardour/io_processor.h"
85 #include "ardour/location.h"
86 #include "ardour/midi_diskstream.h"
87 #include "ardour/midi_patch_manager.h"
88 #include "ardour/midi_playlist.h"
89 #include "ardour/midi_region.h"
90 #include "ardour/midi_source.h"
91 #include "ardour/midi_track.h"
92 #include "ardour/named_selection.h"
93 #include "ardour/processor.h"
94 #include "ardour/region_factory.h"
95 #include "ardour/route_group.h"
96 #include "ardour/send.h"
97 #include "ardour/session.h"
98 #include "ardour/session_directory.h"
99 #include "ardour/session_metadata.h"
100 #include "ardour/session_state_utils.h"
101 #include "ardour/session_playlists.h"
102 #include "ardour/session_utils.h"
103 #include "ardour/silentfilesource.h"
104 #include "ardour/slave.h"
105 #include "ardour/smf_source.h"
106 #include "ardour/sndfile_helpers.h"
107 #include "ardour/sndfilesource.h"
108 #include "ardour/source_factory.h"
109 #include "ardour/template_utils.h"
110 #include "ardour/tempo.h"
111 #include "ardour/ticker.h"
112 #include "ardour/user_bundle.h"
113 #include "ardour/utils.h"
114 #include "ardour/utils.h"
115 #include "ardour/version.h"
116 #include "ardour/playlist_factory.h"
118 #include "control_protocol/control_protocol.h"
124 using namespace ARDOUR;
128 Session::first_stage_init (string fullpath, string snapshot_name)
130 if (fullpath.length() == 0) {
132 throw failed_constructor();
135 char buf[PATH_MAX+1];
136 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
137 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
139 throw failed_constructor();
144 if (_path[_path.length()-1] != '/') {
148 if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
149 cerr << "Session non-writable based on " << _path << endl;
152 cerr << "Session writable based on " << _path << endl;
156 /* these two are just provisional settings. set_state()
157 will likely override them.
160 _name = _current_snapshot_name = snapshot_name;
162 set_history_depth (Config->get_history_depth());
164 _current_frame_rate = _engine.frame_rate ();
165 _nominal_frame_rate = _current_frame_rate;
166 _base_frame_rate = _current_frame_rate;
168 _tempo_map = new TempoMap (_current_frame_rate);
169 _tempo_map->StateChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
172 _non_soloed_outs_muted = false;
174 g_atomic_int_set (&processing_prohibited, 0);
175 _transport_speed = 0;
176 _last_transport_speed = 0;
177 _target_transport_speed = 0;
178 auto_play_legal = false;
179 transport_sub_state = 0;
180 _transport_frame = 0;
181 _requested_return_frame = -1;
182 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
183 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
184 g_atomic_int_set (&_record_status, Disabled);
185 loop_changing = false;
188 _last_roll_location = 0;
189 _last_record_location = 0;
190 pending_locate_frame = 0;
191 pending_locate_roll = false;
192 pending_locate_flush = false;
193 state_was_pending = false;
195 outbound_mtc_timecode_frame = 0;
196 next_quarter_frame_to_send = -1;
197 current_block_size = 0;
198 solo_update_disabled = false;
199 _have_captured = false;
200 _worst_output_latency = 0;
201 _worst_input_latency = 0;
202 _worst_track_latency = 0;
203 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
204 _was_seamless = Config->get_seamless_loop ();
206 session_send_mmc = false;
207 session_send_mtc = false;
208 g_atomic_int_set (&_playback_load, 100);
209 g_atomic_int_set (&_capture_load, 100);
210 g_atomic_int_set (&_playback_load_min, 100);
211 g_atomic_int_set (&_capture_load_min, 100);
214 _gain_automation_buffer = 0;
215 _pan_automation_buffer = 0;
217 pending_abort = false;
218 destructive_index = 0;
219 first_file_data_format_reset = true;
220 first_file_header_format_reset = true;
221 post_export_sync = false;
224 AudioDiskstream::allocate_working_buffers();
226 /* default short fade = 15ms */
228 Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
229 SndFileSource::setup_standard_crossfades (*this, frame_rate());
231 last_mmc_step.tv_sec = 0;
232 last_mmc_step.tv_usec = 0;
235 /* click sounds are unset by default, which causes us to internal
236 waveforms for clicks.
240 click_emphasis_length = 0;
243 process_function = &Session::process_with_events;
245 if (config.get_use_video_sync()) {
246 waiting_for_sync_offset = true;
248 waiting_for_sync_offset = false;
251 last_timecode_when = 0;
252 _timecode_offset = 0;
253 _timecode_offset_negative = true;
254 last_timecode_valid = false;
258 last_rr_session_dir = session_dirs.begin();
259 refresh_disk_space ();
261 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
265 average_slave_delta = 1800; // !!! why 1800 ????
266 have_first_delta_accumulator = false;
267 delta_accumulator_cnt = 0;
268 _slave_state = Stopped;
270 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
272 /* These are all static "per-class" signals */
274 RegionFactory::CheckNewRegion.connect_same_thread (*this, boost::bind (&Session::add_region, this, _1));
275 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
276 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
277 Processor::ProcessorCreated.connect_same_thread (*this, boost::bind (&Session::add_processor, this, _1));
278 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
279 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
280 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
282 /* stop IO objects from doing stuff until we're ready for them */
284 Delivery::disable_panners ();
285 IO::disable_connecting ();
289 Session::second_stage_init (bool new_session)
291 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
294 if (load_state (_current_snapshot_name)) {
297 remove_empty_sounds ();
300 if (_butler->start_thread()) {
304 if (start_midi_thread ()) {
308 // set_state() will call setup_raid_path(), but if it's a new session we need
309 // to call setup_raid_path() here.
312 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
316 setup_raid_path(_path);
319 /* we can't save till after ::when_engine_running() is called,
320 because otherwise we save state with no connections made.
321 therefore, we reset _state_of_the_state because ::set_state()
322 will have cleared it.
324 we also have to include Loading so that any events that get
325 generated between here and the end of ::when_engine_running()
326 will be processed directly rather than queued.
329 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
332 _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
333 _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
334 setup_click_sounds (0);
335 setup_midi_control ();
337 /* Pay attention ... */
339 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
340 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
343 when_engine_running();
346 /* handle this one in a different way than all others, so that its clear what happened */
348 catch (AudioEngine::PortRegistrationFailure& err) {
349 error << err.what() << endmsg;
357 BootMessage (_("Reset Remote Controls"));
359 send_full_time_code (0);
360 _engine.transport_locate (0);
361 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
362 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
364 MidiClockTicker::instance().set_session (this);
365 MIDI::Name::MidiPatchManager::instance().set_session (this);
367 /* initial program change will be delivered later; see ::config_changed() */
369 BootMessage (_("Reset Control Protocols"));
371 ControlProtocolManager::instance().set_session (this);
373 config.set_end_marker_is_free (new_session);
375 _state_of_the_state = Clean;
377 DirtyChanged (); /* EMIT SIGNAL */
379 if (state_was_pending) {
380 save_state (_current_snapshot_name);
381 remove_pending_capture_state ();
382 state_was_pending = false;
385 BootMessage (_("Session loading complete"));
391 Session::raid_path () const
393 SearchPath raid_search_path;
395 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
396 raid_search_path += sys::path((*i).path);
399 return raid_search_path.to_string ();
403 Session::setup_raid_path (string path)
412 session_dirs.clear ();
414 SearchPath search_path(path);
415 SearchPath sound_search_path;
416 SearchPath midi_search_path;
418 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
419 sp.path = (*i).to_string ();
420 sp.blocks = 0; // not needed
421 session_dirs.push_back (sp);
423 SessionDirectory sdir(sp.path);
425 sound_search_path += sdir.sound_path ();
426 midi_search_path += sdir.midi_path ();
429 // set the search path for each data type
430 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
431 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
433 // reset the round-robin soundfile path thingie
434 last_rr_session_dir = session_dirs.begin();
438 Session::path_is_within_session (const std::string& path)
440 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
441 if (path.find ((*i).path) == 0) {
449 Session::ensure_subdirs ()
453 dir = session_directory().peak_path().to_string();
455 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
456 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
460 dir = session_directory().sound_path().to_string();
462 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
463 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
467 dir = session_directory().midi_path().to_string();
469 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
470 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
474 dir = session_directory().dead_sound_path().to_string();
476 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
477 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
481 dir = session_directory().export_path().to_string();
483 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
484 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
488 dir = analysis_dir ();
490 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
491 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
499 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
502 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
503 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
507 if (ensure_subdirs ()) {
511 /* check new_session so we don't overwrite an existing one */
513 if (!mix_template.empty()) {
514 std::string in_path = mix_template;
516 ifstream in(in_path.c_str());
519 string out_path = _path;
521 out_path += statefile_suffix;
523 ofstream out(out_path.c_str());
528 // okay, session is set up. Treat like normal saved
529 // session from now on.
535 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
541 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
548 /* Instantiate metadata */
550 _metadata = new SessionMetadata ();
552 /* set initial start + end point */
554 start_location->set_end (0);
555 _locations.add (start_location);
557 end_location->set_end (initial_length);
558 _locations.add (end_location);
560 _state_of_the_state = Clean;
569 Session::load_diskstreams (const XMLNode& node)
572 XMLNodeConstIterator citer;
574 clist = node.children();
576 for (citer = clist.begin(); citer != clist.end(); ++citer) {
579 /* diskstreams added automatically by DiskstreamCreated handler */
580 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
581 AudioDiskstream* dsp (new AudioDiskstream (*this, **citer));
582 boost::shared_ptr<AudioDiskstream> dstream (dsp);
583 add_diskstream (dstream);
584 } else if ((*citer)->name() == "MidiDiskstream") {
585 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
586 add_diskstream (dstream);
588 error << _("Session: unknown diskstream type in XML") << endmsg;
592 catch (failed_constructor& err) {
593 error << _("Session: could not load diskstream via XML state") << endmsg;
602 Session::maybe_write_autosave()
604 if (dirty() && record_status() != Recording) {
605 save_state("", true);
610 Session::remove_pending_capture_state ()
612 sys::path pending_state_file_path(_session_dir->root_path());
614 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
618 sys::remove (pending_state_file_path);
620 catch(sys::filesystem_error& ex)
622 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
623 pending_state_file_path.to_string(), ex.what()) << endmsg;
627 /** Rename a state file.
628 * @param snapshot_name Snapshot name.
631 Session::rename_state (string old_name, string new_name)
633 if (old_name == _current_snapshot_name || old_name == _name) {
634 /* refuse to rename the current snapshot or the "main" one */
638 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
639 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
641 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
642 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
646 sys::rename (old_xml_path, new_xml_path);
648 catch (const sys::filesystem_error& err)
650 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
651 old_name, new_name, err.what()) << endmsg;
655 /** Remove a state file.
656 * @param snapshot_name Snapshot name.
659 Session::remove_state (string snapshot_name)
661 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
662 // refuse to remove the current snapshot or the "main" one
666 sys::path xml_path(_session_dir->root_path());
668 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
670 if (!create_backup_file (xml_path)) {
671 // don't remove it if a backup can't be made
672 // create_backup_file will log the error.
677 sys::remove (xml_path);
681 Session::save_state (string snapshot_name, bool pending)
684 sys::path xml_path(_session_dir->root_path());
686 if (!_writable || (_state_of_the_state & CannotSave)) {
690 if (!_engine.connected ()) {
691 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
696 /* tell sources we're saving first, in case they write out to a new file
697 * which should be saved with the state rather than the old one */
698 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
699 i->second->session_saved();
701 tree.set_root (&get_state());
703 if (snapshot_name.empty()) {
704 snapshot_name = _current_snapshot_name;
709 /* proper save: use statefile_suffix (.ardour in English) */
711 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
713 /* make a backup copy of the old file */
715 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
716 // create_backup_file will log the error
722 /* pending save: use pending_suffix (.pending in English) */
723 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
726 sys::path tmp_path(_session_dir->root_path());
728 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
730 // cerr << "actually writing state to " << xml_path.to_string() << endl;
732 if (!tree.write (tmp_path.to_string())) {
733 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
734 sys::remove (tmp_path);
739 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
740 error << string_compose (_("could not rename temporary session file %1 to %2"),
741 tmp_path.to_string(), xml_path.to_string()) << endmsg;
742 sys::remove (tmp_path);
749 save_history (snapshot_name);
751 bool was_dirty = dirty();
753 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
756 DirtyChanged (); /* EMIT SIGNAL */
759 StateSaved (snapshot_name); /* EMIT SIGNAL */
766 Session::restore_state (string snapshot_name)
768 if (load_state (snapshot_name) == 0) {
769 set_state (*state_tree->root(), Stateful::loading_state_version);
776 Session::load_state (string snapshot_name)
781 state_was_pending = false;
783 /* check for leftover pending state from a crashed capture attempt */
785 sys::path xmlpath(_session_dir->root_path());
786 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
788 if (sys::exists (xmlpath)) {
790 /* there is pending state from a crashed capture attempt */
792 if (*AskAboutPendingState()) {
793 state_was_pending = true;
797 if (!state_was_pending) {
798 xmlpath = _session_dir->root_path();
799 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
802 if (!sys::exists (xmlpath)) {
803 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
807 state_tree = new XMLTree;
811 /* writable() really reflects the whole folder, but if for any
812 reason the session state file can't be written to, still
816 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
820 if (!state_tree->read (xmlpath.to_string())) {
821 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
827 XMLNode& root (*state_tree->root());
829 if (root.name() != X_("Session")) {
830 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
836 const XMLProperty* prop;
838 if ((prop = root.property ("version")) == 0) {
839 /* no version implies very old version of Ardour */
840 Stateful::loading_state_version = 1000;
846 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
847 Stateful::loading_state_version = (major * 1000) + minor;
850 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
852 sys::path backup_path(_session_dir->root_path());
854 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
856 // only create a backup once
857 if (sys::exists (backup_path)) {
861 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
862 xmlpath.to_string(), backup_path.to_string())
867 sys::copy_file (xmlpath, backup_path);
869 catch(sys::filesystem_error& ex)
871 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
872 xmlpath.to_string(), ex.what())
882 Session::load_options (const XMLNode& node)
884 LocaleGuard lg (X_("POSIX"));
885 config.set_variables (node);
896 Session::get_template()
898 /* if we don't disable rec-enable, diskstreams
899 will believe they need to store their capture
900 sources in their state node.
903 disable_record (false);
909 Session::state(bool full_state)
911 XMLNode* node = new XMLNode("Session");
914 // store libardour version, just in case
916 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
917 node->add_property("version", string(buf));
919 /* store configuration settings */
923 node->add_property ("name", _name);
924 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
925 node->add_property ("sample-rate", buf);
927 if (session_dirs.size() > 1) {
931 vector<space_and_path>::iterator i = session_dirs.begin();
932 vector<space_and_path>::iterator next;
934 ++i; /* skip the first one */
938 while (i != session_dirs.end()) {
942 if (next != session_dirs.end()) {
952 child = node->add_child ("Path");
953 child->add_content (p);
957 /* save the ID counter */
959 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
960 node->add_property ("id-counter", buf);
962 /* various options */
964 node->add_child_nocopy (config.get_variables ());
966 node->add_child_nocopy (_metadata->get_state());
968 child = node->add_child ("Sources");
971 Glib::Mutex::Lock sl (source_lock);
973 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
975 /* Don't save information about non-destructive file sources that are empty */
976 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
978 boost::shared_ptr<AudioFileSource> fs;
979 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
980 if (!fs->destructive()) {
981 if (fs->length(fs->timeline_position()) == 0) {
987 child->add_child_nocopy (siter->second->get_state());
991 child = node->add_child ("Regions");
994 Glib::Mutex::Lock rl (region_lock);
996 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
998 /* only store regions not attached to playlists */
1000 if (i->second->playlist() == 0) {
1001 child->add_child_nocopy (i->second->state (true));
1006 child = node->add_child ("DiskStreams");
1009 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1010 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1011 if (!(*i)->hidden()) {
1012 child->add_child_nocopy ((*i)->get_state());
1018 node->add_child_nocopy (_locations.get_state());
1020 // for a template, just create a new Locations, populate it
1021 // with the default start and end, and get the state for that.
1023 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1024 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1027 end->set_end(compute_initial_length());
1029 node->add_child_nocopy (loc.get_state());
1032 child = node->add_child ("Bundles");
1034 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1035 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1036 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1038 child->add_child_nocopy (b->get_state());
1043 child = node->add_child ("Routes");
1045 boost::shared_ptr<RouteList> r = routes.reader ();
1047 RoutePublicOrderSorter cmp;
1048 RouteList public_order (*r);
1049 public_order.sort (cmp);
1051 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1052 if (!(*i)->is_hidden()) {
1054 child->add_child_nocopy ((*i)->get_state());
1056 child->add_child_nocopy ((*i)->get_template());
1062 playlists->add_state (node, full_state);
1064 child = node->add_child ("RouteGroups");
1065 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1066 child->add_child_nocopy ((*i)->get_state());
1070 child = node->add_child ("Click");
1071 child->add_child_nocopy (_click_io->state (full_state));
1075 child = node->add_child ("NamedSelections");
1076 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1078 child->add_child_nocopy ((*i)->get_state());
1083 node->add_child_nocopy (_tempo_map->get_state());
1085 node->add_child_nocopy (get_control_protocol_state());
1088 node->add_child_copy (*_extra_xml);
1095 Session::get_control_protocol_state ()
1097 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1098 return cpm.get_state();
1102 Session::set_state (const XMLNode& node, int version)
1106 const XMLProperty* prop;
1109 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1111 if (node.name() != X_("Session")){
1112 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1116 if ((prop = node.property ("version")) != 0) {
1117 version = atoi (prop->value ()) * 1000;
1120 if ((prop = node.property ("name")) != 0) {
1121 _name = prop->value ();
1124 if ((prop = node.property (X_("sample-rate"))) != 0) {
1126 _nominal_frame_rate = atoi (prop->value());
1128 if (_nominal_frame_rate != _current_frame_rate) {
1129 if (*AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1135 setup_raid_path(_session_dir->root_path().to_string());
1137 if ((prop = node.property (X_("id-counter"))) != 0) {
1139 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1140 ID::init_counter (x);
1142 /* old sessions used a timebased counter, so fake
1143 the startup ID counter based on a standard
1148 ID::init_counter (now);
1152 IO::disable_connecting ();
1154 /* Object loading order:
1159 MIDI Control // relies on data from Options/Config
1173 if ((child = find_named_node (node, "Extra")) != 0) {
1174 _extra_xml = new XMLNode (*child);
1177 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1178 load_options (*child);
1179 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1180 load_options (*child);
1182 error << _("Session: XML state has no options section") << endmsg;
1185 if (use_config_midi_ports ()) {
1188 if (version >= 3000) {
1189 if ((child = find_named_node (node, "Metadata")) == 0) {
1190 warning << _("Session: XML state has no metadata section") << endmsg;
1191 } else if (_metadata->set_state (*child, version)) {
1196 if ((child = find_named_node (node, "Locations")) == 0) {
1197 error << _("Session: XML state has no locations section") << endmsg;
1199 } else if (_locations.set_state (*child, version)) {
1205 if ((location = _locations.auto_loop_location()) != 0) {
1206 set_auto_loop_location (location);
1209 if ((location = _locations.auto_punch_location()) != 0) {
1210 set_auto_punch_location (location);
1213 if ((location = _locations.end_location()) == 0) {
1214 _locations.add (end_location);
1216 delete end_location;
1217 end_location = location;
1220 if ((location = _locations.start_location()) == 0) {
1221 _locations.add (start_location);
1223 delete start_location;
1224 start_location = location;
1227 AudioFileSource::set_header_position_offset (start_location->start());
1229 if ((child = find_named_node (node, "Sources")) == 0) {
1230 error << _("Session: XML state has no sources section") << endmsg;
1232 } else if (load_sources (*child)) {
1236 if ((child = find_named_node (node, "Regions")) == 0) {
1237 error << _("Session: XML state has no Regions section") << endmsg;
1239 } else if (load_regions (*child)) {
1243 if ((child = find_named_node (node, "Playlists")) == 0) {
1244 error << _("Session: XML state has no playlists section") << endmsg;
1246 } else if (playlists->load (*this, *child)) {
1250 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1252 } else if (playlists->load_unused (*this, *child)) {
1256 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1257 if (load_named_selections (*child)) {
1262 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1263 error << _("Session: XML state has no diskstreams section") << endmsg;
1265 } else if (load_diskstreams (*child)) {
1269 if (version >= 3000) {
1270 if ((child = find_named_node (node, "Bundles")) == 0) {
1271 warning << _("Session: XML state has no bundles section") << endmsg;
1274 /* We can't load Bundles yet as they need to be able
1275 to convert from port names to Port objects, which can't happen until
1277 _bundle_xml_node = new XMLNode (*child);
1281 if ((child = find_named_node (node, "TempoMap")) == 0) {
1282 error << _("Session: XML state has no Tempo Map section") << endmsg;
1284 } else if (_tempo_map->set_state (*child, version)) {
1288 if ((child = find_named_node (node, "Routes")) == 0) {
1289 error << _("Session: XML state has no routes section") << endmsg;
1291 } else if (load_routes (*child, version)) {
1295 if (version >= 3000) {
1297 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1298 error << _("Session: XML state has no route groups section") << endmsg;
1300 } else if (load_route_groups (*child, version)) {
1304 } else if (version < 3000) {
1306 if ((child = find_named_node (node, "EditGroups")) == 0) {
1307 error << _("Session: XML state has no edit groups section") << endmsg;
1309 } else if (load_route_groups (*child, version)) {
1313 if ((child = find_named_node (node, "MixGroups")) == 0) {
1314 error << _("Session: XML state has no mix groups section") << endmsg;
1316 } else if (load_route_groups (*child, version)) {
1321 if ((child = find_named_node (node, "Click")) == 0) {
1322 warning << _("Session: XML state has no click section") << endmsg;
1323 } else if (_click_io) {
1324 _click_io->set_state (*child, version);
1327 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1328 ControlProtocolManager::instance().set_protocol_states (*child);
1331 /* here beginneth the second phase ... */
1333 StateReady (); /* EMIT SIGNAL */
1342 Session::load_routes (const XMLNode& node, int version)
1345 XMLNodeConstIterator niter;
1346 RouteList new_routes;
1348 nlist = node.children();
1352 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1354 boost::shared_ptr<Route> route (XMLRouteFactory (**niter, version));
1357 error << _("Session: cannot create Route from XML description.") << endmsg;
1361 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1363 new_routes.push_back (route);
1366 add_routes (new_routes, false);
1371 boost::shared_ptr<Route>
1372 Session::XMLRouteFactory (const XMLNode& node, int version)
1374 if (node.name() != "Route") {
1375 return boost::shared_ptr<Route> ((Route*) 0);
1378 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1380 DataType type = DataType::AUDIO;
1381 const XMLProperty* prop = node.property("default-type");
1382 boost::shared_ptr<Route> ret;
1385 type = DataType(prop->value());
1388 assert(type != DataType::NIL);
1390 if (has_diskstream) {
1391 if (type == DataType::AUDIO) {
1392 AudioTrack* at = new AudioTrack (*this, node, version);
1393 boost_debug_shared_ptr_mark_interesting (at, "Track");
1397 ret.reset (new MidiTrack (*this, node, version));
1400 Route* rt = new Route (*this, node);
1401 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1409 Session::load_regions (const XMLNode& node)
1412 XMLNodeConstIterator niter;
1413 boost::shared_ptr<Region> region;
1415 nlist = node.children();
1419 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1420 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1421 error << _("Session: cannot create Region from XML description.");
1422 const XMLProperty *name = (**niter).property("name");
1425 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1435 boost::shared_ptr<Region>
1436 Session::XMLRegionFactory (const XMLNode& node, bool full)
1438 const XMLProperty* type = node.property("type");
1442 if ( !type || type->value() == "audio" ) {
1444 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1446 } else if (type->value() == "midi") {
1448 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1452 } catch (failed_constructor& err) {
1453 return boost::shared_ptr<Region> ();
1456 return boost::shared_ptr<Region> ();
1459 boost::shared_ptr<AudioRegion>
1460 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1462 const XMLProperty* prop;
1463 boost::shared_ptr<Source> source;
1464 boost::shared_ptr<AudioSource> as;
1466 SourceList master_sources;
1467 uint32_t nchans = 1;
1470 if (node.name() != X_("Region")) {
1471 return boost::shared_ptr<AudioRegion>();
1474 if ((prop = node.property (X_("channels"))) != 0) {
1475 nchans = atoi (prop->value().c_str());
1478 if ((prop = node.property ("name")) == 0) {
1479 cerr << "no name for this region\n";
1483 if ((prop = node.property (X_("source-0"))) == 0) {
1484 if ((prop = node.property ("source")) == 0) {
1485 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1486 return boost::shared_ptr<AudioRegion>();
1490 PBD::ID s_id (prop->value());
1492 if ((source = source_by_id (s_id)) == 0) {
1493 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1494 return boost::shared_ptr<AudioRegion>();
1497 as = boost::dynamic_pointer_cast<AudioSource>(source);
1499 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1500 return boost::shared_ptr<AudioRegion>();
1503 sources.push_back (as);
1505 /* pickup other channels */
1507 for (uint32_t n=1; n < nchans; ++n) {
1508 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1509 if ((prop = node.property (buf)) != 0) {
1511 PBD::ID id2 (prop->value());
1513 if ((source = source_by_id (id2)) == 0) {
1514 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1515 return boost::shared_ptr<AudioRegion>();
1518 as = boost::dynamic_pointer_cast<AudioSource>(source);
1520 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1521 return boost::shared_ptr<AudioRegion>();
1523 sources.push_back (as);
1527 for (uint32_t n = 0; n < nchans; ++n) {
1528 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1529 if ((prop = node.property (buf)) != 0) {
1531 PBD::ID id2 (prop->value());
1533 if ((source = source_by_id (id2)) == 0) {
1534 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1535 return boost::shared_ptr<AudioRegion>();
1538 as = boost::dynamic_pointer_cast<AudioSource>(source);
1540 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1541 return boost::shared_ptr<AudioRegion>();
1543 master_sources.push_back (as);
1548 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1550 /* a final detail: this is the one and only place that we know how long missing files are */
1552 if (region->whole_file()) {
1553 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1554 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1556 sfp->set_length (region->length());
1561 if (!master_sources.empty()) {
1562 if (master_sources.size() != nchans) {
1563 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1565 region->set_master_sources (master_sources);
1573 catch (failed_constructor& err) {
1574 return boost::shared_ptr<AudioRegion>();
1578 boost::shared_ptr<MidiRegion>
1579 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1581 const XMLProperty* prop;
1582 boost::shared_ptr<Source> source;
1583 boost::shared_ptr<MidiSource> ms;
1585 uint32_t nchans = 1;
1587 if (node.name() != X_("Region")) {
1588 return boost::shared_ptr<MidiRegion>();
1591 if ((prop = node.property (X_("channels"))) != 0) {
1592 nchans = atoi (prop->value().c_str());
1595 if ((prop = node.property ("name")) == 0) {
1596 cerr << "no name for this region\n";
1600 // Multiple midi channels? that's just crazy talk
1601 assert(nchans == 1);
1603 if ((prop = node.property (X_("source-0"))) == 0) {
1604 if ((prop = node.property ("source")) == 0) {
1605 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1606 return boost::shared_ptr<MidiRegion>();
1610 PBD::ID s_id (prop->value());
1612 if ((source = source_by_id (s_id)) == 0) {
1613 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1614 return boost::shared_ptr<MidiRegion>();
1617 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1619 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1620 return boost::shared_ptr<MidiRegion>();
1623 sources.push_back (ms);
1626 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1627 /* a final detail: this is the one and only place that we know how long missing files are */
1629 if (region->whole_file()) {
1630 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1631 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1633 sfp->set_length (region->length());
1641 catch (failed_constructor& err) {
1642 return boost::shared_ptr<MidiRegion>();
1647 Session::get_sources_as_xml ()
1650 XMLNode* node = new XMLNode (X_("Sources"));
1651 Glib::Mutex::Lock lm (source_lock);
1653 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1654 node->add_child_nocopy (i->second->get_state());
1661 Session::path_from_region_name (DataType type, string name, string identifier)
1663 char buf[PATH_MAX+1];
1665 SessionDirectory sdir(get_best_session_directory_for_new_source());
1666 sys::path source_dir = ((type == DataType::AUDIO)
1667 ? sdir.sound_path() : sdir.midi_path());
1669 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1671 for (n = 0; n < 999999; ++n) {
1672 if (identifier.length()) {
1673 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1674 identifier.c_str(), n, ext.c_str());
1676 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1680 sys::path source_path = source_dir / buf;
1682 if (!sys::exists (source_path)) {
1683 return source_path.to_string();
1687 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1696 Session::load_sources (const XMLNode& node)
1699 XMLNodeConstIterator niter;
1700 boost::shared_ptr<Source> source;
1702 nlist = node.children();
1706 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1708 if ((source = XMLSourceFactory (**niter)) == 0) {
1709 error << _("Session: cannot create Source from XML description.") << endmsg;
1711 } catch (MissingSource& err) {
1712 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1713 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1720 boost::shared_ptr<Source>
1721 Session::XMLSourceFactory (const XMLNode& node)
1723 if (node.name() != "Source") {
1724 return boost::shared_ptr<Source>();
1728 /* note: do peak building in another thread when loading session state */
1729 return SourceFactory::create (*this, node, true);
1732 catch (failed_constructor& err) {
1733 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1734 return boost::shared_ptr<Source>();
1739 Session::save_template (string template_name)
1743 if (_state_of_the_state & CannotSave) {
1747 sys::path user_template_dir(user_template_directory());
1751 sys::create_directories (user_template_dir);
1753 catch(sys::filesystem_error& ex)
1755 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1756 user_template_dir.to_string(), ex.what()) << endmsg;
1760 tree.set_root (&get_template());
1762 sys::path template_file_path(user_template_dir);
1763 template_file_path /= template_name + template_suffix;
1765 if (sys::exists (template_file_path))
1767 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1768 template_file_path.to_string()) << endmsg;
1772 if (!tree.write (template_file_path.to_string())) {
1773 error << _("mix template not saved") << endmsg;
1781 Session::rename_template (string old_name, string new_name)
1783 sys::path old_path (user_template_directory());
1784 old_path /= old_name + template_suffix;
1786 sys::path new_path(user_template_directory());
1787 new_path /= new_name + template_suffix;
1789 if (sys::exists (new_path)) {
1790 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1791 new_path.to_string()) << endmsg;
1796 sys::rename (old_path, new_path);
1804 Session::delete_template (string name)
1806 sys::path path = user_template_directory();
1807 path /= name + template_suffix;
1818 Session::refresh_disk_space ()
1821 struct statfs statfsbuf;
1822 vector<space_and_path>::iterator i;
1823 Glib::Mutex::Lock lm (space_lock);
1826 /* get freespace on every FS that is part of the session path */
1828 _total_free_4k_blocks = 0;
1830 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1831 statfs ((*i).path.c_str(), &statfsbuf);
1833 scale = statfsbuf.f_bsize/4096.0;
1835 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1836 _total_free_4k_blocks += (*i).blocks;
1842 Session::get_best_session_directory_for_new_source ()
1844 vector<space_and_path>::iterator i;
1845 string result = _session_dir->root_path().to_string();
1847 /* handle common case without system calls */
1849 if (session_dirs.size() == 1) {
1853 /* OK, here's the algorithm we're following here:
1855 We want to select which directory to use for
1856 the next file source to be created. Ideally,
1857 we'd like to use a round-robin process so as to
1858 get maximum performance benefits from splitting
1859 the files across multiple disks.
1861 However, in situations without much diskspace, an
1862 RR approach may end up filling up a filesystem
1863 with new files while others still have space.
1864 Its therefore important to pay some attention to
1865 the freespace in the filesystem holding each
1866 directory as well. However, if we did that by
1867 itself, we'd keep creating new files in the file
1868 system with the most space until it was as full
1869 as all others, thus negating any performance
1870 benefits of this RAID-1 like approach.
1872 So, we use a user-configurable space threshold. If
1873 there are at least 2 filesystems with more than this
1874 much space available, we use RR selection between them.
1875 If not, then we pick the filesystem with the most space.
1877 This gets a good balance between the two
1881 refresh_disk_space ();
1883 int free_enough = 0;
1885 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1886 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1891 if (free_enough >= 2) {
1892 /* use RR selection process, ensuring that the one
1896 i = last_rr_session_dir;
1899 if (++i == session_dirs.end()) {
1900 i = session_dirs.begin();
1903 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1904 if (create_session_directory ((*i).path)) {
1906 last_rr_session_dir = i;
1911 } while (i != last_rr_session_dir);
1915 /* pick FS with the most freespace (and that
1916 seems to actually work ...)
1919 vector<space_and_path> sorted;
1920 space_and_path_ascending_cmp cmp;
1922 sorted = session_dirs;
1923 sort (sorted.begin(), sorted.end(), cmp);
1925 for (i = sorted.begin(); i != sorted.end(); ++i) {
1926 if (create_session_directory ((*i).path)) {
1928 last_rr_session_dir = i;
1938 Session::load_named_selections (const XMLNode& node)
1941 XMLNodeConstIterator niter;
1944 nlist = node.children();
1948 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1950 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1951 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1959 Session::XMLNamedSelectionFactory (const XMLNode& node)
1962 return new NamedSelection (*this, node);
1965 catch (failed_constructor& err) {
1971 Session::automation_dir () const
1973 return Glib::build_filename (_path, "automation");
1977 Session::analysis_dir () const
1979 return Glib::build_filename (_path, "analysis");
1983 Session::load_bundles (XMLNode const & node)
1985 XMLNodeList nlist = node.children();
1986 XMLNodeConstIterator niter;
1990 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1991 if ((*niter)->name() == "InputBundle") {
1992 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
1993 } else if ((*niter)->name() == "OutputBundle") {
1994 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
1996 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2005 Session::load_route_groups (const XMLNode& node, int version)
2007 XMLNodeList nlist = node.children();
2008 XMLNodeConstIterator niter;
2012 if (version >= 3000) {
2014 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2015 if ((*niter)->name() == "RouteGroup") {
2016 RouteGroup* rg = new RouteGroup (*this, "");
2017 add_route_group (rg);
2018 rg->set_state (**niter, version);
2022 } else if (version < 3000) {
2024 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2025 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2026 RouteGroup* rg = new RouteGroup (*this, "");
2027 add_route_group (rg);
2028 rg->set_state (**niter, version);
2037 Session::auto_save()
2039 save_state (_current_snapshot_name);
2043 state_file_filter (const string &str, void */*arg*/)
2045 return (str.length() > strlen(statefile_suffix) &&
2046 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2050 bool operator()(const string* a, const string* b) {
2056 remove_end(string* state)
2058 string statename(*state);
2060 string::size_type start,end;
2061 if ((start = statename.find_last_of ('/')) != string::npos) {
2062 statename = statename.substr (start+1);
2065 if ((end = statename.rfind(".ardour")) == string::npos) {
2066 end = statename.length();
2069 return new string(statename.substr (0, end));
2073 Session::possible_states (string path)
2075 PathScanner scanner;
2076 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2078 transform(states->begin(), states->end(), states->begin(), remove_end);
2081 sort (states->begin(), states->end(), cmp);
2087 Session::possible_states () const
2089 return possible_states(_path);
2093 Session::add_route_group (RouteGroup* g)
2095 _route_groups.push_back (g);
2096 route_group_added (g); /* EMIT SIGNAL */
2101 Session::remove_route_group (RouteGroup& rg)
2103 list<RouteGroup*>::iterator i;
2105 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2106 _route_groups.erase (i);
2109 route_group_removed (); /* EMIT SIGNAL */
2115 Session::route_group_by_name (string name)
2117 list<RouteGroup *>::iterator i;
2119 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2120 if ((*i)->name() == name) {
2128 Session::start_reversible_command (const string& name)
2130 UndoTransaction* trans = new UndoTransaction();
2131 trans->set_name(name);
2136 Session::finish_reversible_command (UndoTransaction& ut)
2139 gettimeofday(&now, 0);
2140 ut.set_timestamp(now);
2145 Session::begin_reversible_command(const string& name)
2147 UndoTransaction* trans = new UndoTransaction();
2148 trans->set_name(name);
2150 if (!_current_trans.empty()) {
2151 _current_trans.top()->add_command (trans);
2153 _current_trans.push(trans);
2158 Session::commit_reversible_command(Command *cmd)
2160 assert(!_current_trans.empty());
2164 _current_trans.top()->add_command(cmd);
2167 if (_current_trans.top()->empty()) {
2168 _current_trans.pop();
2172 gettimeofday(&now, 0);
2173 _current_trans.top()->set_timestamp(now);
2175 _history.add(_current_trans.top());
2176 _current_trans.pop();
2180 accept_all_non_peak_files (const string& path, void */*arg*/)
2182 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2186 accept_all_state_files (const string& path, void */*arg*/)
2188 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2192 Session::find_all_sources (string path, set<string>& result)
2197 if (!tree.read (path)) {
2201 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2206 XMLNodeConstIterator niter;
2208 nlist = node->children();
2212 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2216 if ((prop = (*niter)->property (X_("type"))) == 0) {
2220 DataType type (prop->value());
2222 if ((prop = (*niter)->property (X_("name"))) == 0) {
2226 if (prop->value()[0] == '/') {
2227 /* external file, ignore */
2231 Glib::ustring found_path;
2235 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2236 result.insert (found_path);
2244 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2246 PathScanner scanner;
2247 vector<string*>* state_files;
2249 string this_snapshot_path;
2255 if (ripped[ripped.length()-1] == '/') {
2256 ripped = ripped.substr (0, ripped.length() - 1);
2259 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2261 if (state_files == 0) {
2266 this_snapshot_path = _path;
2267 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2268 this_snapshot_path += statefile_suffix;
2270 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2272 if (exclude_this_snapshot && **i == this_snapshot_path) {
2276 if (find_all_sources (**i, result) < 0) {
2284 struct RegionCounter {
2285 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2286 AudioSourceList::iterator iter;
2287 boost::shared_ptr<Region> region;
2290 RegionCounter() : count (0) {}
2294 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2296 return *AskAboutPlaylistDeletion (p);
2300 Session::cleanup_sources (CleanupReport& rep)
2302 // FIXME: needs adaptation to midi
2304 vector<boost::shared_ptr<Source> > dead_sources;
2305 PathScanner scanner;
2307 vector<space_and_path>::iterator i;
2308 vector<space_and_path>::iterator nexti;
2309 vector<string*>* soundfiles;
2310 vector<string> unused;
2311 set<string> all_sources;
2316 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2318 /* step 1: consider deleting all unused playlists */
2320 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2325 /* step 2: find all un-used sources */
2330 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2332 SourceMap::iterator tmp;
2337 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2341 if (!playlists->source_use_count(i->second) && i->second->length(i->second->timeline_position()) > 0) {
2342 dead_sources.push_back (i->second);
2343 i->second->drop_references ();
2349 /* build a list of all the possible sound directories for the session */
2351 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2356 SessionDirectory sdir ((*i).path);
2357 sound_path += sdir.sound_path().to_string();
2359 if (nexti != session_dirs.end()) {
2366 /* now do the same thing for the files that ended up in the sounds dir(s)
2367 but are not referenced as sources in any snapshot.
2370 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2372 if (soundfiles == 0) {
2376 /* find all sources, but don't use this snapshot because the
2377 state file on disk still references sources we may have already
2381 find_all_sources_across_snapshots (all_sources, true);
2383 /* add our current source list
2386 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2387 boost::shared_ptr<FileSource> fs;
2389 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2390 all_sources.insert (fs->path());
2394 char tmppath1[PATH_MAX+1];
2395 char tmppath2[PATH_MAX+1];
2397 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2402 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2404 realpath(spath.c_str(), tmppath1);
2405 realpath((*i).c_str(), tmppath2);
2407 if (strcmp(tmppath1, tmppath2) == 0) {
2414 unused.push_back (spath);
2418 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2420 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2421 struct stat statbuf;
2423 rep.paths.push_back (*x);
2424 if (stat ((*x).c_str(), &statbuf) == 0) {
2425 rep.space += statbuf.st_size;
2430 /* don't move the file across filesystems, just
2431 stick it in the `dead_sound_dir_name' directory
2432 on whichever filesystem it was already on.
2435 if ((*x).find ("/sounds/") != string::npos) {
2437 /* old school, go up 1 level */
2439 newpath = Glib::path_get_dirname (*x); // "sounds"
2440 newpath = Glib::path_get_dirname (newpath); // "session-name"
2444 /* new school, go up 4 levels */
2446 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2447 newpath = Glib::path_get_dirname (newpath); // "session-name"
2448 newpath = Glib::path_get_dirname (newpath); // "interchange"
2449 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2453 newpath += dead_sound_dir_name;
2455 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2456 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2461 newpath += Glib::path_get_basename ((*x));
2463 if (access (newpath.c_str(), F_OK) == 0) {
2465 /* the new path already exists, try versioning */
2467 char buf[PATH_MAX+1];
2471 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2474 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2475 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2479 if (version == 999) {
2480 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2484 newpath = newpath_v;
2489 /* it doesn't exist, or we can't read it or something */
2493 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2494 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2495 (*x), newpath, strerror (errno))
2500 /* see if there an easy to find peakfile for this file, and remove it.
2503 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2504 peakpath += peakfile_suffix;
2506 if (access (peakpath.c_str(), W_OK) == 0) {
2507 if (::unlink (peakpath.c_str()) != 0) {
2508 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2509 peakpath, _path, strerror (errno))
2511 /* try to back out */
2512 rename (newpath.c_str(), _path.c_str());
2520 /* dump the history list */
2524 /* save state so we don't end up a session file
2525 referring to non-existent sources.
2531 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2537 Session::cleanup_trash_sources (CleanupReport& rep)
2539 // FIXME: needs adaptation for MIDI
2541 vector<space_and_path>::iterator i;
2542 string dead_sound_dir;
2543 struct dirent* dentry;
2544 struct stat statbuf;
2550 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2552 dead_sound_dir = (*i).path;
2553 dead_sound_dir += dead_sound_dir_name;
2555 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2559 while ((dentry = readdir (dead)) != 0) {
2561 /* avoid '.' and '..' */
2563 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2564 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2570 fullpath = dead_sound_dir;
2572 fullpath += dentry->d_name;
2574 if (stat (fullpath.c_str(), &statbuf)) {
2578 if (!S_ISREG (statbuf.st_mode)) {
2582 if (unlink (fullpath.c_str())) {
2583 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2584 fullpath, strerror (errno))
2588 rep.paths.push_back (dentry->d_name);
2589 rep.space += statbuf.st_size;
2600 Session::set_dirty ()
2602 bool was_dirty = dirty();
2604 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2608 DirtyChanged(); /* EMIT SIGNAL */
2614 Session::set_clean ()
2616 bool was_dirty = dirty();
2618 _state_of_the_state = Clean;
2622 DirtyChanged(); /* EMIT SIGNAL */
2627 Session::set_deletion_in_progress ()
2629 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2633 Session::clear_deletion_in_progress ()
2635 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2639 Session::add_controllable (boost::shared_ptr<Controllable> c)
2641 /* this adds a controllable to the list managed by the Session.
2642 this is a subset of those managed by the Controllable class
2643 itself, and represents the only ones whose state will be saved
2644 as part of the session.
2647 Glib::Mutex::Lock lm (controllables_lock);
2648 controllables.insert (c);
2651 struct null_deleter { void operator()(void const *) const {} };
2654 Session::remove_controllable (Controllable* c)
2656 if (_state_of_the_state | Deletion) {
2660 Glib::Mutex::Lock lm (controllables_lock);
2662 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2664 if (x != controllables.end()) {
2665 controllables.erase (x);
2669 boost::shared_ptr<Controllable>
2670 Session::controllable_by_id (const PBD::ID& id)
2672 Glib::Mutex::Lock lm (controllables_lock);
2674 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2675 if ((*i)->id() == id) {
2680 return boost::shared_ptr<Controllable>();
2683 boost::shared_ptr<Controllable>
2684 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2686 boost::shared_ptr<Controllable> c;
2687 boost::shared_ptr<Route> r;
2689 switch (desc.top_level_type()) {
2690 case ControllableDescriptor::NamedRoute:
2692 std::string str = desc.top_level_name();
2693 if (str == "master") {
2695 } else if (str == "control" || str == "listen") {
2698 r = route_by_name (desc.top_level_name());
2703 case ControllableDescriptor::RemoteControlID:
2704 r = route_by_remote_id (desc.rid());
2712 switch (desc.subtype()) {
2713 case ControllableDescriptor::Gain:
2714 c = r->gain_control ();
2716 case ControllableDescriptor::Solo:
2717 c = r->solo_control();
2720 case ControllableDescriptor::Mute:
2721 c = r->mute_control();
2724 case ControllableDescriptor::Recenable:
2726 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2729 c = t->rec_enable_control ();
2734 case ControllableDescriptor::Pan:
2735 /* XXX pan control */
2738 case ControllableDescriptor::Balance:
2739 /* XXX simple pan control */
2742 case ControllableDescriptor::PluginParameter:
2744 uint32_t plugin = desc.target (0);
2745 uint32_t parameter_index = desc.target (1);
2747 /* revert to zero based counting */
2753 if (parameter_index > 0) {
2757 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
2760 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
2761 p->data().control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
2766 case ControllableDescriptor::SendGain:
2768 uint32_t send = desc.target (0);
2770 /* revert to zero-based counting */
2776 boost::shared_ptr<Processor> p = r->nth_send (send);
2779 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
2780 boost::shared_ptr<Amp> a = s->amp();
2783 c = s->amp()->gain_control();
2790 /* relax and return a null pointer */
2798 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2801 Stateful::add_instant_xml (node, _path);
2804 if (write_to_config) {
2805 Config->add_instant_xml (node);
2810 Session::instant_xml (const string& node_name)
2812 return Stateful::instant_xml (node_name, _path);
2816 Session::save_history (string snapshot_name)
2824 if (snapshot_name.empty()) {
2825 snapshot_name = _current_snapshot_name;
2828 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2829 const string backup_filename = history_filename + backup_suffix;
2830 const sys::path xml_path = _session_dir->root_path() / history_filename;
2831 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2833 if (sys::exists (xml_path)) {
2836 sys::rename (xml_path, backup_path);
2838 catch (const sys::filesystem_error& err)
2840 error << _("could not backup old history file, current history not saved") << endmsg;
2845 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2849 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2851 if (!tree.write (xml_path.to_string()))
2853 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2857 sys::remove (xml_path);
2858 sys::rename (backup_path, xml_path);
2860 catch (const sys::filesystem_error& err)
2862 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2863 backup_path.to_string(), err.what()) << endmsg;
2873 Session::restore_history (string snapshot_name)
2877 if (snapshot_name.empty()) {
2878 snapshot_name = _current_snapshot_name;
2881 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
2882 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2884 info << "Loading history from " << xml_path.to_string() << endmsg;
2886 if (!sys::exists (xml_path)) {
2887 info << string_compose (_("%1: no history file \"%2\" for this session."),
2888 _name, xml_path.to_string()) << endmsg;
2892 if (!tree.read (xml_path.to_string())) {
2893 error << string_compose (_("Could not understand session history file \"%1\""),
2894 xml_path.to_string()) << endmsg;
2901 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2904 UndoTransaction* ut = new UndoTransaction ();
2907 ut->set_name(t->property("name")->value());
2908 stringstream ss(t->property("tv-sec")->value());
2910 ss.str(t->property("tv-usec")->value());
2912 ut->set_timestamp(tv);
2914 for (XMLNodeConstIterator child_it = t->children().begin();
2915 child_it != t->children().end(); child_it++)
2917 XMLNode *n = *child_it;
2920 if (n->name() == "MementoCommand" ||
2921 n->name() == "MementoUndoCommand" ||
2922 n->name() == "MementoRedoCommand") {
2924 if ((c = memento_command_factory(n))) {
2928 } else if (n->name() == "DeltaCommand") {
2929 PBD::ID id(n->property("midi-source")->value());
2930 boost::shared_ptr<MidiSource> midi_source =
2931 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2933 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
2935 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
2938 } else if (n->name() == "DiffCommand") {
2939 PBD::ID id(n->property("midi-source")->value());
2940 boost::shared_ptr<MidiSource> midi_source =
2941 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2943 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
2945 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
2949 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2960 Session::config_changed (std::string p, bool ours)
2966 if (p == "seamless-loop") {
2968 } else if (p == "rf-speed") {
2970 } else if (p == "auto-loop") {
2972 } else if (p == "auto-input") {
2974 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2975 /* auto-input only makes a difference if we're rolling */
2977 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2979 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2980 if ((*i)->record_enabled ()) {
2981 (*i)->monitor_input (!config.get_auto_input());
2986 } else if (p == "punch-in") {
2990 if ((location = _locations.auto_punch_location()) != 0) {
2992 if (config.get_punch_in ()) {
2993 replace_event (SessionEvent::PunchIn, location->start());
2995 remove_event (location->start(), SessionEvent::PunchIn);
2999 } else if (p == "punch-out") {
3003 if ((location = _locations.auto_punch_location()) != 0) {
3005 if (config.get_punch_out()) {
3006 replace_event (SessionEvent::PunchOut, location->end());
3008 clear_events (SessionEvent::PunchOut);
3012 } else if (p == "edit-mode") {
3014 Glib::Mutex::Lock lm (playlists->lock);
3016 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3017 (*i)->set_edit_mode (Config->get_edit_mode ());
3020 } else if (p == "use-video-sync") {
3022 waiting_for_sync_offset = config.get_use_video_sync();
3024 } else if (p == "mmc-control") {
3026 //poke_midi_thread ();
3028 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3031 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3034 } else if (p == "mmc-send-id") {
3037 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3040 } else if (p == "midi-control") {
3042 //poke_midi_thread ();
3044 } else if (p == "raid-path") {
3046 setup_raid_path (config.get_raid_path());
3048 } else if (p == "timecode-format") {
3052 } else if (p == "video-pullup") {
3056 } else if (p == "seamless-loop") {
3058 if (play_loop && transport_rolling()) {
3059 // to reset diskstreams etc
3060 request_play_loop (true);
3063 } else if (p == "rf-speed") {
3065 cumulative_rf_motion = 0;
3068 } else if (p == "click-sound") {
3070 setup_click_sounds (1);
3072 } else if (p == "click-emphasis-sound") {
3074 setup_click_sounds (-1);
3076 } else if (p == "clicking") {
3078 if (Config->get_clicking()) {
3079 if (_click_io && click_data) { // don't require emphasis data
3086 } else if (p == "send-mtc") {
3088 /* only set the internal flag if we have
3092 if (_mtc_port != 0) {
3093 session_send_mtc = Config->get_send_mtc();
3094 if (session_send_mtc) {
3095 /* mark us ready to send */
3096 next_quarter_frame_to_send = 0;
3099 session_send_mtc = false;
3102 } else if (p == "send-mmc") {
3104 /* only set the internal flag if we have
3108 if (_mmc_port != 0) {
3109 session_send_mmc = Config->get_send_mmc();
3112 session_send_mmc = false;
3115 } else if (p == "midi-feedback") {
3117 /* only set the internal flag if we have
3121 if (_mtc_port != 0) {
3122 session_midi_feedback = Config->get_midi_feedback();
3125 } else if (p == "jack-time-master") {
3127 engine().reset_timebase ();
3129 } else if (p == "native-file-header-format") {
3131 if (!first_file_header_format_reset) {
3132 reset_native_file_format ();
3135 first_file_header_format_reset = false;
3137 } else if (p == "native-file-data-format") {
3139 if (!first_file_data_format_reset) {
3140 reset_native_file_format ();
3143 first_file_data_format_reset = false;
3145 } else if (p == "external-sync") {
3146 if (!config.get_external_sync()) {
3147 drop_sync_source ();
3149 switch_to_sync_source (config.get_sync_source());
3151 } else if (p == "remote-model") {
3152 set_remote_control_ids ();
3153 } else if (p == "denormal-model") {
3155 } else if (p == "history-depth") {
3156 set_history_depth (Config->get_history_depth());
3157 } else if (p == "sync-all-route-ordering") {
3158 sync_order_keys ("session");
3159 } else if (p == "initial-program-change") {
3161 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3164 buf[0] = MIDI::program; // channel zero by default
3165 buf[1] = (Config->get_initial_program_change() & 0x7f);
3167 _mmc_port->midimsg (buf, sizeof (buf), 0);
3169 } else if (p == "initial-program-change") {
3171 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3172 MIDI::byte* buf = new MIDI::byte[2];
3174 buf[0] = MIDI::program; // channel zero by default
3175 buf[1] = (Config->get_initial_program_change() & 0x7f);
3176 // deliver_midi (_mmc_port, buf, 2);
3178 } else if (p == "solo-mute-override") {
3179 // catch_up_on_solo_mute_override ();
3180 } else if (p == "listen-position") {
3181 listen_position_changed ();
3182 } else if (p == "solo-control-is-listen-control") {
3183 solo_control_mode_changed ();
3191 Session::set_history_depth (uint32_t d)
3193 _history.set_depth (d);