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.
20 #define __STDC_FORMAT_MACROS 1
28 #include <sigc++/bind.h>
30 #include <cstdio> /* snprintf(3) ... grrr */
45 #include <sys/param.h>
46 #include <sys/mount.h>
50 #include <glibmm/thread.h>
52 #include "midi++/mmc.h"
53 #include "midi++/port.h"
55 #include "pbd/error.h"
56 #include "pbd/pathscanner.h"
57 #include "pbd/pthread_utils.h"
58 #include "pbd/search_path.h"
59 #include "pbd/stacktrace.h"
61 #include "ardour/audioengine.h"
62 #include "ardour/configuration.h"
63 #include "ardour/session.h"
64 #include "ardour/session_directory.h"
65 #include "ardour/session_utils.h"
66 #include "ardour/session_state_utils.h"
67 #include "ardour/session_metadata.h"
68 #include "ardour/buffer.h"
69 #include "ardour/audio_diskstream.h"
70 #include "ardour/midi_diskstream.h"
71 #include "ardour/utils.h"
72 #include "ardour/audioplaylist.h"
73 #include "ardour/midi_playlist.h"
74 #include "ardour/smf_source.h"
75 #include "ardour/audiofilesource.h"
76 #include "ardour/silentfilesource.h"
77 #include "ardour/sndfilesource.h"
78 #include "ardour/midi_source.h"
79 #include "ardour/sndfile_helpers.h"
80 #include "ardour/auditioner.h"
81 #include "ardour/io_processor.h"
82 #include "ardour/send.h"
83 #include "ardour/processor.h"
84 #include "ardour/user_bundle.h"
85 #include "ardour/slave.h"
86 #include "ardour/tempo.h"
87 #include "ardour/audio_track.h"
88 #include "ardour/midi_track.h"
89 #include "ardour/midi_patch_manager.h"
90 #include "ardour/cycle_timer.h"
91 #include "ardour/utils.h"
92 #include "ardour/named_selection.h"
93 #include "ardour/version.h"
94 #include "ardour/location.h"
95 #include "ardour/audioregion.h"
96 #include "ardour/midi_region.h"
97 #include "ardour/crossfade.h"
98 #include "ardour/control_protocol_manager.h"
99 #include "ardour/region_factory.h"
100 #include "ardour/source_factory.h"
101 #include "ardour/playlist_factory.h"
102 #include "ardour/filename_extensions.h"
103 #include "ardour/directory_names.h"
104 #include "ardour/template_utils.h"
105 #include "ardour/ticker.h"
106 #include "ardour/route_group.h"
108 #include "control_protocol/control_protocol.h"
114 using namespace ARDOUR;
118 Session::first_stage_init (string fullpath, string snapshot_name)
120 if (fullpath.length() == 0) {
122 throw failed_constructor();
125 char buf[PATH_MAX+1];
126 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
127 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
129 throw failed_constructor();
134 if (_path[_path.length()-1] != '/') {
138 /* these two are just provisional settings. set_state()
139 will likely override them.
142 _name = _current_snapshot_name = snapshot_name;
144 set_history_depth (Config->get_history_depth());
146 _current_frame_rate = _engine.frame_rate ();
147 _nominal_frame_rate = _current_frame_rate;
148 _base_frame_rate = _current_frame_rate;
150 _tempo_map = new TempoMap (_current_frame_rate);
151 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
154 _non_soloed_outs_muted = false;
155 g_atomic_int_set (&processing_prohibited, 0);
156 _transport_speed = 0;
157 _last_transport_speed = 0;
158 _target_transport_speed = 0;
159 auto_play_legal = false;
160 transport_sub_state = 0;
161 _transport_frame = 0;
162 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
163 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
164 g_atomic_int_set (&_record_status, Disabled);
165 loop_changing = false;
168 _last_roll_location = 0;
169 _last_record_location = 0;
170 pending_locate_frame = 0;
171 pending_locate_roll = false;
172 pending_locate_flush = false;
173 audio_dstream_buffer_size = 0;
174 midi_dstream_buffer_size = 0;
175 state_was_pending = false;
177 outbound_mtc_smpte_frame = 0;
178 next_quarter_frame_to_send = -1;
179 current_block_size = 0;
180 solo_update_disabled = false;
181 _have_captured = false;
182 _worst_output_latency = 0;
183 _worst_input_latency = 0;
184 _worst_track_latency = 0;
185 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
188 session_send_mmc = false;
189 session_send_mtc = false;
190 post_transport_work = PostTransportWork (0);
191 g_atomic_int_set (&butler_should_do_transport_work, 0);
192 g_atomic_int_set (&_playback_load, 100);
193 g_atomic_int_set (&_capture_load, 100);
194 g_atomic_int_set (&_playback_load_min, 100);
195 g_atomic_int_set (&_capture_load_min, 100);
198 _exporting_realtime = false;
199 _gain_automation_buffer = 0;
200 _pan_automation_buffer = 0;
202 pending_abort = false;
203 destructive_index = 0;
204 first_file_data_format_reset = true;
205 first_file_header_format_reset = true;
206 butler_thread = (pthread_t) 0;
207 //midi_thread = (pthread_t) 0;
209 AudioDiskstream::allocate_working_buffers();
211 /* default short fade = 15ms */
213 Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
214 SndFileSource::setup_standard_crossfades (*this, frame_rate());
216 last_mmc_step.tv_sec = 0;
217 last_mmc_step.tv_usec = 0;
220 /* click sounds are unset by default, which causes us to internal
221 waveforms for clicks.
225 click_emphasis_length = 0;
228 process_function = &Session::process_with_events;
230 if (config.get_use_video_sync()) {
231 waiting_for_sync_offset = true;
233 waiting_for_sync_offset = false;
238 _smpte_offset_negative = true;
239 last_smpte_valid = false;
243 last_rr_session_dir = session_dirs.begin();
244 refresh_disk_space ();
246 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
250 average_slave_delta = 1800; // !!! why 1800 ????
251 have_first_delta_accumulator = false;
252 delta_accumulator_cnt = 0;
253 slave_state = Stopped;
255 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
257 /* These are all static "per-class" signals */
259 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
260 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
261 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
262 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
263 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
264 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
266 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
268 IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
270 /* stop IO objects from doing stuff until we're ready for them */
272 Delivery::disable_panners ();
273 IO::disable_connecting ();
277 Session::second_stage_init (bool new_session)
279 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
282 if (load_state (_current_snapshot_name)) {
285 remove_empty_sounds ();
288 if (start_butler_thread()) {
292 if (start_midi_thread ()) {
296 // set_state() will call setup_raid_path(), but if it's a new session we need
297 // to call setup_raid_path() here.
300 if (set_state (*state_tree->root())) {
304 setup_raid_path(_path);
307 /* we can't save till after ::when_engine_running() is called,
308 because otherwise we save state with no connections made.
309 therefore, we reset _state_of_the_state because ::set_state()
310 will have cleared it.
312 we also have to include Loading so that any events that get
313 generated between here and the end of ::when_engine_running()
314 will be processed directly rather than queued.
317 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
320 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
321 _locations.added.connect (mem_fun (this, &Session::locations_added));
322 setup_click_sounds (0);
323 setup_midi_control ();
325 /* Pay attention ... */
327 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
328 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
331 when_engine_running();
334 /* handle this one in a different way than all others, so that its clear what happened */
336 catch (AudioEngine::PortRegistrationFailure& err) {
337 error << err.what() << endmsg;
345 BootMessage (_("Reset Remote Controls"));
347 send_full_time_code (0);
348 _engine.transport_locate (0);
349 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
350 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
352 MidiClockTicker::instance().set_session(*this);
353 MIDI::Name::MidiPatchManager::instance().set_session(*this);
355 /* initial program change will be delivered later; see ::config_changed() */
357 BootMessage (_("Reset Control Protocols"));
359 ControlProtocolManager::instance().set_session (*this);
361 config.set_end_marker_is_free (new_session);
363 _state_of_the_state = Clean;
365 DirtyChanged (); /* EMIT SIGNAL */
367 if (state_was_pending) {
368 save_state (_current_snapshot_name);
369 remove_pending_capture_state ();
370 state_was_pending = false;
373 BootMessage (_("Session loading complete"));
379 Session::raid_path () const
381 SearchPath raid_search_path;
383 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
384 raid_search_path += sys::path((*i).path);
387 return raid_search_path.to_string ();
391 Session::setup_raid_path (string path)
400 session_dirs.clear ();
402 SearchPath search_path(path);
403 SearchPath sound_search_path;
404 SearchPath midi_search_path;
406 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
407 sp.path = (*i).to_string ();
408 sp.blocks = 0; // not needed
409 session_dirs.push_back (sp);
411 SessionDirectory sdir(sp.path);
413 sound_search_path += sdir.sound_path ();
414 midi_search_path += sdir.midi_path ();
417 // set the search path for each data type
418 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
419 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
421 // reset the round-robin soundfile path thingie
422 last_rr_session_dir = session_dirs.begin();
426 Session::ensure_subdirs ()
430 dir = session_directory().peak_path().to_string();
432 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
433 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
437 dir = session_directory().sound_path().to_string();
439 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
440 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
444 dir = session_directory().midi_path().to_string();
446 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
447 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
451 dir = session_directory().dead_sound_path().to_string();
453 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
454 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
458 dir = session_directory().export_path().to_string();
460 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
461 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
465 dir = analysis_dir ();
467 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
468 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
476 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
479 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
480 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
484 if (ensure_subdirs ()) {
488 /* check new_session so we don't overwrite an existing one */
490 if (!mix_template.empty()) {
491 std::string in_path = mix_template;
493 ifstream in(in_path.c_str());
496 string out_path = _path;
498 out_path += statefile_suffix;
500 ofstream out(out_path.c_str());
505 // okay, session is set up. Treat like normal saved
506 // session from now on.
512 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
518 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
525 /* Instantiate metadata */
527 _metadata = new SessionMetadata ();
529 /* set initial start + end point */
531 start_location->set_end (0);
532 _locations.add (start_location);
534 end_location->set_end (initial_length);
535 _locations.add (end_location);
537 _state_of_the_state = Clean;
546 Session::load_diskstreams (const XMLNode& node)
549 XMLNodeConstIterator citer;
551 clist = node.children();
553 for (citer = clist.begin(); citer != clist.end(); ++citer) {
556 /* diskstreams added automatically by DiskstreamCreated handler */
557 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
558 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
559 add_diskstream (dstream);
560 } else if ((*citer)->name() == "MidiDiskstream") {
561 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
562 add_diskstream (dstream);
564 error << _("Session: unknown diskstream type in XML") << endmsg;
568 catch (failed_constructor& err) {
569 error << _("Session: could not load diskstream via XML state") << endmsg;
578 Session::maybe_write_autosave()
580 if (dirty() && record_status() != Recording) {
581 save_state("", true);
586 Session::remove_pending_capture_state ()
588 sys::path pending_state_file_path(_session_dir->root_path());
590 pending_state_file_path /= _current_snapshot_name + pending_suffix;
594 sys::remove (pending_state_file_path);
596 catch(sys::filesystem_error& ex)
598 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
599 pending_state_file_path.to_string(), ex.what()) << endmsg;
603 /** Rename a state file.
604 * @param snapshot_name Snapshot name.
607 Session::rename_state (string old_name, string new_name)
609 if (old_name == _current_snapshot_name || old_name == _name) {
610 /* refuse to rename the current snapshot or the "main" one */
614 const string old_xml_filename = old_name + statefile_suffix;
615 const string new_xml_filename = new_name + statefile_suffix;
617 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
618 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
622 sys::rename (old_xml_path, new_xml_path);
624 catch (const sys::filesystem_error& err)
626 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
627 old_name, new_name, err.what()) << endmsg;
631 /** Remove a state file.
632 * @param snapshot_name Snapshot name.
635 Session::remove_state (string snapshot_name)
637 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
638 // refuse to remove the current snapshot or the "main" one
642 sys::path xml_path(_session_dir->root_path());
644 xml_path /= snapshot_name + statefile_suffix;
646 if (!create_backup_file (xml_path)) {
647 // don't remove it if a backup can't be made
648 // create_backup_file will log the error.
653 sys::remove (xml_path);
657 Session::save_state (string snapshot_name, bool pending)
660 sys::path xml_path(_session_dir->root_path());
662 if (_state_of_the_state & CannotSave) {
666 if (!_engine.connected ()) {
667 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
672 /* tell sources we're saving first, in case they write out to a new file
673 * which should be saved with the state rather than the old one */
674 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
675 i->second->session_saved();
677 tree.set_root (&get_state());
679 if (snapshot_name.empty()) {
680 snapshot_name = _current_snapshot_name;
685 /* proper save: use statefile_suffix (.ardour in English) */
687 xml_path /= snapshot_name + statefile_suffix;
689 /* make a backup copy of the old file */
691 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
692 // create_backup_file will log the error
698 /* pending save: use pending_suffix (.pending in English) */
699 xml_path /= snapshot_name + pending_suffix;
702 sys::path tmp_path(_session_dir->root_path());
704 tmp_path /= snapshot_name + temp_suffix;
706 // cerr << "actually writing state to " << xml_path.to_string() << endl;
708 if (!tree.write (tmp_path.to_string())) {
709 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
710 sys::remove (tmp_path);
715 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
716 error << string_compose (_("could not rename temporary session file %1 to %2"),
717 tmp_path.to_string(), xml_path.to_string()) << endmsg;
718 sys::remove (tmp_path);
725 save_history (snapshot_name);
727 bool was_dirty = dirty();
729 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
732 DirtyChanged (); /* EMIT SIGNAL */
735 StateSaved (snapshot_name); /* EMIT SIGNAL */
742 Session::restore_state (string snapshot_name)
744 if (load_state (snapshot_name) == 0) {
745 set_state (*state_tree->root());
752 Session::load_state (string snapshot_name)
757 state_was_pending = false;
759 /* check for leftover pending state from a crashed capture attempt */
761 sys::path xmlpath(_session_dir->root_path());
762 xmlpath /= snapshot_name + pending_suffix;
764 if (sys::exists (xmlpath)) {
766 /* there is pending state from a crashed capture attempt */
768 if (AskAboutPendingState()) {
769 state_was_pending = true;
773 if (!state_was_pending) {
774 xmlpath = _session_dir->root_path();
775 xmlpath /= snapshot_name + statefile_suffix;
778 if (!sys::exists (xmlpath)) {
779 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
783 state_tree = new XMLTree;
787 if (!state_tree->read (xmlpath.to_string())) {
788 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
794 XMLNode& root (*state_tree->root());
796 if (root.name() != X_("Session")) {
797 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
803 const XMLProperty* prop;
804 bool is_old = false; // session is _very_ old (pre-2.0)
806 if ((prop = root.property ("version")) == 0) {
807 /* no version implies very old version of Ardour */
811 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
812 if (major_version < 2) {
819 sys::path backup_path(_session_dir->root_path());
821 backup_path /= snapshot_name + "-1" + statefile_suffix;
823 // only create a backup once
824 if (sys::exists (backup_path)) {
828 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
829 xmlpath.to_string(), backup_path.to_string())
834 sys::copy_file (xmlpath, backup_path);
836 catch(sys::filesystem_error& ex)
838 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
839 xmlpath.to_string(), ex.what())
849 Session::load_options (const XMLNode& node)
851 LocaleGuard lg (X_("POSIX"));
853 config.set_variables (node);
855 /* now reset MIDI ports because the session can have its own
871 Session::get_template()
873 /* if we don't disable rec-enable, diskstreams
874 will believe they need to store their capture
875 sources in their state node.
878 disable_record (false);
884 Session::state(bool full_state)
886 XMLNode* node = new XMLNode("Session");
889 // store libardour version, just in case
891 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
892 node->add_property("version", string(buf));
894 /* store configuration settings */
898 node->add_property ("name", _name);
899 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
900 node->add_property ("sample-rate", buf);
902 if (session_dirs.size() > 1) {
906 vector<space_and_path>::iterator i = session_dirs.begin();
907 vector<space_and_path>::iterator next;
909 ++i; /* skip the first one */
913 while (i != session_dirs.end()) {
917 if (next != session_dirs.end()) {
927 child = node->add_child ("Path");
928 child->add_content (p);
932 /* save the ID counter */
934 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
935 node->add_property ("id-counter", buf);
937 /* various options */
939 node->add_child_nocopy (config.get_variables ());
941 node->add_child_nocopy (_metadata->get_state());
943 child = node->add_child ("Sources");
946 Glib::Mutex::Lock sl (source_lock);
948 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
950 /* Don't save information about non-destructive file sources that are empty */
951 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
953 boost::shared_ptr<AudioFileSource> fs;
954 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
955 if (!fs->destructive()) {
956 if (fs->length(fs->timeline_position()) == 0) {
962 child->add_child_nocopy (siter->second->get_state());
966 child = node->add_child ("Regions");
969 Glib::Mutex::Lock rl (region_lock);
971 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
973 /* only store regions not attached to playlists */
975 if (i->second->playlist() == 0) {
976 child->add_child_nocopy (i->second->state (true));
981 child = node->add_child ("DiskStreams");
984 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
985 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
986 if (!(*i)->hidden()) {
987 child->add_child_nocopy ((*i)->get_state());
993 node->add_child_nocopy (_locations.get_state());
995 // for a template, just create a new Locations, populate it
996 // with the default start and end, and get the state for that.
998 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
999 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1002 end->set_end(compute_initial_length());
1004 node->add_child_nocopy (loc.get_state());
1007 child = node->add_child ("Bundles");
1009 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1010 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1011 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1013 child->add_child_nocopy (b->get_state());
1018 child = node->add_child ("Routes");
1020 boost::shared_ptr<RouteList> r = routes.reader ();
1022 RoutePublicOrderSorter cmp;
1023 RouteList public_order (*r);
1024 public_order.sort (cmp);
1026 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1027 if (!(*i)->is_hidden()) {
1029 child->add_child_nocopy ((*i)->get_state());
1031 child->add_child_nocopy ((*i)->get_template());
1038 child = node->add_child ("EditGroups");
1039 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1040 child->add_child_nocopy ((*i)->get_state());
1043 child = node->add_child ("MixGroups");
1044 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1045 child->add_child_nocopy ((*i)->get_state());
1048 child = node->add_child ("Playlists");
1049 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1050 if (!(*i)->hidden()) {
1051 if (!(*i)->empty()) {
1053 child->add_child_nocopy ((*i)->get_state());
1055 child->add_child_nocopy ((*i)->get_template());
1061 child = node->add_child ("UnusedPlaylists");
1062 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1063 if (!(*i)->hidden()) {
1064 if (!(*i)->empty()) {
1066 child->add_child_nocopy ((*i)->get_state());
1068 child->add_child_nocopy ((*i)->get_template());
1076 child = node->add_child ("Click");
1077 child->add_child_nocopy (_click_io->state (full_state));
1081 child = node->add_child ("NamedSelections");
1082 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1084 child->add_child_nocopy ((*i)->get_state());
1089 node->add_child_nocopy (_tempo_map->get_state());
1091 node->add_child_nocopy (get_control_protocol_state());
1094 node->add_child_copy (*_extra_xml);
1101 Session::get_control_protocol_state ()
1103 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1104 return cpm.get_state();
1108 Session::set_state (const XMLNode& node)
1112 const XMLProperty* prop;
1115 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1117 if (node.name() != X_("Session")){
1118 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1122 if ((prop = node.property ("name")) != 0) {
1123 _name = prop->value ();
1126 if ((prop = node.property (X_("sample-rate"))) != 0) {
1128 _nominal_frame_rate = atoi (prop->value());
1130 if (_nominal_frame_rate != _current_frame_rate) {
1131 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1137 setup_raid_path(_session_dir->root_path().to_string());
1139 if ((prop = node.property (X_("id-counter"))) != 0) {
1141 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1142 ID::init_counter (x);
1144 /* old sessions used a timebased counter, so fake
1145 the startup ID counter based on a standard
1150 ID::init_counter (now);
1154 IO::disable_connecting ();
1156 /* Object loading order:
1161 MIDI Control // relies on data from Options/Config
1175 if ((child = find_named_node (node, "Extra")) != 0) {
1176 _extra_xml = new XMLNode (*child);
1179 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1180 load_options (*child);
1181 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1182 load_options (*child);
1184 error << _("Session: XML state has no options section") << endmsg;
1187 if (use_config_midi_ports ()) {
1190 if ((child = find_named_node (node, "Metadata")) == 0) {
1191 warning << _("Session: XML state has no metadata section (2.0 session?)") << endmsg;
1192 } else if (_metadata->set_state (*child)) {
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)) {
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 (load_playlists (*child)) {
1250 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1252 } else if (load_unused_playlists (*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 ((child = find_named_node (node, "Bundles")) == 0) {
1270 warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg;
1273 /* We can't load Bundles yet as they need to be able
1274 to convert from port names to Port objects, which can't happen until
1276 _bundle_xml_node = new XMLNode (*child);
1279 if ((child = find_named_node (node, "EditGroups")) == 0) {
1280 error << _("Session: XML state has no edit groups section") << endmsg;
1282 } else if (load_edit_groups (*child)) {
1286 if ((child = find_named_node (node, "MixGroups")) == 0) {
1287 error << _("Session: XML state has no mix groups section") << endmsg;
1289 } else if (load_mix_groups (*child)) {
1293 if ((child = find_named_node (node, "TempoMap")) == 0) {
1294 error << _("Session: XML state has no Tempo Map section") << endmsg;
1296 } else if (_tempo_map->set_state (*child)) {
1300 if ((child = find_named_node (node, "Routes")) == 0) {
1301 error << _("Session: XML state has no routes section") << endmsg;
1303 } else if (load_routes (*child)) {
1307 if ((child = find_named_node (node, "Click")) == 0) {
1308 warning << _("Session: XML state has no click section") << endmsg;
1309 } else if (_click_io) {
1310 _click_io->set_state (*child);
1313 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1314 ControlProtocolManager::instance().set_protocol_states (*child);
1317 /* here beginneth the second phase ... */
1319 StateReady (); /* EMIT SIGNAL */
1328 Session::load_routes (const XMLNode& node)
1331 XMLNodeConstIterator niter;
1332 RouteList new_routes;
1334 nlist = node.children();
1338 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1340 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1343 error << _("Session: cannot create Route from XML description.") << endmsg;
1347 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1349 new_routes.push_back (route);
1352 add_routes (new_routes, false);
1357 boost::shared_ptr<Route>
1358 Session::XMLRouteFactory (const XMLNode& node)
1360 if (node.name() != "Route") {
1361 return boost::shared_ptr<Route> ((Route*) 0);
1364 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1366 DataType type = DataType::AUDIO;
1367 const XMLProperty* prop = node.property("default-type");
1370 type = DataType(prop->value());
1373 assert(type != DataType::NIL);
1375 if (has_diskstream) {
1376 if (type == DataType::AUDIO) {
1377 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1380 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1384 boost::shared_ptr<Route> ret (new Route (*this, node));
1390 Session::load_regions (const XMLNode& node)
1393 XMLNodeConstIterator niter;
1394 boost::shared_ptr<Region> region;
1396 nlist = node.children();
1400 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1401 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1402 error << _("Session: cannot create Region from XML description.");
1403 const XMLProperty *name = (**niter).property("name");
1406 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1416 boost::shared_ptr<Region>
1417 Session::XMLRegionFactory (const XMLNode& node, bool full)
1419 const XMLProperty* type = node.property("type");
1423 if ( !type || type->value() == "audio" ) {
1425 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1427 } else if (type->value() == "midi") {
1429 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1433 } catch (failed_constructor& err) {
1434 return boost::shared_ptr<Region> ();
1437 return boost::shared_ptr<Region> ();
1440 boost::shared_ptr<AudioRegion>
1441 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1443 const XMLProperty* prop;
1444 boost::shared_ptr<Source> source;
1445 boost::shared_ptr<AudioSource> as;
1447 SourceList master_sources;
1448 uint32_t nchans = 1;
1451 if (node.name() != X_("Region")) {
1452 return boost::shared_ptr<AudioRegion>();
1455 if ((prop = node.property (X_("channels"))) != 0) {
1456 nchans = atoi (prop->value().c_str());
1459 if ((prop = node.property ("name")) == 0) {
1460 cerr << "no name for this region\n";
1464 if ((prop = node.property (X_("source-0"))) == 0) {
1465 if ((prop = node.property ("source")) == 0) {
1466 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1467 return boost::shared_ptr<AudioRegion>();
1471 PBD::ID s_id (prop->value());
1473 if ((source = source_by_id (s_id)) == 0) {
1474 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1475 return boost::shared_ptr<AudioRegion>();
1478 as = boost::dynamic_pointer_cast<AudioSource>(source);
1480 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1481 return boost::shared_ptr<AudioRegion>();
1484 sources.push_back (as);
1486 /* pickup other channels */
1488 for (uint32_t n=1; n < nchans; ++n) {
1489 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1490 if ((prop = node.property (buf)) != 0) {
1492 PBD::ID id2 (prop->value());
1494 if ((source = source_by_id (id2)) == 0) {
1495 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1496 return boost::shared_ptr<AudioRegion>();
1499 as = boost::dynamic_pointer_cast<AudioSource>(source);
1501 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1502 return boost::shared_ptr<AudioRegion>();
1504 sources.push_back (as);
1508 for (uint32_t n = 0; n < nchans; ++n) {
1509 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1510 if ((prop = node.property (buf)) != 0) {
1512 PBD::ID id2 (prop->value());
1514 if ((source = source_by_id (id2)) == 0) {
1515 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1516 return boost::shared_ptr<AudioRegion>();
1519 as = boost::dynamic_pointer_cast<AudioSource>(source);
1521 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1522 return boost::shared_ptr<AudioRegion>();
1524 master_sources.push_back (as);
1529 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1531 /* a final detail: this is the one and only place that we know how long missing files are */
1533 if (region->whole_file()) {
1534 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1535 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1537 sfp->set_length (region->length());
1542 if (!master_sources.empty()) {
1543 if (master_sources.size() != nchans) {
1544 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1546 region->set_master_sources (master_sources);
1554 catch (failed_constructor& err) {
1555 return boost::shared_ptr<AudioRegion>();
1559 boost::shared_ptr<MidiRegion>
1560 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1562 const XMLProperty* prop;
1563 boost::shared_ptr<Source> source;
1564 boost::shared_ptr<MidiSource> ms;
1566 uint32_t nchans = 1;
1568 if (node.name() != X_("Region")) {
1569 return boost::shared_ptr<MidiRegion>();
1572 if ((prop = node.property (X_("channels"))) != 0) {
1573 nchans = atoi (prop->value().c_str());
1576 if ((prop = node.property ("name")) == 0) {
1577 cerr << "no name for this region\n";
1581 // Multiple midi channels? that's just crazy talk
1582 assert(nchans == 1);
1584 if ((prop = node.property (X_("source-0"))) == 0) {
1585 if ((prop = node.property ("source")) == 0) {
1586 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1587 return boost::shared_ptr<MidiRegion>();
1591 PBD::ID s_id (prop->value());
1593 if ((source = source_by_id (s_id)) == 0) {
1594 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1595 return boost::shared_ptr<MidiRegion>();
1598 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1600 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1601 return boost::shared_ptr<MidiRegion>();
1604 sources.push_back (ms);
1607 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1608 /* a final detail: this is the one and only place that we know how long missing files are */
1610 if (region->whole_file()) {
1611 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1612 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1614 sfp->set_length (region->length());
1622 catch (failed_constructor& err) {
1623 return boost::shared_ptr<MidiRegion>();
1628 Session::get_sources_as_xml ()
1631 XMLNode* node = new XMLNode (X_("Sources"));
1632 Glib::Mutex::Lock lm (source_lock);
1634 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1635 node->add_child_nocopy (i->second->get_state());
1642 Session::path_from_region_name (DataType type, string name, string identifier)
1644 char buf[PATH_MAX+1];
1646 SessionDirectory sdir(get_best_session_directory_for_new_source());
1647 sys::path source_dir = ((type == DataType::AUDIO)
1648 ? sdir.sound_path() : sdir.midi_path());
1650 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1652 for (n = 0; n < 999999; ++n) {
1653 if (identifier.length()) {
1654 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1655 identifier.c_str(), n, ext.c_str());
1657 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1661 sys::path source_path = source_dir / buf;
1663 if (!sys::exists (source_path)) {
1664 return source_path.to_string();
1668 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1677 Session::load_sources (const XMLNode& node)
1680 XMLNodeConstIterator niter;
1681 boost::shared_ptr<Source> source;
1683 nlist = node.children();
1687 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1689 if ((source = XMLSourceFactory (**niter)) == 0) {
1690 error << _("Session: cannot create Source from XML description.") << endmsg;
1692 } catch (MissingSource& err) {
1693 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1694 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1701 boost::shared_ptr<Source>
1702 Session::XMLSourceFactory (const XMLNode& node)
1704 if (node.name() != "Source") {
1705 return boost::shared_ptr<Source>();
1709 /* note: do peak building in another thread when loading session state */
1710 return SourceFactory::create (*this, node, true);
1713 catch (failed_constructor& err) {
1714 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1715 return boost::shared_ptr<Source>();
1720 Session::save_template (string template_name)
1724 if (_state_of_the_state & CannotSave) {
1728 sys::path user_template_dir(user_template_directory());
1732 sys::create_directories (user_template_dir);
1734 catch(sys::filesystem_error& ex)
1736 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1737 user_template_dir.to_string(), ex.what()) << endmsg;
1741 tree.set_root (&get_template());
1743 sys::path template_file_path(user_template_dir);
1744 template_file_path /= template_name + template_suffix;
1746 if (sys::exists (template_file_path))
1748 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1749 template_file_path.to_string()) << endmsg;
1753 if (!tree.write (template_file_path.to_string())) {
1754 error << _("mix template not saved") << endmsg;
1762 Session::rename_template (string old_name, string new_name)
1764 sys::path old_path (user_template_directory());
1765 old_path /= old_name + template_suffix;
1767 sys::path new_path(user_template_directory());
1768 new_path /= new_name + template_suffix;
1770 if (sys::exists (new_path)) {
1771 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1772 new_path.to_string()) << endmsg;
1777 sys::rename (old_path, new_path);
1785 Session::delete_template (string name)
1787 sys::path path = user_template_directory();
1788 path /= name + template_suffix;
1799 Session::refresh_disk_space ()
1802 struct statfs statfsbuf;
1803 vector<space_and_path>::iterator i;
1804 Glib::Mutex::Lock lm (space_lock);
1807 /* get freespace on every FS that is part of the session path */
1809 _total_free_4k_blocks = 0;
1811 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1812 statfs ((*i).path.c_str(), &statfsbuf);
1814 scale = statfsbuf.f_bsize/4096.0;
1816 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1817 _total_free_4k_blocks += (*i).blocks;
1823 Session::get_best_session_directory_for_new_source ()
1825 vector<space_and_path>::iterator i;
1826 string result = _session_dir->root_path().to_string();
1828 /* handle common case without system calls */
1830 if (session_dirs.size() == 1) {
1834 /* OK, here's the algorithm we're following here:
1836 We want to select which directory to use for
1837 the next file source to be created. Ideally,
1838 we'd like to use a round-robin process so as to
1839 get maximum performance benefits from splitting
1840 the files across multiple disks.
1842 However, in situations without much diskspace, an
1843 RR approach may end up filling up a filesystem
1844 with new files while others still have space.
1845 Its therefore important to pay some attention to
1846 the freespace in the filesystem holding each
1847 directory as well. However, if we did that by
1848 itself, we'd keep creating new files in the file
1849 system with the most space until it was as full
1850 as all others, thus negating any performance
1851 benefits of this RAID-1 like approach.
1853 So, we use a user-configurable space threshold. If
1854 there are at least 2 filesystems with more than this
1855 much space available, we use RR selection between them.
1856 If not, then we pick the filesystem with the most space.
1858 This gets a good balance between the two
1862 refresh_disk_space ();
1864 int free_enough = 0;
1866 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1867 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1872 if (free_enough >= 2) {
1873 /* use RR selection process, ensuring that the one
1877 i = last_rr_session_dir;
1880 if (++i == session_dirs.end()) {
1881 i = session_dirs.begin();
1884 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1885 if (create_session_directory ((*i).path)) {
1887 last_rr_session_dir = i;
1892 } while (i != last_rr_session_dir);
1896 /* pick FS with the most freespace (and that
1897 seems to actually work ...)
1900 vector<space_and_path> sorted;
1901 space_and_path_ascending_cmp cmp;
1903 sorted = session_dirs;
1904 sort (sorted.begin(), sorted.end(), cmp);
1906 for (i = sorted.begin(); i != sorted.end(); ++i) {
1907 if (create_session_directory ((*i).path)) {
1909 last_rr_session_dir = i;
1919 Session::load_playlists (const XMLNode& node)
1922 XMLNodeConstIterator niter;
1923 boost::shared_ptr<Playlist> playlist;
1925 nlist = node.children();
1929 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1931 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1932 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1940 Session::load_unused_playlists (const XMLNode& node)
1943 XMLNodeConstIterator niter;
1944 boost::shared_ptr<Playlist> playlist;
1946 nlist = node.children();
1950 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1952 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1953 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1957 // now manually untrack it
1959 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1965 boost::shared_ptr<Playlist>
1966 Session::XMLPlaylistFactory (const XMLNode& node)
1969 return PlaylistFactory::create (*this, node);
1972 catch (failed_constructor& err) {
1973 return boost::shared_ptr<Playlist>();
1978 Session::load_named_selections (const XMLNode& node)
1981 XMLNodeConstIterator niter;
1984 nlist = node.children();
1988 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1990 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1991 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1999 Session::XMLNamedSelectionFactory (const XMLNode& node)
2002 return new NamedSelection (*this, node);
2005 catch (failed_constructor& err) {
2011 Session::automation_dir () const
2013 return Glib::build_filename (_path, "automation");
2017 Session::analysis_dir () const
2019 return Glib::build_filename (_path, "analysis");
2023 Session::load_bundles (XMLNode const & node)
2025 XMLNodeList nlist = node.children();
2026 XMLNodeConstIterator niter;
2030 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2031 if ((*niter)->name() == "InputBundle") {
2032 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2033 } else if ((*niter)->name() == "OutputBundle") {
2034 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2036 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2045 Session::load_edit_groups (const XMLNode& node)
2047 return load_route_groups (node, true);
2051 Session::load_mix_groups (const XMLNode& node)
2053 return load_route_groups (node, false);
2057 Session::load_route_groups (const XMLNode& node, bool edit)
2059 XMLNodeList nlist = node.children();
2060 XMLNodeConstIterator niter;
2064 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2065 if ((*niter)->name() == "RouteGroup") {
2066 RouteGroup* rg = new RouteGroup (*this, "");
2068 add_edit_group (rg);
2069 rg->set_state (**niter);
2072 rg->set_state (**niter);
2081 Session::auto_save()
2083 save_state (_current_snapshot_name);
2087 state_file_filter (const string &str, void *arg)
2089 return (str.length() > strlen(statefile_suffix) &&
2090 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2094 bool operator()(const string* a, const string* b) {
2100 remove_end(string* state)
2102 string statename(*state);
2104 string::size_type start,end;
2105 if ((start = statename.find_last_of ('/')) != string::npos) {
2106 statename = statename.substr (start+1);
2109 if ((end = statename.rfind(".ardour")) == string::npos) {
2110 end = statename.length();
2113 return new string(statename.substr (0, end));
2117 Session::possible_states (string path)
2119 PathScanner scanner;
2120 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2122 transform(states->begin(), states->end(), states->begin(), remove_end);
2125 sort (states->begin(), states->end(), cmp);
2131 Session::possible_states () const
2133 return possible_states(_path);
2137 Session::add_edit_group (RouteGroup* g)
2139 edit_groups.push_back (g);
2140 edit_group_added (g); /* EMIT SIGNAL */
2145 Session::add_mix_group (RouteGroup* g)
2147 mix_groups.push_back (g);
2148 mix_group_added (g); /* EMIT SIGNAL */
2153 Session::remove_edit_group (RouteGroup& rg)
2155 list<RouteGroup*>::iterator i;
2157 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2158 (*i)->apply (&Route::drop_edit_group, this);
2159 edit_groups.erase (i);
2160 edit_group_removed (); /* EMIT SIGNAL */
2167 Session::remove_mix_group (RouteGroup& rg)
2169 list<RouteGroup*>::iterator i;
2171 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2172 (*i)->apply (&Route::drop_mix_group, this);
2173 mix_groups.erase (i);
2174 mix_group_removed (); /* EMIT SIGNAL */
2181 Session::mix_group_by_name (string name)
2183 list<RouteGroup *>::iterator i;
2185 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2186 if ((*i)->name() == name) {
2194 Session::edit_group_by_name (string name)
2196 list<RouteGroup *>::iterator i;
2198 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2199 if ((*i)->name() == name) {
2207 Session::begin_reversible_command(const string& name)
2209 UndoTransaction* trans = new UndoTransaction();
2210 trans->set_name(name);
2211 if (!_current_trans.empty()) {
2212 _current_trans.top()->add_command(trans);
2214 _current_trans.push(trans);
2218 Session::commit_reversible_command(Command *cmd)
2220 assert(!_current_trans.empty());
2224 _current_trans.top()->add_command(cmd);
2227 if (_current_trans.top()->empty()) {
2228 _current_trans.pop();
2232 gettimeofday(&now, 0);
2233 _current_trans.top()->set_timestamp(now);
2235 _history.add(_current_trans.top());
2236 _current_trans.pop();
2239 Session::GlobalRouteBooleanState
2240 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2242 GlobalRouteBooleanState s;
2243 boost::shared_ptr<RouteList> r = routes.reader ();
2245 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2246 if (!(*i)->is_hidden()) {
2247 RouteBooleanState v;
2250 Route* r = (*i).get();
2251 v.second = (r->*method)();
2260 Session::GlobalRouteMeterState
2261 Session::get_global_route_metering ()
2263 GlobalRouteMeterState s;
2264 boost::shared_ptr<RouteList> r = routes.reader ();
2266 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2267 if (!(*i)->is_hidden()) {
2271 v.second = (*i)->meter_point();
2281 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2283 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2285 boost::shared_ptr<Route> r = (i->first.lock());
2288 r->set_meter_point (i->second, arg);
2294 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2296 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2298 boost::shared_ptr<Route> r = (i->first.lock());
2301 Route* rp = r.get();
2302 (rp->*method) (i->second, arg);
2308 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2310 set_global_route_boolean (s, &Route::set_mute, src);
2314 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2316 set_global_route_boolean (s, &Route::set_solo, src);
2320 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2322 set_global_route_boolean (s, &Route::set_record_enable, src);
2326 accept_all_non_peak_files (const string& path, void *arg)
2328 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2332 accept_all_state_files (const string& path, void *arg)
2334 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2338 Session::find_all_sources (string path, set<string>& result)
2343 if (!tree.read (path)) {
2347 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2352 XMLNodeConstIterator niter;
2354 nlist = node->children();
2358 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2362 if ((prop = (*niter)->property (X_("name"))) == 0) {
2366 if (prop->value()[0] == '/') {
2367 /* external file, ignore */
2371 sys::path source_path = _session_dir->sound_path ();
2373 source_path /= prop->value ();
2375 result.insert (source_path.to_string ());
2382 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2384 PathScanner scanner;
2385 vector<string*>* state_files;
2387 string this_snapshot_path;
2393 if (ripped[ripped.length()-1] == '/') {
2394 ripped = ripped.substr (0, ripped.length() - 1);
2397 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2399 if (state_files == 0) {
2404 this_snapshot_path = _path;
2405 this_snapshot_path += _current_snapshot_name;
2406 this_snapshot_path += statefile_suffix;
2408 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2410 if (exclude_this_snapshot && **i == this_snapshot_path) {
2414 if (find_all_sources (**i, result) < 0) {
2422 struct RegionCounter {
2423 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2424 AudioSourceList::iterator iter;
2425 boost::shared_ptr<Region> region;
2428 RegionCounter() : count (0) {}
2432 Session::cleanup_sources (Session::cleanup_report& rep)
2434 // FIXME: needs adaptation to midi
2436 vector<boost::shared_ptr<Source> > dead_sources;
2437 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2438 PathScanner scanner;
2440 vector<space_and_path>::iterator i;
2441 vector<space_and_path>::iterator nexti;
2442 vector<string*>* soundfiles;
2443 vector<string> unused;
2444 set<string> all_sources;
2449 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2452 /* step 1: consider deleting all unused playlists */
2454 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2457 status = AskAboutPlaylistDeletion (*x);
2466 playlists_tbd.push_back (*x);
2470 /* leave it alone */
2475 /* now delete any that were marked for deletion */
2477 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2478 (*x)->drop_references ();
2481 playlists_tbd.clear ();
2483 /* step 2: find all un-used sources */
2488 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2490 SourceMap::iterator tmp;
2495 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2499 if (!i->second->used() && i->second->length(i->second->timeline_position()) > 0) {
2500 dead_sources.push_back (i->second);
2501 i->second->GoingAway();
2507 /* build a list of all the possible sound directories for the session */
2509 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2514 SessionDirectory sdir ((*i).path);
2515 sound_path += sdir.sound_path().to_string();
2517 if (nexti != session_dirs.end()) {
2524 /* now do the same thing for the files that ended up in the sounds dir(s)
2525 but are not referenced as sources in any snapshot.
2528 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2530 if (soundfiles == 0) {
2534 /* find all sources, but don't use this snapshot because the
2535 state file on disk still references sources we may have already
2539 find_all_sources_across_snapshots (all_sources, true);
2541 /* add our current source list
2544 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2545 boost::shared_ptr<FileSource> fs;
2547 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2548 all_sources.insert (fs->path());
2552 char tmppath1[PATH_MAX+1];
2553 char tmppath2[PATH_MAX+1];
2555 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2560 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2562 realpath(spath.c_str(), tmppath1);
2563 realpath((*i).c_str(), tmppath2);
2565 if (strcmp(tmppath1, tmppath2) == 0) {
2572 unused.push_back (spath);
2576 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2578 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2579 struct stat statbuf;
2581 rep.paths.push_back (*x);
2582 if (stat ((*x).c_str(), &statbuf) == 0) {
2583 rep.space += statbuf.st_size;
2588 /* don't move the file across filesystems, just
2589 stick it in the `dead_sound_dir_name' directory
2590 on whichever filesystem it was already on.
2593 if ((*x).find ("/sounds/") != string::npos) {
2595 /* old school, go up 1 level */
2597 newpath = Glib::path_get_dirname (*x); // "sounds"
2598 newpath = Glib::path_get_dirname (newpath); // "session-name"
2602 /* new school, go up 4 levels */
2604 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2605 newpath = Glib::path_get_dirname (newpath); // "session-name"
2606 newpath = Glib::path_get_dirname (newpath); // "interchange"
2607 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2611 newpath += dead_sound_dir_name;
2613 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2614 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2619 newpath += Glib::path_get_basename ((*x));
2621 if (access (newpath.c_str(), F_OK) == 0) {
2623 /* the new path already exists, try versioning */
2625 char buf[PATH_MAX+1];
2629 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2632 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2633 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2637 if (version == 999) {
2638 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2642 newpath = newpath_v;
2647 /* it doesn't exist, or we can't read it or something */
2651 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2652 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2653 (*x), newpath, strerror (errno))
2658 /* see if there an easy to find peakfile for this file, and remove it.
2661 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2662 peakpath += peakfile_suffix;
2664 if (access (peakpath.c_str(), W_OK) == 0) {
2665 if (::unlink (peakpath.c_str()) != 0) {
2666 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2667 peakpath, _path, strerror (errno))
2669 /* try to back out */
2670 rename (newpath.c_str(), _path.c_str());
2678 /* dump the history list */
2682 /* save state so we don't end up a session file
2683 referring to non-existent sources.
2689 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2695 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2697 // FIXME: needs adaptation for MIDI
2699 vector<space_and_path>::iterator i;
2700 string dead_sound_dir;
2701 struct dirent* dentry;
2702 struct stat statbuf;
2708 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2710 dead_sound_dir = (*i).path;
2711 dead_sound_dir += dead_sound_dir_name;
2713 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2717 while ((dentry = readdir (dead)) != 0) {
2719 /* avoid '.' and '..' */
2721 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2722 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2728 fullpath = dead_sound_dir;
2730 fullpath += dentry->d_name;
2732 if (stat (fullpath.c_str(), &statbuf)) {
2736 if (!S_ISREG (statbuf.st_mode)) {
2740 if (unlink (fullpath.c_str())) {
2741 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2742 fullpath, strerror (errno))
2746 rep.paths.push_back (dentry->d_name);
2747 rep.space += statbuf.st_size;
2758 Session::set_dirty ()
2760 bool was_dirty = dirty();
2762 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2766 DirtyChanged(); /* EMIT SIGNAL */
2772 Session::set_clean ()
2774 bool was_dirty = dirty();
2776 _state_of_the_state = Clean;
2780 DirtyChanged(); /* EMIT SIGNAL */
2785 Session::set_deletion_in_progress ()
2787 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2791 Session::clear_deletion_in_progress ()
2793 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2797 Session::add_controllable (boost::shared_ptr<Controllable> c)
2799 /* this adds a controllable to the list managed by the Session.
2800 this is a subset of those managed by the Controllable class
2801 itself, and represents the only ones whose state will be saved
2802 as part of the session.
2805 Glib::Mutex::Lock lm (controllables_lock);
2806 controllables.insert (c);
2809 struct null_deleter { void operator()(void const *) const {} };
2812 Session::remove_controllable (Controllable* c)
2814 if (_state_of_the_state | Deletion) {
2818 Glib::Mutex::Lock lm (controllables_lock);
2820 Controllables::iterator x = controllables.find(
2821 boost::shared_ptr<Controllable>(c, null_deleter()));
2823 if (x != controllables.end()) {
2824 controllables.erase (x);
2828 boost::shared_ptr<Controllable>
2829 Session::controllable_by_id (const PBD::ID& id)
2831 Glib::Mutex::Lock lm (controllables_lock);
2833 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2834 if ((*i)->id() == id) {
2839 return boost::shared_ptr<Controllable>();
2843 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2845 Stateful::add_instant_xml (node, _path);
2846 if (write_to_config) {
2847 Config->add_instant_xml (node);
2852 Session::instant_xml (const string& node_name)
2854 return Stateful::instant_xml (node_name, _path);
2858 Session::save_history (string snapshot_name)
2862 if (snapshot_name.empty()) {
2863 snapshot_name = _current_snapshot_name;
2866 const string history_filename = snapshot_name + history_suffix;
2867 const string backup_filename = history_filename + backup_suffix;
2868 const sys::path xml_path = _session_dir->root_path() / history_filename;
2869 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2871 if (sys::exists (xml_path)) {
2874 sys::rename (xml_path, backup_path);
2876 catch (const sys::filesystem_error& err)
2878 error << _("could not backup old history file, current history not saved") << endmsg;
2884 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2888 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2890 if (!tree.write (xml_path.to_string()))
2892 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2896 sys::remove (xml_path);
2897 sys::rename (backup_path, xml_path);
2899 catch (const sys::filesystem_error& err)
2901 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2902 backup_path.to_string(), err.what()) << endmsg;
2912 Session::restore_history (string snapshot_name)
2916 if (snapshot_name.empty()) {
2917 snapshot_name = _current_snapshot_name;
2920 const string xml_filename = snapshot_name + history_suffix;
2921 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2923 cerr << "Loading history from " << xml_path.to_string() << endmsg;
2925 if (!sys::exists (xml_path)) {
2926 info << string_compose (_("%1: no history file \"%2\" for this session."),
2927 _name, xml_path.to_string()) << endmsg;
2931 if (!tree.read (xml_path.to_string())) {
2932 error << string_compose (_("Could not understand session history file \"%1\""),
2933 xml_path.to_string()) << endmsg;
2940 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2943 UndoTransaction* ut = new UndoTransaction ();
2946 ut->set_name(t->property("name")->value());
2947 stringstream ss(t->property("tv-sec")->value());
2949 ss.str(t->property("tv-usec")->value());
2951 ut->set_timestamp(tv);
2953 for (XMLNodeConstIterator child_it = t->children().begin();
2954 child_it != t->children().end(); child_it++)
2956 XMLNode *n = *child_it;
2959 if (n->name() == "MementoCommand" ||
2960 n->name() == "MementoUndoCommand" ||
2961 n->name() == "MementoRedoCommand") {
2963 if ((c = memento_command_factory(n))) {
2967 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2969 if ((c = global_state_command_factory (*n))) {
2970 ut->add_command (c);
2973 } else if (n->name() == "DeltaCommand") {
2974 PBD::ID id(n->property("midi-source")->value());
2975 boost::shared_ptr<MidiSource> midi_source =
2976 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2978 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
2980 error << "FIXME: Failed to downcast MidiSource for DeltaCommand" << endmsg;
2983 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2994 Session::config_changed (std::string p, bool ours)
3000 if (p == "seamless-loop") {
3002 } else if (p == "rf-speed") {
3004 } else if (p == "auto-loop") {
3006 } else if (p == "auto-input") {
3008 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3009 /* auto-input only makes a difference if we're rolling */
3011 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3013 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3014 if ((*i)->record_enabled ()) {
3015 (*i)->monitor_input (!config.get_auto_input());
3020 } else if (p == "punch-in") {
3024 if ((location = _locations.auto_punch_location()) != 0) {
3026 if (config.get_punch_in ()) {
3027 replace_event (Event::PunchIn, location->start());
3029 remove_event (location->start(), Event::PunchIn);
3033 } else if (p == "punch-out") {
3037 if ((location = _locations.auto_punch_location()) != 0) {
3039 if (config.get_punch_out()) {
3040 replace_event (Event::PunchOut, location->end());
3042 clear_events (Event::PunchOut);
3046 } else if (p == "edit-mode") {
3048 Glib::Mutex::Lock lm (playlist_lock);
3050 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3051 (*i)->set_edit_mode (Config->get_edit_mode ());
3054 } else if (p == "use-video-sync") {
3056 waiting_for_sync_offset = config.get_use_video_sync();
3058 } else if (p == "mmc-control") {
3060 //poke_midi_thread ();
3062 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3065 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3068 } else if (p == "mmc-send-id") {
3071 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3074 } else if (p == "midi-control") {
3076 //poke_midi_thread ();
3078 } else if (p == "raid-path") {
3080 setup_raid_path (config.get_raid_path());
3082 } else if (p == "smpte-format") {
3086 } else if (p == "video-pullup") {
3090 } else if (p == "seamless-loop") {
3092 if (play_loop && transport_rolling()) {
3093 // to reset diskstreams etc
3094 request_play_loop (true);
3097 } else if (p == "rf-speed") {
3099 cumulative_rf_motion = 0;
3102 } else if (p == "click-sound") {
3104 setup_click_sounds (1);
3106 } else if (p == "click-emphasis-sound") {
3108 setup_click_sounds (-1);
3110 } else if (p == "clicking") {
3112 if (Config->get_clicking()) {
3113 if (_click_io && click_data) { // don't require emphasis data
3120 } else if (p == "send-mtc") {
3122 /* only set the internal flag if we have
3126 if (_mtc_port != 0) {
3127 session_send_mtc = Config->get_send_mtc();
3128 if (session_send_mtc) {
3129 /* mark us ready to send */
3130 next_quarter_frame_to_send = 0;
3133 session_send_mtc = false;
3136 } else if (p == "send-mmc") {
3138 /* only set the internal flag if we have
3142 if (_mmc_port != 0) {
3143 session_send_mmc = Config->get_send_mmc();
3146 session_send_mmc = false;
3149 } else if (p == "midi-feedback") {
3151 /* only set the internal flag if we have
3155 if (_mtc_port != 0) {
3156 session_midi_feedback = Config->get_midi_feedback();
3159 } else if (p == "jack-time-master") {
3161 engine().reset_timebase ();
3163 } else if (p == "native-file-header-format") {
3165 if (!first_file_header_format_reset) {
3166 reset_native_file_format ();
3169 first_file_header_format_reset = false;
3171 } else if (p == "native-file-data-format") {
3173 if (!first_file_data_format_reset) {
3174 reset_native_file_format ();
3177 first_file_data_format_reset = false;
3179 } else if (p == "slave-source") {
3180 set_slave_source (Config->get_slave_source());
3181 } else if (p == "remote-model") {
3182 set_remote_control_ids ();
3183 } else if (p == "denormal-model") {
3185 } else if (p == "history-depth") {
3186 set_history_depth (Config->get_history_depth());
3187 } else if (p == "sync-all-route-ordering") {
3188 sync_order_keys ("session");
3189 } else if (p == "initial-program-change") {
3191 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3194 buf[0] = MIDI::program; // channel zero by default
3195 buf[1] = (Config->get_initial_program_change() & 0x7f);
3197 _mmc_port->midimsg (buf, sizeof (buf), 0);
3199 } else if (p == "initial-program-change") {
3201 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3202 MIDI::byte* buf = new MIDI::byte[2];
3204 buf[0] = MIDI::program; // channel zero by default
3205 buf[1] = (Config->get_initial_program_change() & 0x7f);
3206 // deliver_midi (_mmc_port, buf, 2);
3208 } else if (p == "solo-mute-override") {
3209 // catch_up_on_solo_mute_override ();
3210 } else if (p == "solo-model") {
3211 solo_model_changed ();
3218 Session::set_history_depth (uint32_t d)
3220 _history.set_depth (d);