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;
2065 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2066 if ((*niter)->name() == "RouteGroup") {
2068 rg = add_edit_group ("");
2069 rg->set_state (**niter);
2071 rg = add_mix_group ("");
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 (string name)
2139 RouteGroup* rg = new RouteGroup (*this, name);
2140 edit_groups.push_back (rg);
2141 edit_group_added (rg); /* EMIT SIGNAL */
2147 Session::add_mix_group (string name)
2149 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2150 mix_groups.push_back (rg);
2151 mix_group_added (rg); /* EMIT SIGNAL */
2157 Session::remove_edit_group (RouteGroup& rg)
2159 list<RouteGroup*>::iterator i;
2161 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2162 (*i)->apply (&Route::drop_edit_group, this);
2163 edit_groups.erase (i);
2164 edit_group_removed (); /* EMIT SIGNAL */
2171 Session::remove_mix_group (RouteGroup& rg)
2173 list<RouteGroup*>::iterator i;
2175 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2176 (*i)->apply (&Route::drop_mix_group, this);
2177 mix_groups.erase (i);
2178 mix_group_removed (); /* EMIT SIGNAL */
2185 Session::mix_group_by_name (string name)
2187 list<RouteGroup *>::iterator i;
2189 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2190 if ((*i)->name() == name) {
2198 Session::edit_group_by_name (string name)
2200 list<RouteGroup *>::iterator i;
2202 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2203 if ((*i)->name() == name) {
2211 Session::begin_reversible_command(const string& name)
2213 UndoTransaction* trans = new UndoTransaction();
2214 trans->set_name(name);
2215 if (!_current_trans.empty()) {
2216 _current_trans.top()->add_command(trans);
2218 _current_trans.push(trans);
2222 Session::commit_reversible_command(Command *cmd)
2224 assert(!_current_trans.empty());
2228 _current_trans.top()->add_command(cmd);
2231 if (_current_trans.top()->empty()) {
2232 _current_trans.pop();
2236 gettimeofday(&now, 0);
2237 _current_trans.top()->set_timestamp(now);
2239 _history.add(_current_trans.top());
2240 _current_trans.pop();
2243 Session::GlobalRouteBooleanState
2244 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2246 GlobalRouteBooleanState s;
2247 boost::shared_ptr<RouteList> r = routes.reader ();
2249 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2250 if (!(*i)->is_hidden()) {
2251 RouteBooleanState v;
2254 Route* r = (*i).get();
2255 v.second = (r->*method)();
2264 Session::GlobalRouteMeterState
2265 Session::get_global_route_metering ()
2267 GlobalRouteMeterState s;
2268 boost::shared_ptr<RouteList> r = routes.reader ();
2270 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2271 if (!(*i)->is_hidden()) {
2275 v.second = (*i)->meter_point();
2285 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2287 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2289 boost::shared_ptr<Route> r = (i->first.lock());
2292 r->set_meter_point (i->second, arg);
2298 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2300 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2302 boost::shared_ptr<Route> r = (i->first.lock());
2305 Route* rp = r.get();
2306 (rp->*method) (i->second, arg);
2312 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2314 set_global_route_boolean (s, &Route::set_mute, src);
2318 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2320 set_global_route_boolean (s, &Route::set_solo, src);
2324 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2326 set_global_route_boolean (s, &Route::set_record_enable, src);
2330 accept_all_non_peak_files (const string& path, void *arg)
2332 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2336 accept_all_state_files (const string& path, void *arg)
2338 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2342 Session::find_all_sources (string path, set<string>& result)
2347 if (!tree.read (path)) {
2351 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2356 XMLNodeConstIterator niter;
2358 nlist = node->children();
2362 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2366 if ((prop = (*niter)->property (X_("name"))) == 0) {
2370 if (prop->value()[0] == '/') {
2371 /* external file, ignore */
2375 sys::path source_path = _session_dir->sound_path ();
2377 source_path /= prop->value ();
2379 result.insert (source_path.to_string ());
2386 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2388 PathScanner scanner;
2389 vector<string*>* state_files;
2391 string this_snapshot_path;
2397 if (ripped[ripped.length()-1] == '/') {
2398 ripped = ripped.substr (0, ripped.length() - 1);
2401 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2403 if (state_files == 0) {
2408 this_snapshot_path = _path;
2409 this_snapshot_path += _current_snapshot_name;
2410 this_snapshot_path += statefile_suffix;
2412 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2414 if (exclude_this_snapshot && **i == this_snapshot_path) {
2418 if (find_all_sources (**i, result) < 0) {
2426 struct RegionCounter {
2427 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2428 AudioSourceList::iterator iter;
2429 boost::shared_ptr<Region> region;
2432 RegionCounter() : count (0) {}
2436 Session::cleanup_sources (Session::cleanup_report& rep)
2438 // FIXME: needs adaptation to midi
2440 vector<boost::shared_ptr<Source> > dead_sources;
2441 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2442 PathScanner scanner;
2444 vector<space_and_path>::iterator i;
2445 vector<space_and_path>::iterator nexti;
2446 vector<string*>* soundfiles;
2447 vector<string> unused;
2448 set<string> all_sources;
2453 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2456 /* step 1: consider deleting all unused playlists */
2458 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2461 status = AskAboutPlaylistDeletion (*x);
2470 playlists_tbd.push_back (*x);
2474 /* leave it alone */
2479 /* now delete any that were marked for deletion */
2481 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2482 (*x)->drop_references ();
2485 playlists_tbd.clear ();
2487 /* step 2: find all un-used sources */
2492 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2494 SourceMap::iterator tmp;
2499 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2503 if (!i->second->used() && i->second->length(i->second->timeline_position()) > 0) {
2504 dead_sources.push_back (i->second);
2505 i->second->GoingAway();
2511 /* build a list of all the possible sound directories for the session */
2513 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2518 SessionDirectory sdir ((*i).path);
2519 sound_path += sdir.sound_path().to_string();
2521 if (nexti != session_dirs.end()) {
2528 /* now do the same thing for the files that ended up in the sounds dir(s)
2529 but are not referenced as sources in any snapshot.
2532 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2534 if (soundfiles == 0) {
2538 /* find all sources, but don't use this snapshot because the
2539 state file on disk still references sources we may have already
2543 find_all_sources_across_snapshots (all_sources, true);
2545 /* add our current source list
2548 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2549 boost::shared_ptr<FileSource> fs;
2551 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2552 all_sources.insert (fs->path());
2556 char tmppath1[PATH_MAX+1];
2557 char tmppath2[PATH_MAX+1];
2559 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2564 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2566 realpath(spath.c_str(), tmppath1);
2567 realpath((*i).c_str(), tmppath2);
2569 if (strcmp(tmppath1, tmppath2) == 0) {
2576 unused.push_back (spath);
2580 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2582 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2583 struct stat statbuf;
2585 rep.paths.push_back (*x);
2586 if (stat ((*x).c_str(), &statbuf) == 0) {
2587 rep.space += statbuf.st_size;
2592 /* don't move the file across filesystems, just
2593 stick it in the `dead_sound_dir_name' directory
2594 on whichever filesystem it was already on.
2597 if ((*x).find ("/sounds/") != string::npos) {
2599 /* old school, go up 1 level */
2601 newpath = Glib::path_get_dirname (*x); // "sounds"
2602 newpath = Glib::path_get_dirname (newpath); // "session-name"
2606 /* new school, go up 4 levels */
2608 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2609 newpath = Glib::path_get_dirname (newpath); // "session-name"
2610 newpath = Glib::path_get_dirname (newpath); // "interchange"
2611 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2615 newpath += dead_sound_dir_name;
2617 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2618 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2623 newpath += Glib::path_get_basename ((*x));
2625 if (access (newpath.c_str(), F_OK) == 0) {
2627 /* the new path already exists, try versioning */
2629 char buf[PATH_MAX+1];
2633 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2636 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2637 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2641 if (version == 999) {
2642 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2646 newpath = newpath_v;
2651 /* it doesn't exist, or we can't read it or something */
2655 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2656 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2657 (*x), newpath, strerror (errno))
2662 /* see if there an easy to find peakfile for this file, and remove it.
2665 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2666 peakpath += peakfile_suffix;
2668 if (access (peakpath.c_str(), W_OK) == 0) {
2669 if (::unlink (peakpath.c_str()) != 0) {
2670 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2671 peakpath, _path, strerror (errno))
2673 /* try to back out */
2674 rename (newpath.c_str(), _path.c_str());
2682 /* dump the history list */
2686 /* save state so we don't end up a session file
2687 referring to non-existent sources.
2693 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2699 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2701 // FIXME: needs adaptation for MIDI
2703 vector<space_and_path>::iterator i;
2704 string dead_sound_dir;
2705 struct dirent* dentry;
2706 struct stat statbuf;
2712 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2714 dead_sound_dir = (*i).path;
2715 dead_sound_dir += dead_sound_dir_name;
2717 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2721 while ((dentry = readdir (dead)) != 0) {
2723 /* avoid '.' and '..' */
2725 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2726 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2732 fullpath = dead_sound_dir;
2734 fullpath += dentry->d_name;
2736 if (stat (fullpath.c_str(), &statbuf)) {
2740 if (!S_ISREG (statbuf.st_mode)) {
2744 if (unlink (fullpath.c_str())) {
2745 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2746 fullpath, strerror (errno))
2750 rep.paths.push_back (dentry->d_name);
2751 rep.space += statbuf.st_size;
2762 Session::set_dirty ()
2764 bool was_dirty = dirty();
2766 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2770 DirtyChanged(); /* EMIT SIGNAL */
2776 Session::set_clean ()
2778 bool was_dirty = dirty();
2780 _state_of_the_state = Clean;
2784 DirtyChanged(); /* EMIT SIGNAL */
2789 Session::set_deletion_in_progress ()
2791 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2795 Session::clear_deletion_in_progress ()
2797 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2801 Session::add_controllable (boost::shared_ptr<Controllable> c)
2803 /* this adds a controllable to the list managed by the Session.
2804 this is a subset of those managed by the Controllable class
2805 itself, and represents the only ones whose state will be saved
2806 as part of the session.
2809 Glib::Mutex::Lock lm (controllables_lock);
2810 controllables.insert (c);
2813 struct null_deleter { void operator()(void const *) const {} };
2816 Session::remove_controllable (Controllable* c)
2818 if (_state_of_the_state | Deletion) {
2822 Glib::Mutex::Lock lm (controllables_lock);
2824 Controllables::iterator x = controllables.find(
2825 boost::shared_ptr<Controllable>(c, null_deleter()));
2827 if (x != controllables.end()) {
2828 controllables.erase (x);
2832 boost::shared_ptr<Controllable>
2833 Session::controllable_by_id (const PBD::ID& id)
2835 Glib::Mutex::Lock lm (controllables_lock);
2837 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2838 if ((*i)->id() == id) {
2843 return boost::shared_ptr<Controllable>();
2847 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2849 Stateful::add_instant_xml (node, _path);
2850 if (write_to_config) {
2851 Config->add_instant_xml (node);
2856 Session::instant_xml (const string& node_name)
2858 return Stateful::instant_xml (node_name, _path);
2862 Session::save_history (string snapshot_name)
2866 if (snapshot_name.empty()) {
2867 snapshot_name = _current_snapshot_name;
2870 const string history_filename = snapshot_name + history_suffix;
2871 const string backup_filename = history_filename + backup_suffix;
2872 const sys::path xml_path = _session_dir->root_path() / history_filename;
2873 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2875 if (sys::exists (xml_path)) {
2878 sys::rename (xml_path, backup_path);
2880 catch (const sys::filesystem_error& err)
2882 error << _("could not backup old history file, current history not saved") << endmsg;
2888 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2892 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2894 if (!tree.write (xml_path.to_string()))
2896 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2900 sys::remove (xml_path);
2901 sys::rename (backup_path, xml_path);
2903 catch (const sys::filesystem_error& err)
2905 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2906 backup_path.to_string(), err.what()) << endmsg;
2916 Session::restore_history (string snapshot_name)
2920 if (snapshot_name.empty()) {
2921 snapshot_name = _current_snapshot_name;
2924 const string xml_filename = snapshot_name + history_suffix;
2925 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2927 cerr << "Loading history from " << xml_path.to_string() << endmsg;
2929 if (!sys::exists (xml_path)) {
2930 info << string_compose (_("%1: no history file \"%2\" for this session."),
2931 _name, xml_path.to_string()) << endmsg;
2935 if (!tree.read (xml_path.to_string())) {
2936 error << string_compose (_("Could not understand session history file \"%1\""),
2937 xml_path.to_string()) << endmsg;
2944 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2947 UndoTransaction* ut = new UndoTransaction ();
2950 ut->set_name(t->property("name")->value());
2951 stringstream ss(t->property("tv-sec")->value());
2953 ss.str(t->property("tv-usec")->value());
2955 ut->set_timestamp(tv);
2957 for (XMLNodeConstIterator child_it = t->children().begin();
2958 child_it != t->children().end(); child_it++)
2960 XMLNode *n = *child_it;
2963 if (n->name() == "MementoCommand" ||
2964 n->name() == "MementoUndoCommand" ||
2965 n->name() == "MementoRedoCommand") {
2967 if ((c = memento_command_factory(n))) {
2971 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2973 if ((c = global_state_command_factory (*n))) {
2974 ut->add_command (c);
2977 } else if (n->name() == "DeltaCommand") {
2978 PBD::ID id(n->property("midi-source")->value());
2979 boost::shared_ptr<MidiSource> midi_source =
2980 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2982 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
2984 error << "FIXME: Failed to downcast MidiSource for DeltaCommand" << endmsg;
2987 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2998 Session::config_changed (std::string p, bool ours)
3004 if (p == "seamless-loop") {
3006 } else if (p == "rf-speed") {
3008 } else if (p == "auto-loop") {
3010 } else if (p == "auto-input") {
3012 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3013 /* auto-input only makes a difference if we're rolling */
3015 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3017 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3018 if ((*i)->record_enabled ()) {
3019 (*i)->monitor_input (!config.get_auto_input());
3024 } else if (p == "punch-in") {
3028 if ((location = _locations.auto_punch_location()) != 0) {
3030 if (config.get_punch_in ()) {
3031 replace_event (Event::PunchIn, location->start());
3033 remove_event (location->start(), Event::PunchIn);
3037 } else if (p == "punch-out") {
3041 if ((location = _locations.auto_punch_location()) != 0) {
3043 if (config.get_punch_out()) {
3044 replace_event (Event::PunchOut, location->end());
3046 clear_events (Event::PunchOut);
3050 } else if (p == "edit-mode") {
3052 Glib::Mutex::Lock lm (playlist_lock);
3054 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3055 (*i)->set_edit_mode (Config->get_edit_mode ());
3058 } else if (p == "use-video-sync") {
3060 waiting_for_sync_offset = config.get_use_video_sync();
3062 } else if (p == "mmc-control") {
3064 //poke_midi_thread ();
3066 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3069 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3072 } else if (p == "mmc-send-id") {
3075 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3078 } else if (p == "midi-control") {
3080 //poke_midi_thread ();
3082 } else if (p == "raid-path") {
3084 setup_raid_path (config.get_raid_path());
3086 } else if (p == "smpte-format") {
3090 } else if (p == "video-pullup") {
3094 } else if (p == "seamless-loop") {
3096 if (play_loop && transport_rolling()) {
3097 // to reset diskstreams etc
3098 request_play_loop (true);
3101 } else if (p == "rf-speed") {
3103 cumulative_rf_motion = 0;
3106 } else if (p == "click-sound") {
3108 setup_click_sounds (1);
3110 } else if (p == "click-emphasis-sound") {
3112 setup_click_sounds (-1);
3114 } else if (p == "clicking") {
3116 if (Config->get_clicking()) {
3117 if (_click_io && click_data) { // don't require emphasis data
3124 } else if (p == "send-mtc") {
3126 /* only set the internal flag if we have
3130 if (_mtc_port != 0) {
3131 session_send_mtc = Config->get_send_mtc();
3132 if (session_send_mtc) {
3133 /* mark us ready to send */
3134 next_quarter_frame_to_send = 0;
3137 session_send_mtc = false;
3140 } else if (p == "send-mmc") {
3142 /* only set the internal flag if we have
3146 if (_mmc_port != 0) {
3147 session_send_mmc = Config->get_send_mmc();
3150 session_send_mmc = false;
3153 } else if (p == "midi-feedback") {
3155 /* only set the internal flag if we have
3159 if (_mtc_port != 0) {
3160 session_midi_feedback = Config->get_midi_feedback();
3163 } else if (p == "jack-time-master") {
3165 engine().reset_timebase ();
3167 } else if (p == "native-file-header-format") {
3169 if (!first_file_header_format_reset) {
3170 reset_native_file_format ();
3173 first_file_header_format_reset = false;
3175 } else if (p == "native-file-data-format") {
3177 if (!first_file_data_format_reset) {
3178 reset_native_file_format ();
3181 first_file_data_format_reset = false;
3183 } else if (p == "slave-source") {
3184 set_slave_source (Config->get_slave_source());
3185 } else if (p == "remote-model") {
3186 set_remote_control_ids ();
3187 } else if (p == "denormal-model") {
3189 } else if (p == "history-depth") {
3190 set_history_depth (Config->get_history_depth());
3191 } else if (p == "sync-all-route-ordering") {
3192 sync_order_keys ("session");
3193 } else if (p == "initial-program-change") {
3195 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3198 buf[0] = MIDI::program; // channel zero by default
3199 buf[1] = (Config->get_initial_program_change() & 0x7f);
3201 _mmc_port->midimsg (buf, sizeof (buf), 0);
3203 } else if (p == "initial-program-change") {
3205 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3206 MIDI::byte* buf = new MIDI::byte[2];
3208 buf[0] = MIDI::program; // channel zero by default
3209 buf[1] = (Config->get_initial_program_change() & 0x7f);
3210 // deliver_midi (_mmc_port, buf, 2);
3212 } else if (p == "solo-mute-override") {
3213 // catch_up_on_solo_mute_override ();
3214 } else if (p == "solo-model") {
3215 solo_model_changed ();
3222 Session::set_history_depth (uint32_t d)
3224 _history.set_depth (d);