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);
157 _transport_speed = 0;
158 _last_transport_speed = 0;
159 phi = (uint64_t) (0x1000000);
161 auto_play_legal = false;
162 transport_sub_state = 0;
163 _transport_frame = 0;
164 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
165 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
166 g_atomic_int_set (&_record_status, Disabled);
167 loop_changing = false;
170 _last_roll_location = 0;
171 _last_record_location = 0;
172 pending_locate_frame = 0;
173 pending_locate_roll = false;
174 pending_locate_flush = false;
175 audio_dstream_buffer_size = 0;
176 midi_dstream_buffer_size = 0;
177 state_was_pending = false;
179 outbound_mtc_smpte_frame = 0;
180 next_quarter_frame_to_send = -1;
181 current_block_size = 0;
182 solo_update_disabled = false;
183 currently_soloing = false;
184 _have_captured = false;
185 _worst_output_latency = 0;
186 _worst_input_latency = 0;
187 _worst_track_latency = 0;
188 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
191 session_send_mmc = false;
192 session_send_mtc = false;
193 post_transport_work = PostTransportWork (0);
194 g_atomic_int_set (&butler_should_do_transport_work, 0);
195 g_atomic_int_set (&_playback_load, 100);
196 g_atomic_int_set (&_capture_load, 100);
197 g_atomic_int_set (&_playback_load_min, 100);
198 g_atomic_int_set (&_capture_load_min, 100);
201 _exporting_realtime = false;
202 _gain_automation_buffer = 0;
203 _pan_automation_buffer = 0;
205 pending_abort = false;
206 destructive_index = 0;
207 first_file_data_format_reset = true;
208 first_file_header_format_reset = true;
209 butler_thread = (pthread_t) 0;
210 //midi_thread = (pthread_t) 0;
212 AudioDiskstream::allocate_working_buffers();
214 /* default short fade = 15ms */
216 Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
217 SndFileSource::setup_standard_crossfades (*this, frame_rate());
219 last_mmc_step.tv_sec = 0;
220 last_mmc_step.tv_usec = 0;
223 /* click sounds are unset by default, which causes us to internal
224 waveforms for clicks.
228 click_emphasis_length = 0;
231 process_function = &Session::process_with_events;
233 if (config.get_use_video_sync()) {
234 waiting_for_sync_offset = true;
236 waiting_for_sync_offset = false;
241 _smpte_offset_negative = true;
242 last_smpte_valid = false;
246 last_rr_session_dir = session_dirs.begin();
247 refresh_disk_space ();
249 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
253 average_slave_delta = 1800; // !!! why 1800 ????
254 have_first_delta_accumulator = false;
255 delta_accumulator_cnt = 0;
256 slave_state = Stopped;
258 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
260 /* These are all static "per-class" signals */
262 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
263 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
264 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
265 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
266 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
267 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
269 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
271 IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
273 /* stop IO objects from doing stuff until we're ready for them */
275 Delivery::disable_panners ();
276 IO::disable_connecting ();
280 Session::second_stage_init (bool new_session)
282 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
285 if (load_state (_current_snapshot_name)) {
288 remove_empty_sounds ();
291 if (start_butler_thread()) {
295 if (start_midi_thread ()) {
299 // set_state() will call setup_raid_path(), but if it's a new session we need
300 // to call setup_raid_path() here.
303 if (set_state (*state_tree->root())) {
307 setup_raid_path(_path);
310 /* we can't save till after ::when_engine_running() is called,
311 because otherwise we save state with no connections made.
312 therefore, we reset _state_of_the_state because ::set_state()
313 will have cleared it.
315 we also have to include Loading so that any events that get
316 generated between here and the end of ::when_engine_running()
317 will be processed directly rather than queued.
320 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
323 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
324 _locations.added.connect (mem_fun (this, &Session::locations_added));
325 setup_click_sounds (0);
326 setup_midi_control ();
328 /* Pay attention ... */
330 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
331 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
334 when_engine_running();
337 /* handle this one in a different way than all others, so that its clear what happened */
339 catch (AudioEngine::PortRegistrationFailure& err) {
340 error << err.what() << endmsg;
348 BootMessage (_("Reset Remote Controls"));
350 send_full_time_code (0);
351 _engine.transport_locate (0);
352 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
353 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
355 MidiClockTicker::instance().set_session(*this);
356 MIDI::Name::MidiPatchManager::instance().set_session(*this);
358 /* initial program change will be delivered later; see ::config_changed() */
360 BootMessage (_("Reset Control Protocols"));
362 ControlProtocolManager::instance().set_session (*this);
364 config.set_end_marker_is_free (new_session);
366 _state_of_the_state = Clean;
368 DirtyChanged (); /* EMIT SIGNAL */
370 if (state_was_pending) {
371 save_state (_current_snapshot_name);
372 remove_pending_capture_state ();
373 state_was_pending = false;
376 BootMessage (_("Session loading complete"));
382 Session::raid_path () const
384 SearchPath raid_search_path;
386 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
387 raid_search_path += sys::path((*i).path);
390 return raid_search_path.to_string ();
394 Session::setup_raid_path (string path)
403 session_dirs.clear ();
405 SearchPath search_path(path);
406 SearchPath sound_search_path;
407 SearchPath midi_search_path;
409 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
410 sp.path = (*i).to_string ();
411 sp.blocks = 0; // not needed
412 session_dirs.push_back (sp);
414 SessionDirectory sdir(sp.path);
416 sound_search_path += sdir.sound_path ();
417 midi_search_path += sdir.midi_path ();
420 // set the search path for each data type
421 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
422 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
424 // reset the round-robin soundfile path thingie
425 last_rr_session_dir = session_dirs.begin();
429 Session::ensure_subdirs ()
433 dir = session_directory().peak_path().to_string();
435 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
436 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
440 dir = session_directory().sound_path().to_string();
442 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
443 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
447 dir = session_directory().midi_path().to_string();
449 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
450 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
454 dir = session_directory().dead_sound_path().to_string();
456 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
457 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
461 dir = session_directory().export_path().to_string();
463 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
464 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
468 dir = analysis_dir ();
470 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
471 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
479 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
482 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
483 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
487 if (ensure_subdirs ()) {
491 /* check new_session so we don't overwrite an existing one */
493 if (!mix_template.empty()) {
494 std::string in_path = mix_template;
496 ifstream in(in_path.c_str());
499 string out_path = _path;
501 out_path += statefile_suffix;
503 ofstream out(out_path.c_str());
508 // okay, session is set up. Treat like normal saved
509 // session from now on.
515 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
521 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
528 /* Instantiate metadata */
530 _metadata = new SessionMetadata ();
532 /* set initial start + end point */
534 start_location->set_end (0);
535 _locations.add (start_location);
537 end_location->set_end (initial_length);
538 _locations.add (end_location);
540 _state_of_the_state = Clean;
549 Session::load_diskstreams (const XMLNode& node)
552 XMLNodeConstIterator citer;
554 clist = node.children();
556 for (citer = clist.begin(); citer != clist.end(); ++citer) {
559 /* diskstreams added automatically by DiskstreamCreated handler */
560 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
561 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
562 add_diskstream (dstream);
563 } else if ((*citer)->name() == "MidiDiskstream") {
564 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
565 add_diskstream (dstream);
567 error << _("Session: unknown diskstream type in XML") << endmsg;
571 catch (failed_constructor& err) {
572 error << _("Session: could not load diskstream via XML state") << endmsg;
581 Session::maybe_write_autosave()
583 if (dirty() && record_status() != Recording) {
584 save_state("", true);
589 Session::remove_pending_capture_state ()
591 sys::path pending_state_file_path(_session_dir->root_path());
593 pending_state_file_path /= _current_snapshot_name + pending_suffix;
597 sys::remove (pending_state_file_path);
599 catch(sys::filesystem_error& ex)
601 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
602 pending_state_file_path.to_string(), ex.what()) << endmsg;
606 /** Rename a state file.
607 * @param snapshot_name Snapshot name.
610 Session::rename_state (string old_name, string new_name)
612 if (old_name == _current_snapshot_name || old_name == _name) {
613 /* refuse to rename the current snapshot or the "main" one */
617 const string old_xml_filename = old_name + statefile_suffix;
618 const string new_xml_filename = new_name + statefile_suffix;
620 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
621 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
625 sys::rename (old_xml_path, new_xml_path);
627 catch (const sys::filesystem_error& err)
629 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
630 old_name, new_name, err.what()) << endmsg;
634 /** Remove a state file.
635 * @param snapshot_name Snapshot name.
638 Session::remove_state (string snapshot_name)
640 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
641 // refuse to remove the current snapshot or the "main" one
645 sys::path xml_path(_session_dir->root_path());
647 xml_path /= snapshot_name + statefile_suffix;
649 if (!create_backup_file (xml_path)) {
650 // don't remove it if a backup can't be made
651 // create_backup_file will log the error.
656 sys::remove (xml_path);
660 Session::save_state (string snapshot_name, bool pending)
663 sys::path xml_path(_session_dir->root_path());
665 if (_state_of_the_state & CannotSave) {
669 if (!_engine.connected ()) {
670 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
675 /* tell sources we're saving first, in case they write out to a new file
676 * which should be saved with the state rather than the old one */
677 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
678 i->second->session_saved();
680 tree.set_root (&get_state());
682 if (snapshot_name.empty()) {
683 snapshot_name = _current_snapshot_name;
688 /* proper save: use statefile_suffix (.ardour in English) */
690 xml_path /= snapshot_name + statefile_suffix;
692 /* make a backup copy of the old file */
694 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
695 // create_backup_file will log the error
701 /* pending save: use pending_suffix (.pending in English) */
702 xml_path /= snapshot_name + pending_suffix;
705 sys::path tmp_path(_session_dir->root_path());
707 tmp_path /= snapshot_name + temp_suffix;
709 // cerr << "actually writing state to " << xml_path.to_string() << endl;
711 if (!tree.write (tmp_path.to_string())) {
712 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
713 sys::remove (tmp_path);
718 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
719 error << string_compose (_("could not rename temporary session file %1 to %2"),
720 tmp_path.to_string(), xml_path.to_string()) << endmsg;
721 sys::remove (tmp_path);
728 save_history (snapshot_name);
730 bool was_dirty = dirty();
732 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
735 DirtyChanged (); /* EMIT SIGNAL */
738 StateSaved (snapshot_name); /* EMIT SIGNAL */
745 Session::restore_state (string snapshot_name)
747 if (load_state (snapshot_name) == 0) {
748 set_state (*state_tree->root());
755 Session::load_state (string snapshot_name)
760 state_was_pending = false;
762 /* check for leftover pending state from a crashed capture attempt */
764 sys::path xmlpath(_session_dir->root_path());
765 xmlpath /= snapshot_name + pending_suffix;
767 if (sys::exists (xmlpath)) {
769 /* there is pending state from a crashed capture attempt */
771 if (AskAboutPendingState()) {
772 state_was_pending = true;
776 if (!state_was_pending) {
777 xmlpath = _session_dir->root_path();
778 xmlpath /= snapshot_name + statefile_suffix;
781 if (!sys::exists (xmlpath)) {
782 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
786 state_tree = new XMLTree;
790 if (!state_tree->read (xmlpath.to_string())) {
791 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
797 XMLNode& root (*state_tree->root());
799 if (root.name() != X_("Session")) {
800 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
806 const XMLProperty* prop;
807 bool is_old = false; // session is _very_ old (pre-2.0)
809 if ((prop = root.property ("version")) == 0) {
810 /* no version implies very old version of Ardour */
814 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
815 if (major_version < 2) {
822 sys::path backup_path(_session_dir->root_path());
824 backup_path /= snapshot_name + "-1" + statefile_suffix;
826 // only create a backup once
827 if (sys::exists (backup_path)) {
831 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
832 xmlpath.to_string(), backup_path.to_string())
837 sys::copy_file (xmlpath, backup_path);
839 catch(sys::filesystem_error& ex)
841 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
842 xmlpath.to_string(), ex.what())
852 Session::load_options (const XMLNode& node)
854 LocaleGuard lg (X_("POSIX"));
856 config.set_variables (node);
858 /* now reset MIDI ports because the session can have its own
874 Session::get_template()
876 /* if we don't disable rec-enable, diskstreams
877 will believe they need to store their capture
878 sources in their state node.
881 disable_record (false);
887 Session::state(bool full_state)
889 XMLNode* node = new XMLNode("Session");
892 // store libardour version, just in case
894 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
895 node->add_property("version", string(buf));
897 /* store configuration settings */
901 node->add_property ("name", _name);
902 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
903 node->add_property ("sample-rate", buf);
905 if (session_dirs.size() > 1) {
909 vector<space_and_path>::iterator i = session_dirs.begin();
910 vector<space_and_path>::iterator next;
912 ++i; /* skip the first one */
916 while (i != session_dirs.end()) {
920 if (next != session_dirs.end()) {
930 child = node->add_child ("Path");
931 child->add_content (p);
935 /* save the ID counter */
937 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
938 node->add_property ("id-counter", buf);
940 /* various options */
942 node->add_child_nocopy (config.get_variables ());
944 node->add_child_nocopy (_metadata->get_state());
946 child = node->add_child ("Sources");
949 Glib::Mutex::Lock sl (source_lock);
951 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
953 /* Don't save information about non-destructive file sources that are empty */
954 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
956 boost::shared_ptr<AudioFileSource> fs;
957 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
958 if (!fs->destructive()) {
959 if (fs->length(fs->timeline_position()) == 0) {
965 child->add_child_nocopy (siter->second->get_state());
969 child = node->add_child ("Regions");
972 Glib::Mutex::Lock rl (region_lock);
974 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
976 /* only store regions not attached to playlists */
978 if (i->second->playlist() == 0) {
979 child->add_child_nocopy (i->second->state (true));
984 child = node->add_child ("DiskStreams");
987 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
988 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
989 if (!(*i)->hidden()) {
990 child->add_child_nocopy ((*i)->get_state());
996 node->add_child_nocopy (_locations.get_state());
998 // for a template, just create a new Locations, populate it
999 // with the default start and end, and get the state for that.
1001 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1002 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1005 end->set_end(compute_initial_length());
1007 node->add_child_nocopy (loc.get_state());
1010 child = node->add_child ("Bundles");
1012 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1013 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1014 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1016 child->add_child_nocopy (b->get_state());
1021 child = node->add_child ("Routes");
1023 boost::shared_ptr<RouteList> r = routes.reader ();
1025 RoutePublicOrderSorter cmp;
1026 RouteList public_order (*r);
1027 public_order.sort (cmp);
1029 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1030 if (!(*i)->is_hidden()) {
1032 child->add_child_nocopy ((*i)->get_state());
1034 child->add_child_nocopy ((*i)->get_template());
1041 child = node->add_child ("EditGroups");
1042 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1043 child->add_child_nocopy ((*i)->get_state());
1046 child = node->add_child ("MixGroups");
1047 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1048 child->add_child_nocopy ((*i)->get_state());
1051 child = node->add_child ("Playlists");
1052 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1053 if (!(*i)->hidden()) {
1054 if (!(*i)->empty()) {
1056 child->add_child_nocopy ((*i)->get_state());
1058 child->add_child_nocopy ((*i)->get_template());
1064 child = node->add_child ("UnusedPlaylists");
1065 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1066 if (!(*i)->hidden()) {
1067 if (!(*i)->empty()) {
1069 child->add_child_nocopy ((*i)->get_state());
1071 child->add_child_nocopy ((*i)->get_template());
1079 child = node->add_child ("Click");
1080 child->add_child_nocopy (_click_io->state (full_state));
1084 child = node->add_child ("NamedSelections");
1085 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1087 child->add_child_nocopy ((*i)->get_state());
1092 node->add_child_nocopy (_tempo_map->get_state());
1094 node->add_child_nocopy (get_control_protocol_state());
1097 node->add_child_copy (*_extra_xml);
1104 Session::get_control_protocol_state ()
1106 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1107 return cpm.get_state();
1111 Session::set_state (const XMLNode& node)
1115 const XMLProperty* prop;
1118 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1120 if (node.name() != X_("Session")){
1121 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1125 if ((prop = node.property ("name")) != 0) {
1126 _name = prop->value ();
1129 if ((prop = node.property (X_("sample-rate"))) != 0) {
1131 _nominal_frame_rate = atoi (prop->value());
1133 if (_nominal_frame_rate != _current_frame_rate) {
1134 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1140 setup_raid_path(_session_dir->root_path().to_string());
1142 if ((prop = node.property (X_("id-counter"))) != 0) {
1144 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1145 ID::init_counter (x);
1147 /* old sessions used a timebased counter, so fake
1148 the startup ID counter based on a standard
1153 ID::init_counter (now);
1157 IO::disable_connecting ();
1159 /* Object loading order:
1164 MIDI Control // relies on data from Options/Config
1178 if ((child = find_named_node (node, "Extra")) != 0) {
1179 _extra_xml = new XMLNode (*child);
1182 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1183 load_options (*child);
1184 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1185 load_options (*child);
1187 error << _("Session: XML state has no options section") << endmsg;
1190 if (use_config_midi_ports ()) {
1193 if ((child = find_named_node (node, "Metadata")) == 0) {
1194 warning << _("Session: XML state has no metadata section (2.0 session?)") << endmsg;
1195 } else if (_metadata->set_state (*child)) {
1199 if ((child = find_named_node (node, "Locations")) == 0) {
1200 error << _("Session: XML state has no locations section") << endmsg;
1202 } else if (_locations.set_state (*child)) {
1208 if ((location = _locations.auto_loop_location()) != 0) {
1209 set_auto_loop_location (location);
1212 if ((location = _locations.auto_punch_location()) != 0) {
1213 set_auto_punch_location (location);
1216 if ((location = _locations.end_location()) == 0) {
1217 _locations.add (end_location);
1219 delete end_location;
1220 end_location = location;
1223 if ((location = _locations.start_location()) == 0) {
1224 _locations.add (start_location);
1226 delete start_location;
1227 start_location = location;
1230 AudioFileSource::set_header_position_offset (start_location->start());
1232 if ((child = find_named_node (node, "Sources")) == 0) {
1233 error << _("Session: XML state has no sources section") << endmsg;
1235 } else if (load_sources (*child)) {
1239 if ((child = find_named_node (node, "Regions")) == 0) {
1240 error << _("Session: XML state has no Regions section") << endmsg;
1242 } else if (load_regions (*child)) {
1246 if ((child = find_named_node (node, "Playlists")) == 0) {
1247 error << _("Session: XML state has no playlists section") << endmsg;
1249 } else if (load_playlists (*child)) {
1253 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1255 } else if (load_unused_playlists (*child)) {
1259 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1260 if (load_named_selections (*child)) {
1265 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1266 error << _("Session: XML state has no diskstreams section") << endmsg;
1268 } else if (load_diskstreams (*child)) {
1272 if ((child = find_named_node (node, "Bundles")) == 0) {
1273 warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg;
1276 /* We can't load Bundles yet as they need to be able
1277 to convert from port names to Port objects, which can't happen until
1279 _bundle_xml_node = new XMLNode (*child);
1282 if ((child = find_named_node (node, "EditGroups")) == 0) {
1283 error << _("Session: XML state has no edit groups section") << endmsg;
1285 } else if (load_edit_groups (*child)) {
1289 if ((child = find_named_node (node, "MixGroups")) == 0) {
1290 error << _("Session: XML state has no mix groups section") << endmsg;
1292 } else if (load_mix_groups (*child)) {
1296 if ((child = find_named_node (node, "TempoMap")) == 0) {
1297 error << _("Session: XML state has no Tempo Map section") << endmsg;
1299 } else if (_tempo_map->set_state (*child)) {
1303 if ((child = find_named_node (node, "Routes")) == 0) {
1304 error << _("Session: XML state has no routes section") << endmsg;
1306 } else if (load_routes (*child)) {
1310 if ((child = find_named_node (node, "Click")) == 0) {
1311 warning << _("Session: XML state has no click section") << endmsg;
1312 } else if (_click_io) {
1313 _click_io->set_state (*child);
1316 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1317 ControlProtocolManager::instance().set_protocol_states (*child);
1320 /* here beginneth the second phase ... */
1322 StateReady (); /* EMIT SIGNAL */
1331 Session::load_routes (const XMLNode& node)
1334 XMLNodeConstIterator niter;
1335 RouteList new_routes;
1337 nlist = node.children();
1341 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1343 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1346 error << _("Session: cannot create Route from XML description.") << endmsg;
1350 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1352 new_routes.push_back (route);
1355 add_routes (new_routes, false);
1360 boost::shared_ptr<Route>
1361 Session::XMLRouteFactory (const XMLNode& node)
1363 if (node.name() != "Route") {
1364 return boost::shared_ptr<Route> ((Route*) 0);
1367 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1369 DataType type = DataType::AUDIO;
1370 const XMLProperty* prop = node.property("default-type");
1373 type = DataType(prop->value());
1376 assert(type != DataType::NIL);
1378 if (has_diskstream) {
1379 if (type == DataType::AUDIO) {
1380 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1383 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1387 boost::shared_ptr<Route> ret (new Route (*this, node));
1393 Session::load_regions (const XMLNode& node)
1396 XMLNodeConstIterator niter;
1397 boost::shared_ptr<Region> region;
1399 nlist = node.children();
1403 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1404 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1405 error << _("Session: cannot create Region from XML description.");
1406 const XMLProperty *name = (**niter).property("name");
1409 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1419 boost::shared_ptr<Region>
1420 Session::XMLRegionFactory (const XMLNode& node, bool full)
1422 const XMLProperty* type = node.property("type");
1426 if ( !type || type->value() == "audio" ) {
1428 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1430 } else if (type->value() == "midi") {
1432 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1436 } catch (failed_constructor& err) {
1437 return boost::shared_ptr<Region> ();
1440 return boost::shared_ptr<Region> ();
1443 boost::shared_ptr<AudioRegion>
1444 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1446 const XMLProperty* prop;
1447 boost::shared_ptr<Source> source;
1448 boost::shared_ptr<AudioSource> as;
1450 SourceList master_sources;
1451 uint32_t nchans = 1;
1454 if (node.name() != X_("Region")) {
1455 return boost::shared_ptr<AudioRegion>();
1458 if ((prop = node.property (X_("channels"))) != 0) {
1459 nchans = atoi (prop->value().c_str());
1462 if ((prop = node.property ("name")) == 0) {
1463 cerr << "no name for this region\n";
1467 if ((prop = node.property (X_("source-0"))) == 0) {
1468 if ((prop = node.property ("source")) == 0) {
1469 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1470 return boost::shared_ptr<AudioRegion>();
1474 PBD::ID s_id (prop->value());
1476 if ((source = source_by_id (s_id)) == 0) {
1477 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1478 return boost::shared_ptr<AudioRegion>();
1481 as = boost::dynamic_pointer_cast<AudioSource>(source);
1483 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1484 return boost::shared_ptr<AudioRegion>();
1487 sources.push_back (as);
1489 /* pickup other channels */
1491 for (uint32_t n=1; n < nchans; ++n) {
1492 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1493 if ((prop = node.property (buf)) != 0) {
1495 PBD::ID id2 (prop->value());
1497 if ((source = source_by_id (id2)) == 0) {
1498 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1499 return boost::shared_ptr<AudioRegion>();
1502 as = boost::dynamic_pointer_cast<AudioSource>(source);
1504 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1505 return boost::shared_ptr<AudioRegion>();
1507 sources.push_back (as);
1511 for (uint32_t n=1; n < nchans; ++n) {
1512 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1513 if ((prop = node.property (buf)) != 0) {
1515 PBD::ID id2 (prop->value());
1517 if ((source = source_by_id (id2)) == 0) {
1518 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1519 return boost::shared_ptr<AudioRegion>();
1522 as = boost::dynamic_pointer_cast<AudioSource>(source);
1524 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1525 return boost::shared_ptr<AudioRegion>();
1527 master_sources.push_back (as);
1532 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1534 /* a final detail: this is the one and only place that we know how long missing files are */
1536 if (region->whole_file()) {
1537 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1538 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1540 sfp->set_length (region->length());
1545 if (!master_sources.empty()) {
1546 if (master_sources.size() == nchans) {
1547 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1549 region->set_master_sources (master_sources);
1557 catch (failed_constructor& err) {
1558 return boost::shared_ptr<AudioRegion>();
1562 boost::shared_ptr<MidiRegion>
1563 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1565 const XMLProperty* prop;
1566 boost::shared_ptr<Source> source;
1567 boost::shared_ptr<MidiSource> ms;
1569 uint32_t nchans = 1;
1571 if (node.name() != X_("Region")) {
1572 return boost::shared_ptr<MidiRegion>();
1575 if ((prop = node.property (X_("channels"))) != 0) {
1576 nchans = atoi (prop->value().c_str());
1579 if ((prop = node.property ("name")) == 0) {
1580 cerr << "no name for this region\n";
1584 // Multiple midi channels? that's just crazy talk
1585 assert(nchans == 1);
1587 if ((prop = node.property (X_("source-0"))) == 0) {
1588 if ((prop = node.property ("source")) == 0) {
1589 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1590 return boost::shared_ptr<MidiRegion>();
1594 PBD::ID s_id (prop->value());
1596 if ((source = source_by_id (s_id)) == 0) {
1597 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1598 return boost::shared_ptr<MidiRegion>();
1601 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1603 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1604 return boost::shared_ptr<MidiRegion>();
1607 sources.push_back (ms);
1610 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1611 /* a final detail: this is the one and only place that we know how long missing files are */
1613 if (region->whole_file()) {
1614 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1615 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1617 sfp->set_length (region->length());
1625 catch (failed_constructor& err) {
1626 return boost::shared_ptr<MidiRegion>();
1631 Session::get_sources_as_xml ()
1634 XMLNode* node = new XMLNode (X_("Sources"));
1635 Glib::Mutex::Lock lm (source_lock);
1637 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1638 node->add_child_nocopy (i->second->get_state());
1645 Session::path_from_region_name (DataType type, string name, string identifier)
1647 char buf[PATH_MAX+1];
1649 SessionDirectory sdir(get_best_session_directory_for_new_source());
1650 sys::path source_dir = ((type == DataType::AUDIO)
1651 ? sdir.sound_path() : sdir.midi_path());
1653 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1655 for (n = 0; n < 999999; ++n) {
1656 if (identifier.length()) {
1657 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1658 identifier.c_str(), n, ext.c_str());
1660 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1664 sys::path source_path = source_dir / buf;
1666 if (!sys::exists (source_path)) {
1667 return source_path.to_string();
1671 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1680 Session::load_sources (const XMLNode& node)
1683 XMLNodeConstIterator niter;
1684 boost::shared_ptr<Source> source;
1686 nlist = node.children();
1690 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1692 if ((source = XMLSourceFactory (**niter)) == 0) {
1693 error << _("Session: cannot create Source from XML description.") << endmsg;
1695 } catch (MissingSource& err) {
1696 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1697 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1704 boost::shared_ptr<Source>
1705 Session::XMLSourceFactory (const XMLNode& node)
1707 if (node.name() != "Source") {
1708 return boost::shared_ptr<Source>();
1712 /* note: do peak building in another thread when loading session state */
1713 return SourceFactory::create (*this, node, true);
1716 catch (failed_constructor& err) {
1717 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1718 return boost::shared_ptr<Source>();
1723 Session::save_template (string template_name)
1727 if (_state_of_the_state & CannotSave) {
1731 sys::path user_template_dir(user_template_directory());
1735 sys::create_directories (user_template_dir);
1737 catch(sys::filesystem_error& ex)
1739 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1740 user_template_dir.to_string(), ex.what()) << endmsg;
1744 tree.set_root (&get_template());
1746 sys::path template_file_path(user_template_dir);
1747 template_file_path /= template_name + template_suffix;
1749 if (sys::exists (template_file_path))
1751 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1752 template_file_path.to_string()) << endmsg;
1756 if (!tree.write (template_file_path.to_string())) {
1757 error << _("mix template not saved") << endmsg;
1765 Session::rename_template (string old_name, string new_name)
1767 sys::path old_path (user_template_directory());
1768 old_path /= old_name + template_suffix;
1770 sys::path new_path(user_template_directory());
1771 new_path /= new_name + template_suffix;
1773 if (sys::exists (new_path)) {
1774 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1775 new_path.to_string()) << endmsg;
1780 sys::rename (old_path, new_path);
1788 Session::delete_template (string name)
1790 sys::path path = user_template_directory();
1791 path /= name + template_suffix;
1802 Session::refresh_disk_space ()
1805 struct statfs statfsbuf;
1806 vector<space_and_path>::iterator i;
1807 Glib::Mutex::Lock lm (space_lock);
1810 /* get freespace on every FS that is part of the session path */
1812 _total_free_4k_blocks = 0;
1814 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1815 statfs ((*i).path.c_str(), &statfsbuf);
1817 scale = statfsbuf.f_bsize/4096.0;
1819 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1820 _total_free_4k_blocks += (*i).blocks;
1826 Session::get_best_session_directory_for_new_source ()
1828 vector<space_and_path>::iterator i;
1829 string result = _session_dir->root_path().to_string();
1831 /* handle common case without system calls */
1833 if (session_dirs.size() == 1) {
1837 /* OK, here's the algorithm we're following here:
1839 We want to select which directory to use for
1840 the next file source to be created. Ideally,
1841 we'd like to use a round-robin process so as to
1842 get maximum performance benefits from splitting
1843 the files across multiple disks.
1845 However, in situations without much diskspace, an
1846 RR approach may end up filling up a filesystem
1847 with new files while others still have space.
1848 Its therefore important to pay some attention to
1849 the freespace in the filesystem holding each
1850 directory as well. However, if we did that by
1851 itself, we'd keep creating new files in the file
1852 system with the most space until it was as full
1853 as all others, thus negating any performance
1854 benefits of this RAID-1 like approach.
1856 So, we use a user-configurable space threshold. If
1857 there are at least 2 filesystems with more than this
1858 much space available, we use RR selection between them.
1859 If not, then we pick the filesystem with the most space.
1861 This gets a good balance between the two
1865 refresh_disk_space ();
1867 int free_enough = 0;
1869 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1870 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1875 if (free_enough >= 2) {
1876 /* use RR selection process, ensuring that the one
1880 i = last_rr_session_dir;
1883 if (++i == session_dirs.end()) {
1884 i = session_dirs.begin();
1887 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1888 if (create_session_directory ((*i).path)) {
1890 last_rr_session_dir = i;
1895 } while (i != last_rr_session_dir);
1899 /* pick FS with the most freespace (and that
1900 seems to actually work ...)
1903 vector<space_and_path> sorted;
1904 space_and_path_ascending_cmp cmp;
1906 sorted = session_dirs;
1907 sort (sorted.begin(), sorted.end(), cmp);
1909 for (i = sorted.begin(); i != sorted.end(); ++i) {
1910 if (create_session_directory ((*i).path)) {
1912 last_rr_session_dir = i;
1922 Session::load_playlists (const XMLNode& node)
1925 XMLNodeConstIterator niter;
1926 boost::shared_ptr<Playlist> playlist;
1928 nlist = node.children();
1932 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1934 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1935 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1943 Session::load_unused_playlists (const XMLNode& node)
1946 XMLNodeConstIterator niter;
1947 boost::shared_ptr<Playlist> playlist;
1949 nlist = node.children();
1953 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1955 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1956 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1960 // now manually untrack it
1962 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1968 boost::shared_ptr<Playlist>
1969 Session::XMLPlaylistFactory (const XMLNode& node)
1972 return PlaylistFactory::create (*this, node);
1975 catch (failed_constructor& err) {
1976 return boost::shared_ptr<Playlist>();
1981 Session::load_named_selections (const XMLNode& node)
1984 XMLNodeConstIterator niter;
1987 nlist = node.children();
1991 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1993 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1994 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2002 Session::XMLNamedSelectionFactory (const XMLNode& node)
2005 return new NamedSelection (*this, node);
2008 catch (failed_constructor& err) {
2014 Session::automation_dir () const
2016 return Glib::build_filename (_path, "automation");
2020 Session::analysis_dir () const
2022 return Glib::build_filename (_path, "analysis");
2026 Session::load_bundles (XMLNode const & node)
2028 XMLNodeList nlist = node.children();
2029 XMLNodeConstIterator niter;
2033 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2034 if ((*niter)->name() == "InputBundle") {
2035 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2036 } else if ((*niter)->name() == "OutputBundle") {
2037 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2039 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2048 Session::load_edit_groups (const XMLNode& node)
2050 return load_route_groups (node, true);
2054 Session::load_mix_groups (const XMLNode& node)
2056 return load_route_groups (node, false);
2060 Session::load_route_groups (const XMLNode& node, bool edit)
2062 XMLNodeList nlist = node.children();
2063 XMLNodeConstIterator niter;
2068 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2069 if ((*niter)->name() == "RouteGroup") {
2071 rg = add_edit_group ("");
2072 rg->set_state (**niter);
2074 rg = add_mix_group ("");
2075 rg->set_state (**niter);
2084 Session::auto_save()
2086 save_state (_current_snapshot_name);
2090 state_file_filter (const string &str, void *arg)
2092 return (str.length() > strlen(statefile_suffix) &&
2093 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2097 bool operator()(const string* a, const string* b) {
2103 remove_end(string* state)
2105 string statename(*state);
2107 string::size_type start,end;
2108 if ((start = statename.find_last_of ('/')) != string::npos) {
2109 statename = statename.substr (start+1);
2112 if ((end = statename.rfind(".ardour")) == string::npos) {
2113 end = statename.length();
2116 return new string(statename.substr (0, end));
2120 Session::possible_states (string path)
2122 PathScanner scanner;
2123 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2125 transform(states->begin(), states->end(), states->begin(), remove_end);
2128 sort (states->begin(), states->end(), cmp);
2134 Session::possible_states () const
2136 return possible_states(_path);
2140 Session::add_edit_group (string name)
2142 RouteGroup* rg = new RouteGroup (*this, name);
2143 edit_groups.push_back (rg);
2144 edit_group_added (rg); /* EMIT SIGNAL */
2150 Session::add_mix_group (string name)
2152 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2153 mix_groups.push_back (rg);
2154 mix_group_added (rg); /* EMIT SIGNAL */
2160 Session::remove_edit_group (RouteGroup& rg)
2162 list<RouteGroup*>::iterator i;
2164 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2165 (*i)->apply (&Route::drop_edit_group, this);
2166 edit_groups.erase (i);
2167 edit_group_removed (); /* EMIT SIGNAL */
2174 Session::remove_mix_group (RouteGroup& rg)
2176 list<RouteGroup*>::iterator i;
2178 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2179 (*i)->apply (&Route::drop_mix_group, this);
2180 mix_groups.erase (i);
2181 mix_group_removed (); /* EMIT SIGNAL */
2188 Session::mix_group_by_name (string name)
2190 list<RouteGroup *>::iterator i;
2192 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2193 if ((*i)->name() == name) {
2201 Session::edit_group_by_name (string name)
2203 list<RouteGroup *>::iterator i;
2205 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2206 if ((*i)->name() == name) {
2214 Session::begin_reversible_command(const string& name)
2216 UndoTransaction* trans = new UndoTransaction();
2217 trans->set_name(name);
2218 if (!_current_trans.empty()) {
2219 _current_trans.top()->add_command(trans);
2221 _current_trans.push(trans);
2225 Session::commit_reversible_command(Command *cmd)
2227 assert(!_current_trans.empty());
2231 _current_trans.top()->add_command(cmd);
2234 if (_current_trans.top()->empty()) {
2235 _current_trans.pop();
2239 gettimeofday(&now, 0);
2240 _current_trans.top()->set_timestamp(now);
2242 _history.add(_current_trans.top());
2243 _current_trans.pop();
2246 Session::GlobalRouteBooleanState
2247 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2249 GlobalRouteBooleanState s;
2250 boost::shared_ptr<RouteList> r = routes.reader ();
2252 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2253 if (!(*i)->is_hidden()) {
2254 RouteBooleanState v;
2257 Route* r = (*i).get();
2258 v.second = (r->*method)();
2267 Session::GlobalRouteMeterState
2268 Session::get_global_route_metering ()
2270 GlobalRouteMeterState s;
2271 boost::shared_ptr<RouteList> r = routes.reader ();
2273 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2274 if (!(*i)->is_hidden()) {
2278 v.second = (*i)->meter_point();
2288 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2290 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2292 boost::shared_ptr<Route> r = (i->first.lock());
2295 r->set_meter_point (i->second, arg);
2301 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2303 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2305 boost::shared_ptr<Route> r = (i->first.lock());
2308 Route* rp = r.get();
2309 (rp->*method) (i->second, arg);
2315 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2317 set_global_route_boolean (s, &Route::set_mute, src);
2321 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2323 set_global_route_boolean (s, &Route::set_solo, src);
2327 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2329 set_global_route_boolean (s, &Route::set_record_enable, src);
2333 accept_all_non_peak_files (const string& path, void *arg)
2335 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2339 accept_all_state_files (const string& path, void *arg)
2341 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2345 Session::find_all_sources (string path, set<string>& result)
2350 if (!tree.read (path)) {
2354 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2359 XMLNodeConstIterator niter;
2361 nlist = node->children();
2365 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2369 if ((prop = (*niter)->property (X_("name"))) == 0) {
2373 if (prop->value()[0] == '/') {
2374 /* external file, ignore */
2378 sys::path source_path = _session_dir->sound_path ();
2380 source_path /= prop->value ();
2382 result.insert (source_path.to_string ());
2389 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2391 PathScanner scanner;
2392 vector<string*>* state_files;
2394 string this_snapshot_path;
2400 if (ripped[ripped.length()-1] == '/') {
2401 ripped = ripped.substr (0, ripped.length() - 1);
2404 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2406 if (state_files == 0) {
2411 this_snapshot_path = _path;
2412 this_snapshot_path += _current_snapshot_name;
2413 this_snapshot_path += statefile_suffix;
2415 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2417 if (exclude_this_snapshot && **i == this_snapshot_path) {
2421 if (find_all_sources (**i, result) < 0) {
2429 struct RegionCounter {
2430 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2431 AudioSourceList::iterator iter;
2432 boost::shared_ptr<Region> region;
2435 RegionCounter() : count (0) {}
2439 Session::cleanup_sources (Session::cleanup_report& rep)
2441 // FIXME: needs adaptation to midi
2443 vector<boost::shared_ptr<Source> > dead_sources;
2444 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2445 PathScanner scanner;
2447 vector<space_and_path>::iterator i;
2448 vector<space_and_path>::iterator nexti;
2449 vector<string*>* soundfiles;
2450 vector<string> unused;
2451 set<string> all_sources;
2456 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2459 /* step 1: consider deleting all unused playlists */
2461 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2464 status = AskAboutPlaylistDeletion (*x);
2473 playlists_tbd.push_back (*x);
2477 /* leave it alone */
2482 /* now delete any that were marked for deletion */
2484 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2485 (*x)->drop_references ();
2488 playlists_tbd.clear ();
2490 /* step 2: find all un-used sources */
2495 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2497 SourceMap::iterator tmp;
2502 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2506 if (!i->second->used() && i->second->length(i->second->timeline_position()) > 0) {
2507 dead_sources.push_back (i->second);
2508 i->second->GoingAway();
2514 /* build a list of all the possible sound directories for the session */
2516 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2521 SessionDirectory sdir ((*i).path);
2522 sound_path += sdir.sound_path().to_string();
2524 if (nexti != session_dirs.end()) {
2531 /* now do the same thing for the files that ended up in the sounds dir(s)
2532 but are not referenced as sources in any snapshot.
2535 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2537 if (soundfiles == 0) {
2541 /* find all sources, but don't use this snapshot because the
2542 state file on disk still references sources we may have already
2546 find_all_sources_across_snapshots (all_sources, true);
2548 /* add our current source list
2551 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2552 boost::shared_ptr<FileSource> fs;
2554 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2555 all_sources.insert (fs->path());
2559 char tmppath1[PATH_MAX+1];
2560 char tmppath2[PATH_MAX+1];
2562 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2567 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2569 realpath(spath.c_str(), tmppath1);
2570 realpath((*i).c_str(), tmppath2);
2572 if (strcmp(tmppath1, tmppath2) == 0) {
2579 unused.push_back (spath);
2583 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2585 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2586 struct stat statbuf;
2588 rep.paths.push_back (*x);
2589 if (stat ((*x).c_str(), &statbuf) == 0) {
2590 rep.space += statbuf.st_size;
2595 /* don't move the file across filesystems, just
2596 stick it in the `dead_sound_dir_name' directory
2597 on whichever filesystem it was already on.
2600 if ((*x).find ("/sounds/") != string::npos) {
2602 /* old school, go up 1 level */
2604 newpath = Glib::path_get_dirname (*x); // "sounds"
2605 newpath = Glib::path_get_dirname (newpath); // "session-name"
2609 /* new school, go up 4 levels */
2611 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2612 newpath = Glib::path_get_dirname (newpath); // "session-name"
2613 newpath = Glib::path_get_dirname (newpath); // "interchange"
2614 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2618 newpath += dead_sound_dir_name;
2620 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2621 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2626 newpath += Glib::path_get_basename ((*x));
2628 if (access (newpath.c_str(), F_OK) == 0) {
2630 /* the new path already exists, try versioning */
2632 char buf[PATH_MAX+1];
2636 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2639 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2640 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2644 if (version == 999) {
2645 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2649 newpath = newpath_v;
2654 /* it doesn't exist, or we can't read it or something */
2658 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2659 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2660 (*x), newpath, strerror (errno))
2665 /* see if there an easy to find peakfile for this file, and remove it.
2668 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2669 peakpath += peakfile_suffix;
2671 if (access (peakpath.c_str(), W_OK) == 0) {
2672 if (::unlink (peakpath.c_str()) != 0) {
2673 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2674 peakpath, _path, strerror (errno))
2676 /* try to back out */
2677 rename (newpath.c_str(), _path.c_str());
2685 /* dump the history list */
2689 /* save state so we don't end up a session file
2690 referring to non-existent sources.
2696 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2702 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2704 // FIXME: needs adaptation for MIDI
2706 vector<space_and_path>::iterator i;
2707 string dead_sound_dir;
2708 struct dirent* dentry;
2709 struct stat statbuf;
2715 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2717 dead_sound_dir = (*i).path;
2718 dead_sound_dir += dead_sound_dir_name;
2720 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2724 while ((dentry = readdir (dead)) != 0) {
2726 /* avoid '.' and '..' */
2728 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2729 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2735 fullpath = dead_sound_dir;
2737 fullpath += dentry->d_name;
2739 if (stat (fullpath.c_str(), &statbuf)) {
2743 if (!S_ISREG (statbuf.st_mode)) {
2747 if (unlink (fullpath.c_str())) {
2748 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2749 fullpath, strerror (errno))
2753 rep.paths.push_back (dentry->d_name);
2754 rep.space += statbuf.st_size;
2765 Session::set_dirty ()
2767 bool was_dirty = dirty();
2769 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2773 DirtyChanged(); /* EMIT SIGNAL */
2779 Session::set_clean ()
2781 bool was_dirty = dirty();
2783 _state_of_the_state = Clean;
2787 DirtyChanged(); /* EMIT SIGNAL */
2792 Session::set_deletion_in_progress ()
2794 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2798 Session::clear_deletion_in_progress ()
2800 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2804 Session::add_controllable (boost::shared_ptr<Controllable> c)
2806 /* this adds a controllable to the list managed by the Session.
2807 this is a subset of those managed by the Controllable class
2808 itself, and represents the only ones whose state will be saved
2809 as part of the session.
2812 Glib::Mutex::Lock lm (controllables_lock);
2813 controllables.insert (c);
2816 struct null_deleter { void operator()(void const *) const {} };
2819 Session::remove_controllable (Controllable* c)
2821 if (_state_of_the_state | Deletion) {
2825 Glib::Mutex::Lock lm (controllables_lock);
2827 Controllables::iterator x = controllables.find(
2828 boost::shared_ptr<Controllable>(c, null_deleter()));
2830 if (x != controllables.end()) {
2831 controllables.erase (x);
2835 boost::shared_ptr<Controllable>
2836 Session::controllable_by_id (const PBD::ID& id)
2838 Glib::Mutex::Lock lm (controllables_lock);
2840 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2841 if ((*i)->id() == id) {
2846 return boost::shared_ptr<Controllable>();
2850 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2852 Stateful::add_instant_xml (node, _path);
2853 if (write_to_config) {
2854 Config->add_instant_xml (node);
2859 Session::instant_xml (const string& node_name)
2861 return Stateful::instant_xml (node_name, _path);
2865 Session::save_history (string snapshot_name)
2869 if (snapshot_name.empty()) {
2870 snapshot_name = _current_snapshot_name;
2873 const string history_filename = snapshot_name + history_suffix;
2874 const string backup_filename = history_filename + backup_suffix;
2875 const sys::path xml_path = _session_dir->root_path() / history_filename;
2876 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2878 if (sys::exists (xml_path)) {
2881 sys::rename (xml_path, backup_path);
2883 catch (const sys::filesystem_error& err)
2885 error << _("could not backup old history file, current history not saved") << endmsg;
2891 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2895 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2897 if (!tree.write (xml_path.to_string()))
2899 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2903 sys::remove (xml_path);
2904 sys::rename (backup_path, xml_path);
2906 catch (const sys::filesystem_error& err)
2908 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2909 backup_path.to_string(), err.what()) << endmsg;
2919 Session::restore_history (string snapshot_name)
2923 if (snapshot_name.empty()) {
2924 snapshot_name = _current_snapshot_name;
2927 const string xml_filename = snapshot_name + history_suffix;
2928 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2930 cerr << "Loading history from " << xml_path.to_string() << endmsg;
2932 if (!sys::exists (xml_path)) {
2933 info << string_compose (_("%1: no history file \"%2\" for this session."),
2934 _name, xml_path.to_string()) << endmsg;
2938 if (!tree.read (xml_path.to_string())) {
2939 error << string_compose (_("Could not understand session history file \"%1\""),
2940 xml_path.to_string()) << endmsg;
2947 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2950 UndoTransaction* ut = new UndoTransaction ();
2953 ut->set_name(t->property("name")->value());
2954 stringstream ss(t->property("tv-sec")->value());
2956 ss.str(t->property("tv-usec")->value());
2958 ut->set_timestamp(tv);
2960 for (XMLNodeConstIterator child_it = t->children().begin();
2961 child_it != t->children().end(); child_it++)
2963 XMLNode *n = *child_it;
2966 if (n->name() == "MementoCommand" ||
2967 n->name() == "MementoUndoCommand" ||
2968 n->name() == "MementoRedoCommand") {
2970 if ((c = memento_command_factory(n))) {
2974 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2976 if ((c = global_state_command_factory (*n))) {
2977 ut->add_command (c);
2980 } else if (n->name() == "DeltaCommand") {
2981 PBD::ID id(n->property("midi-source")->value());
2982 boost::shared_ptr<MidiSource> midi_source =
2983 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2985 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
2987 error << "FIXME: Failed to downcast MidiSource for DeltaCommand" << endmsg;
2990 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3001 Session::config_changed (std::string p, bool ours)
3007 if (p == "seamless-loop") {
3009 } else if (p == "rf-speed") {
3011 } else if (p == "auto-loop") {
3013 } else if (p == "auto-input") {
3015 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3016 /* auto-input only makes a difference if we're rolling */
3018 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3020 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3021 if ((*i)->record_enabled ()) {
3022 (*i)->monitor_input (!config.get_auto_input());
3027 } else if (p == "punch-in") {
3031 if ((location = _locations.auto_punch_location()) != 0) {
3033 if (config.get_punch_in ()) {
3034 replace_event (Event::PunchIn, location->start());
3036 remove_event (location->start(), Event::PunchIn);
3040 } else if (p == "punch-out") {
3044 if ((location = _locations.auto_punch_location()) != 0) {
3046 if (config.get_punch_out()) {
3047 replace_event (Event::PunchOut, location->end());
3049 clear_events (Event::PunchOut);
3053 } else if (p == "edit-mode") {
3055 Glib::Mutex::Lock lm (playlist_lock);
3057 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3058 (*i)->set_edit_mode (Config->get_edit_mode ());
3061 } else if (p == "use-video-sync") {
3063 waiting_for_sync_offset = config.get_use_video_sync();
3065 } else if (p == "mmc-control") {
3067 //poke_midi_thread ();
3069 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3072 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3075 } else if (p == "mmc-send-id") {
3078 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3081 } else if (p == "midi-control") {
3083 //poke_midi_thread ();
3085 } else if (p == "raid-path") {
3087 setup_raid_path (config.get_raid_path());
3089 } else if (p == "smpte-format") {
3093 } else if (p == "video-pullup") {
3097 } else if (p == "seamless-loop") {
3099 if (play_loop && transport_rolling()) {
3100 // to reset diskstreams etc
3101 request_play_loop (true);
3104 } else if (p == "rf-speed") {
3106 cumulative_rf_motion = 0;
3109 } else if (p == "click-sound") {
3111 setup_click_sounds (1);
3113 } else if (p == "click-emphasis-sound") {
3115 setup_click_sounds (-1);
3117 } else if (p == "clicking") {
3119 if (Config->get_clicking()) {
3120 if (_click_io && click_data) { // don't require emphasis data
3127 } else if (p == "send-mtc") {
3129 /* only set the internal flag if we have
3133 if (_mtc_port != 0) {
3134 session_send_mtc = Config->get_send_mtc();
3135 if (session_send_mtc) {
3136 /* mark us ready to send */
3137 next_quarter_frame_to_send = 0;
3140 session_send_mtc = false;
3143 } else if (p == "send-mmc") {
3145 /* only set the internal flag if we have
3149 if (_mmc_port != 0) {
3150 session_send_mmc = Config->get_send_mmc();
3153 session_send_mmc = false;
3156 } else if (p == "midi-feedback") {
3158 /* only set the internal flag if we have
3162 if (_mtc_port != 0) {
3163 session_midi_feedback = Config->get_midi_feedback();
3166 } else if (p == "jack-time-master") {
3168 engine().reset_timebase ();
3170 } else if (p == "native-file-header-format") {
3172 if (!first_file_header_format_reset) {
3173 reset_native_file_format ();
3176 first_file_header_format_reset = false;
3178 } else if (p == "native-file-data-format") {
3180 if (!first_file_data_format_reset) {
3181 reset_native_file_format ();
3184 first_file_data_format_reset = false;
3186 } else if (p == "slave-source") {
3187 set_slave_source (Config->get_slave_source());
3188 } else if (p == "remote-model") {
3189 set_remote_control_ids ();
3190 } else if (p == "denormal-model") {
3192 } else if (p == "history-depth") {
3193 set_history_depth (Config->get_history_depth());
3194 } else if (p == "sync-all-route-ordering") {
3195 sync_order_keys ("session");
3196 } else if (p == "initial-program-change") {
3198 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3201 buf[0] = MIDI::program; // channel zero by default
3202 buf[1] = (Config->get_initial_program_change() & 0x7f);
3204 _mmc_port->midimsg (buf, sizeof (buf), 0);
3206 } else if (p == "initial-program-change") {
3208 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3209 MIDI::byte* buf = new MIDI::byte[2];
3211 buf[0] = MIDI::program; // channel zero by default
3212 buf[1] = (Config->get_initial_program_change() & 0x7f);
3213 // deliver_midi (_mmc_port, buf, 2);
3215 } else if (p == "solo-mute-override") {
3216 // catch_up_on_solo_mute_override ();
3223 Session::set_history_depth (uint32_t d)
3225 _history.set_depth (d);