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 _target_transport_speed = 0;
160 auto_play_legal = false;
161 transport_sub_state = 0;
162 _transport_frame = 0;
163 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
164 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
165 g_atomic_int_set (&_record_status, Disabled);
166 loop_changing = false;
169 _last_roll_location = 0;
170 _last_record_location = 0;
171 pending_locate_frame = 0;
172 pending_locate_roll = false;
173 pending_locate_flush = false;
174 audio_dstream_buffer_size = 0;
175 midi_dstream_buffer_size = 0;
176 state_was_pending = false;
178 outbound_mtc_smpte_frame = 0;
179 next_quarter_frame_to_send = -1;
180 current_block_size = 0;
181 solo_update_disabled = false;
182 currently_soloing = false;
183 _have_captured = false;
184 _worst_output_latency = 0;
185 _worst_input_latency = 0;
186 _worst_track_latency = 0;
187 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
190 session_send_mmc = false;
191 session_send_mtc = false;
192 post_transport_work = PostTransportWork (0);
193 g_atomic_int_set (&butler_should_do_transport_work, 0);
194 g_atomic_int_set (&_playback_load, 100);
195 g_atomic_int_set (&_capture_load, 100);
196 g_atomic_int_set (&_playback_load_min, 100);
197 g_atomic_int_set (&_capture_load_min, 100);
200 _exporting_realtime = false;
201 _gain_automation_buffer = 0;
202 _pan_automation_buffer = 0;
204 pending_abort = false;
205 destructive_index = 0;
206 first_file_data_format_reset = true;
207 first_file_header_format_reset = true;
208 butler_thread = (pthread_t) 0;
209 //midi_thread = (pthread_t) 0;
211 AudioDiskstream::allocate_working_buffers();
213 /* default short fade = 15ms */
215 Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
216 SndFileSource::setup_standard_crossfades (*this, frame_rate());
218 last_mmc_step.tv_sec = 0;
219 last_mmc_step.tv_usec = 0;
222 /* click sounds are unset by default, which causes us to internal
223 waveforms for clicks.
227 click_emphasis_length = 0;
230 process_function = &Session::process_with_events;
232 if (config.get_use_video_sync()) {
233 waiting_for_sync_offset = true;
235 waiting_for_sync_offset = false;
240 _smpte_offset_negative = true;
241 last_smpte_valid = false;
245 last_rr_session_dir = session_dirs.begin();
246 refresh_disk_space ();
248 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
252 average_slave_delta = 1800; // !!! why 1800 ????
253 have_first_delta_accumulator = false;
254 delta_accumulator_cnt = 0;
255 slave_state = Stopped;
257 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
259 /* These are all static "per-class" signals */
261 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
262 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
263 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
264 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
265 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
266 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
268 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
270 IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
272 /* stop IO objects from doing stuff until we're ready for them */
274 Delivery::disable_panners ();
275 IO::disable_connecting ();
279 Session::second_stage_init (bool new_session)
281 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
284 if (load_state (_current_snapshot_name)) {
287 remove_empty_sounds ();
290 if (start_butler_thread()) {
294 if (start_midi_thread ()) {
298 // set_state() will call setup_raid_path(), but if it's a new session we need
299 // to call setup_raid_path() here.
302 if (set_state (*state_tree->root())) {
306 setup_raid_path(_path);
309 /* we can't save till after ::when_engine_running() is called,
310 because otherwise we save state with no connections made.
311 therefore, we reset _state_of_the_state because ::set_state()
312 will have cleared it.
314 we also have to include Loading so that any events that get
315 generated between here and the end of ::when_engine_running()
316 will be processed directly rather than queued.
319 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
322 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
323 _locations.added.connect (mem_fun (this, &Session::locations_added));
324 setup_click_sounds (0);
325 setup_midi_control ();
327 /* Pay attention ... */
329 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
330 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
333 when_engine_running();
336 /* handle this one in a different way than all others, so that its clear what happened */
338 catch (AudioEngine::PortRegistrationFailure& err) {
339 error << err.what() << endmsg;
347 BootMessage (_("Reset Remote Controls"));
349 send_full_time_code (0);
350 _engine.transport_locate (0);
351 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
352 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
354 MidiClockTicker::instance().set_session(*this);
355 MIDI::Name::MidiPatchManager::instance().set_session(*this);
357 /* initial program change will be delivered later; see ::config_changed() */
359 BootMessage (_("Reset Control Protocols"));
361 ControlProtocolManager::instance().set_session (*this);
363 config.set_end_marker_is_free (new_session);
365 _state_of_the_state = Clean;
367 DirtyChanged (); /* EMIT SIGNAL */
369 if (state_was_pending) {
370 save_state (_current_snapshot_name);
371 remove_pending_capture_state ();
372 state_was_pending = false;
375 BootMessage (_("Session loading complete"));
381 Session::raid_path () const
383 SearchPath raid_search_path;
385 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
386 raid_search_path += sys::path((*i).path);
389 return raid_search_path.to_string ();
393 Session::setup_raid_path (string path)
402 session_dirs.clear ();
404 SearchPath search_path(path);
405 SearchPath sound_search_path;
406 SearchPath midi_search_path;
408 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
409 sp.path = (*i).to_string ();
410 sp.blocks = 0; // not needed
411 session_dirs.push_back (sp);
413 SessionDirectory sdir(sp.path);
415 sound_search_path += sdir.sound_path ();
416 midi_search_path += sdir.midi_path ();
419 // set the search path for each data type
420 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
421 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
423 // reset the round-robin soundfile path thingie
424 last_rr_session_dir = session_dirs.begin();
428 Session::ensure_subdirs ()
432 dir = session_directory().peak_path().to_string();
434 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
435 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
439 dir = session_directory().sound_path().to_string();
441 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
442 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
446 dir = session_directory().midi_path().to_string();
448 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
449 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
453 dir = session_directory().dead_sound_path().to_string();
455 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
456 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
460 dir = session_directory().export_path().to_string();
462 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
463 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
467 dir = analysis_dir ();
469 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
470 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
478 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
481 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
482 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
486 if (ensure_subdirs ()) {
490 /* check new_session so we don't overwrite an existing one */
492 if (!mix_template.empty()) {
493 std::string in_path = mix_template;
495 ifstream in(in_path.c_str());
498 string out_path = _path;
500 out_path += statefile_suffix;
502 ofstream out(out_path.c_str());
507 // okay, session is set up. Treat like normal saved
508 // session from now on.
514 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
520 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
527 /* Instantiate metadata */
529 _metadata = new SessionMetadata ();
531 /* set initial start + end point */
533 start_location->set_end (0);
534 _locations.add (start_location);
536 end_location->set_end (initial_length);
537 _locations.add (end_location);
539 _state_of_the_state = Clean;
548 Session::load_diskstreams (const XMLNode& node)
551 XMLNodeConstIterator citer;
553 clist = node.children();
555 for (citer = clist.begin(); citer != clist.end(); ++citer) {
558 /* diskstreams added automatically by DiskstreamCreated handler */
559 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
560 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
561 add_diskstream (dstream);
562 } else if ((*citer)->name() == "MidiDiskstream") {
563 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
564 add_diskstream (dstream);
566 error << _("Session: unknown diskstream type in XML") << endmsg;
570 catch (failed_constructor& err) {
571 error << _("Session: could not load diskstream via XML state") << endmsg;
580 Session::maybe_write_autosave()
582 if (dirty() && record_status() != Recording) {
583 save_state("", true);
588 Session::remove_pending_capture_state ()
590 sys::path pending_state_file_path(_session_dir->root_path());
592 pending_state_file_path /= _current_snapshot_name + pending_suffix;
596 sys::remove (pending_state_file_path);
598 catch(sys::filesystem_error& ex)
600 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
601 pending_state_file_path.to_string(), ex.what()) << endmsg;
605 /** Rename a state file.
606 * @param snapshot_name Snapshot name.
609 Session::rename_state (string old_name, string new_name)
611 if (old_name == _current_snapshot_name || old_name == _name) {
612 /* refuse to rename the current snapshot or the "main" one */
616 const string old_xml_filename = old_name + statefile_suffix;
617 const string new_xml_filename = new_name + statefile_suffix;
619 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
620 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
624 sys::rename (old_xml_path, new_xml_path);
626 catch (const sys::filesystem_error& err)
628 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
629 old_name, new_name, err.what()) << endmsg;
633 /** Remove a state file.
634 * @param snapshot_name Snapshot name.
637 Session::remove_state (string snapshot_name)
639 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
640 // refuse to remove the current snapshot or the "main" one
644 sys::path xml_path(_session_dir->root_path());
646 xml_path /= snapshot_name + statefile_suffix;
648 if (!create_backup_file (xml_path)) {
649 // don't remove it if a backup can't be made
650 // create_backup_file will log the error.
655 sys::remove (xml_path);
659 Session::save_state (string snapshot_name, bool pending)
662 sys::path xml_path(_session_dir->root_path());
664 if (_state_of_the_state & CannotSave) {
668 if (!_engine.connected ()) {
669 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
674 /* tell sources we're saving first, in case they write out to a new file
675 * which should be saved with the state rather than the old one */
676 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
677 i->second->session_saved();
679 tree.set_root (&get_state());
681 if (snapshot_name.empty()) {
682 snapshot_name = _current_snapshot_name;
687 /* proper save: use statefile_suffix (.ardour in English) */
689 xml_path /= snapshot_name + statefile_suffix;
691 /* make a backup copy of the old file */
693 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
694 // create_backup_file will log the error
700 /* pending save: use pending_suffix (.pending in English) */
701 xml_path /= snapshot_name + pending_suffix;
704 sys::path tmp_path(_session_dir->root_path());
706 tmp_path /= snapshot_name + temp_suffix;
708 // cerr << "actually writing state to " << xml_path.to_string() << endl;
710 if (!tree.write (tmp_path.to_string())) {
711 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
712 sys::remove (tmp_path);
717 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
718 error << string_compose (_("could not rename temporary session file %1 to %2"),
719 tmp_path.to_string(), xml_path.to_string()) << endmsg;
720 sys::remove (tmp_path);
727 save_history (snapshot_name);
729 bool was_dirty = dirty();
731 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
734 DirtyChanged (); /* EMIT SIGNAL */
737 StateSaved (snapshot_name); /* EMIT SIGNAL */
744 Session::restore_state (string snapshot_name)
746 if (load_state (snapshot_name) == 0) {
747 set_state (*state_tree->root());
754 Session::load_state (string snapshot_name)
759 state_was_pending = false;
761 /* check for leftover pending state from a crashed capture attempt */
763 sys::path xmlpath(_session_dir->root_path());
764 xmlpath /= snapshot_name + pending_suffix;
766 if (sys::exists (xmlpath)) {
768 /* there is pending state from a crashed capture attempt */
770 if (AskAboutPendingState()) {
771 state_was_pending = true;
775 if (!state_was_pending) {
776 xmlpath = _session_dir->root_path();
777 xmlpath /= snapshot_name + statefile_suffix;
780 if (!sys::exists (xmlpath)) {
781 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
785 state_tree = new XMLTree;
789 if (!state_tree->read (xmlpath.to_string())) {
790 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
796 XMLNode& root (*state_tree->root());
798 if (root.name() != X_("Session")) {
799 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
805 const XMLProperty* prop;
806 bool is_old = false; // session is _very_ old (pre-2.0)
808 if ((prop = root.property ("version")) == 0) {
809 /* no version implies very old version of Ardour */
813 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
814 if (major_version < 2) {
821 sys::path backup_path(_session_dir->root_path());
823 backup_path /= snapshot_name + "-1" + statefile_suffix;
825 // only create a backup once
826 if (sys::exists (backup_path)) {
830 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
831 xmlpath.to_string(), backup_path.to_string())
836 sys::copy_file (xmlpath, backup_path);
838 catch(sys::filesystem_error& ex)
840 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
841 xmlpath.to_string(), ex.what())
851 Session::load_options (const XMLNode& node)
853 LocaleGuard lg (X_("POSIX"));
855 config.set_variables (node);
857 /* now reset MIDI ports because the session can have its own
873 Session::get_template()
875 /* if we don't disable rec-enable, diskstreams
876 will believe they need to store their capture
877 sources in their state node.
880 disable_record (false);
886 Session::state(bool full_state)
888 XMLNode* node = new XMLNode("Session");
891 // store libardour version, just in case
893 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
894 node->add_property("version", string(buf));
896 /* store configuration settings */
900 node->add_property ("name", _name);
901 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
902 node->add_property ("sample-rate", buf);
904 if (session_dirs.size() > 1) {
908 vector<space_and_path>::iterator i = session_dirs.begin();
909 vector<space_and_path>::iterator next;
911 ++i; /* skip the first one */
915 while (i != session_dirs.end()) {
919 if (next != session_dirs.end()) {
929 child = node->add_child ("Path");
930 child->add_content (p);
934 /* save the ID counter */
936 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
937 node->add_property ("id-counter", buf);
939 /* various options */
941 node->add_child_nocopy (config.get_variables ());
943 node->add_child_nocopy (_metadata->get_state());
945 child = node->add_child ("Sources");
948 Glib::Mutex::Lock sl (source_lock);
950 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
952 /* Don't save information about non-destructive file sources that are empty */
953 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
955 boost::shared_ptr<AudioFileSource> fs;
956 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
957 if (!fs->destructive()) {
958 if (fs->length(fs->timeline_position()) == 0) {
964 child->add_child_nocopy (siter->second->get_state());
968 child = node->add_child ("Regions");
971 Glib::Mutex::Lock rl (region_lock);
973 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
975 /* only store regions not attached to playlists */
977 if (i->second->playlist() == 0) {
978 child->add_child_nocopy (i->second->state (true));
983 child = node->add_child ("DiskStreams");
986 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
987 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
988 if (!(*i)->hidden()) {
989 child->add_child_nocopy ((*i)->get_state());
995 node->add_child_nocopy (_locations.get_state());
997 // for a template, just create a new Locations, populate it
998 // with the default start and end, and get the state for that.
1000 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1001 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1004 end->set_end(compute_initial_length());
1006 node->add_child_nocopy (loc.get_state());
1009 child = node->add_child ("Bundles");
1011 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1012 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1013 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1015 child->add_child_nocopy (b->get_state());
1020 child = node->add_child ("Routes");
1022 boost::shared_ptr<RouteList> r = routes.reader ();
1024 RoutePublicOrderSorter cmp;
1025 RouteList public_order (*r);
1026 public_order.sort (cmp);
1028 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1029 if (!(*i)->is_hidden()) {
1031 child->add_child_nocopy ((*i)->get_state());
1033 child->add_child_nocopy ((*i)->get_template());
1040 child = node->add_child ("EditGroups");
1041 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1042 child->add_child_nocopy ((*i)->get_state());
1045 child = node->add_child ("MixGroups");
1046 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1047 child->add_child_nocopy ((*i)->get_state());
1050 child = node->add_child ("Playlists");
1051 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1052 if (!(*i)->hidden()) {
1053 if (!(*i)->empty()) {
1055 child->add_child_nocopy ((*i)->get_state());
1057 child->add_child_nocopy ((*i)->get_template());
1063 child = node->add_child ("UnusedPlaylists");
1064 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1065 if (!(*i)->hidden()) {
1066 if (!(*i)->empty()) {
1068 child->add_child_nocopy ((*i)->get_state());
1070 child->add_child_nocopy ((*i)->get_template());
1078 child = node->add_child ("Click");
1079 child->add_child_nocopy (_click_io->state (full_state));
1083 child = node->add_child ("NamedSelections");
1084 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1086 child->add_child_nocopy ((*i)->get_state());
1091 node->add_child_nocopy (_tempo_map->get_state());
1093 node->add_child_nocopy (get_control_protocol_state());
1096 node->add_child_copy (*_extra_xml);
1103 Session::get_control_protocol_state ()
1105 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1106 return cpm.get_state();
1110 Session::set_state (const XMLNode& node)
1114 const XMLProperty* prop;
1117 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1119 if (node.name() != X_("Session")){
1120 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1124 if ((prop = node.property ("name")) != 0) {
1125 _name = prop->value ();
1128 if ((prop = node.property (X_("sample-rate"))) != 0) {
1130 _nominal_frame_rate = atoi (prop->value());
1132 if (_nominal_frame_rate != _current_frame_rate) {
1133 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1139 setup_raid_path(_session_dir->root_path().to_string());
1141 if ((prop = node.property (X_("id-counter"))) != 0) {
1143 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1144 ID::init_counter (x);
1146 /* old sessions used a timebased counter, so fake
1147 the startup ID counter based on a standard
1152 ID::init_counter (now);
1156 IO::disable_connecting ();
1158 /* Object loading order:
1163 MIDI Control // relies on data from Options/Config
1177 if ((child = find_named_node (node, "Extra")) != 0) {
1178 _extra_xml = new XMLNode (*child);
1181 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1182 load_options (*child);
1183 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1184 load_options (*child);
1186 error << _("Session: XML state has no options section") << endmsg;
1189 if (use_config_midi_ports ()) {
1192 if ((child = find_named_node (node, "Metadata")) == 0) {
1193 warning << _("Session: XML state has no metadata section (2.0 session?)") << endmsg;
1194 } else if (_metadata->set_state (*child)) {
1198 if ((child = find_named_node (node, "Locations")) == 0) {
1199 error << _("Session: XML state has no locations section") << endmsg;
1201 } else if (_locations.set_state (*child)) {
1207 if ((location = _locations.auto_loop_location()) != 0) {
1208 set_auto_loop_location (location);
1211 if ((location = _locations.auto_punch_location()) != 0) {
1212 set_auto_punch_location (location);
1215 if ((location = _locations.end_location()) == 0) {
1216 _locations.add (end_location);
1218 delete end_location;
1219 end_location = location;
1222 if ((location = _locations.start_location()) == 0) {
1223 _locations.add (start_location);
1225 delete start_location;
1226 start_location = location;
1229 AudioFileSource::set_header_position_offset (start_location->start());
1231 if ((child = find_named_node (node, "Sources")) == 0) {
1232 error << _("Session: XML state has no sources section") << endmsg;
1234 } else if (load_sources (*child)) {
1238 if ((child = find_named_node (node, "Regions")) == 0) {
1239 error << _("Session: XML state has no Regions section") << endmsg;
1241 } else if (load_regions (*child)) {
1245 if ((child = find_named_node (node, "Playlists")) == 0) {
1246 error << _("Session: XML state has no playlists section") << endmsg;
1248 } else if (load_playlists (*child)) {
1252 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1254 } else if (load_unused_playlists (*child)) {
1258 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1259 if (load_named_selections (*child)) {
1264 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1265 error << _("Session: XML state has no diskstreams section") << endmsg;
1267 } else if (load_diskstreams (*child)) {
1271 if ((child = find_named_node (node, "Bundles")) == 0) {
1272 warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg;
1275 /* We can't load Bundles yet as they need to be able
1276 to convert from port names to Port objects, which can't happen until
1278 _bundle_xml_node = new XMLNode (*child);
1281 if ((child = find_named_node (node, "EditGroups")) == 0) {
1282 error << _("Session: XML state has no edit groups section") << endmsg;
1284 } else if (load_edit_groups (*child)) {
1288 if ((child = find_named_node (node, "MixGroups")) == 0) {
1289 error << _("Session: XML state has no mix groups section") << endmsg;
1291 } else if (load_mix_groups (*child)) {
1295 if ((child = find_named_node (node, "TempoMap")) == 0) {
1296 error << _("Session: XML state has no Tempo Map section") << endmsg;
1298 } else if (_tempo_map->set_state (*child)) {
1302 if ((child = find_named_node (node, "Routes")) == 0) {
1303 error << _("Session: XML state has no routes section") << endmsg;
1305 } else if (load_routes (*child)) {
1309 if ((child = find_named_node (node, "Click")) == 0) {
1310 warning << _("Session: XML state has no click section") << endmsg;
1311 } else if (_click_io) {
1312 _click_io->set_state (*child);
1315 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1316 ControlProtocolManager::instance().set_protocol_states (*child);
1319 /* here beginneth the second phase ... */
1321 StateReady (); /* EMIT SIGNAL */
1330 Session::load_routes (const XMLNode& node)
1333 XMLNodeConstIterator niter;
1334 RouteList new_routes;
1336 nlist = node.children();
1340 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1342 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1345 error << _("Session: cannot create Route from XML description.") << endmsg;
1349 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1351 new_routes.push_back (route);
1354 add_routes (new_routes, false);
1359 boost::shared_ptr<Route>
1360 Session::XMLRouteFactory (const XMLNode& node)
1362 if (node.name() != "Route") {
1363 return boost::shared_ptr<Route> ((Route*) 0);
1366 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1368 DataType type = DataType::AUDIO;
1369 const XMLProperty* prop = node.property("default-type");
1372 type = DataType(prop->value());
1375 assert(type != DataType::NIL);
1377 if (has_diskstream) {
1378 if (type == DataType::AUDIO) {
1379 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1382 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1386 boost::shared_ptr<Route> ret (new Route (*this, node));
1392 Session::load_regions (const XMLNode& node)
1395 XMLNodeConstIterator niter;
1396 boost::shared_ptr<Region> region;
1398 nlist = node.children();
1402 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1403 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1404 error << _("Session: cannot create Region from XML description.");
1405 const XMLProperty *name = (**niter).property("name");
1408 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1418 boost::shared_ptr<Region>
1419 Session::XMLRegionFactory (const XMLNode& node, bool full)
1421 const XMLProperty* type = node.property("type");
1425 if ( !type || type->value() == "audio" ) {
1427 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1429 } else if (type->value() == "midi") {
1431 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1435 } catch (failed_constructor& err) {
1436 return boost::shared_ptr<Region> ();
1439 return boost::shared_ptr<Region> ();
1442 boost::shared_ptr<AudioRegion>
1443 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1445 const XMLProperty* prop;
1446 boost::shared_ptr<Source> source;
1447 boost::shared_ptr<AudioSource> as;
1449 SourceList master_sources;
1450 uint32_t nchans = 1;
1453 if (node.name() != X_("Region")) {
1454 return boost::shared_ptr<AudioRegion>();
1457 if ((prop = node.property (X_("channels"))) != 0) {
1458 nchans = atoi (prop->value().c_str());
1461 if ((prop = node.property ("name")) == 0) {
1462 cerr << "no name for this region\n";
1466 if ((prop = node.property (X_("source-0"))) == 0) {
1467 if ((prop = node.property ("source")) == 0) {
1468 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1469 return boost::shared_ptr<AudioRegion>();
1473 PBD::ID s_id (prop->value());
1475 if ((source = source_by_id (s_id)) == 0) {
1476 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1477 return boost::shared_ptr<AudioRegion>();
1480 as = boost::dynamic_pointer_cast<AudioSource>(source);
1482 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1483 return boost::shared_ptr<AudioRegion>();
1486 sources.push_back (as);
1488 /* pickup other channels */
1490 for (uint32_t n=1; n < nchans; ++n) {
1491 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1492 if ((prop = node.property (buf)) != 0) {
1494 PBD::ID id2 (prop->value());
1496 if ((source = source_by_id (id2)) == 0) {
1497 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1498 return boost::shared_ptr<AudioRegion>();
1501 as = boost::dynamic_pointer_cast<AudioSource>(source);
1503 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1504 return boost::shared_ptr<AudioRegion>();
1506 sources.push_back (as);
1510 for (uint32_t n=1; n < nchans; ++n) {
1511 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1512 if ((prop = node.property (buf)) != 0) {
1514 PBD::ID id2 (prop->value());
1516 if ((source = source_by_id (id2)) == 0) {
1517 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1518 return boost::shared_ptr<AudioRegion>();
1521 as = boost::dynamic_pointer_cast<AudioSource>(source);
1523 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1524 return boost::shared_ptr<AudioRegion>();
1526 master_sources.push_back (as);
1531 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1533 /* a final detail: this is the one and only place that we know how long missing files are */
1535 if (region->whole_file()) {
1536 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1537 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1539 sfp->set_length (region->length());
1544 if (!master_sources.empty()) {
1545 if (master_sources.size() == nchans) {
1546 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1548 region->set_master_sources (master_sources);
1556 catch (failed_constructor& err) {
1557 return boost::shared_ptr<AudioRegion>();
1561 boost::shared_ptr<MidiRegion>
1562 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1564 const XMLProperty* prop;
1565 boost::shared_ptr<Source> source;
1566 boost::shared_ptr<MidiSource> ms;
1568 uint32_t nchans = 1;
1570 if (node.name() != X_("Region")) {
1571 return boost::shared_ptr<MidiRegion>();
1574 if ((prop = node.property (X_("channels"))) != 0) {
1575 nchans = atoi (prop->value().c_str());
1578 if ((prop = node.property ("name")) == 0) {
1579 cerr << "no name for this region\n";
1583 // Multiple midi channels? that's just crazy talk
1584 assert(nchans == 1);
1586 if ((prop = node.property (X_("source-0"))) == 0) {
1587 if ((prop = node.property ("source")) == 0) {
1588 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1589 return boost::shared_ptr<MidiRegion>();
1593 PBD::ID s_id (prop->value());
1595 if ((source = source_by_id (s_id)) == 0) {
1596 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1597 return boost::shared_ptr<MidiRegion>();
1600 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1602 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1603 return boost::shared_ptr<MidiRegion>();
1606 sources.push_back (ms);
1609 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1610 /* a final detail: this is the one and only place that we know how long missing files are */
1612 if (region->whole_file()) {
1613 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1614 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1616 sfp->set_length (region->length());
1624 catch (failed_constructor& err) {
1625 return boost::shared_ptr<MidiRegion>();
1630 Session::get_sources_as_xml ()
1633 XMLNode* node = new XMLNode (X_("Sources"));
1634 Glib::Mutex::Lock lm (source_lock);
1636 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1637 node->add_child_nocopy (i->second->get_state());
1644 Session::path_from_region_name (DataType type, string name, string identifier)
1646 char buf[PATH_MAX+1];
1648 SessionDirectory sdir(get_best_session_directory_for_new_source());
1649 sys::path source_dir = ((type == DataType::AUDIO)
1650 ? sdir.sound_path() : sdir.midi_path());
1652 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1654 for (n = 0; n < 999999; ++n) {
1655 if (identifier.length()) {
1656 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1657 identifier.c_str(), n, ext.c_str());
1659 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1663 sys::path source_path = source_dir / buf;
1665 if (!sys::exists (source_path)) {
1666 return source_path.to_string();
1670 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1679 Session::load_sources (const XMLNode& node)
1682 XMLNodeConstIterator niter;
1683 boost::shared_ptr<Source> source;
1685 nlist = node.children();
1689 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1691 if ((source = XMLSourceFactory (**niter)) == 0) {
1692 error << _("Session: cannot create Source from XML description.") << endmsg;
1694 } catch (MissingSource& err) {
1695 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1696 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1703 boost::shared_ptr<Source>
1704 Session::XMLSourceFactory (const XMLNode& node)
1706 if (node.name() != "Source") {
1707 return boost::shared_ptr<Source>();
1711 /* note: do peak building in another thread when loading session state */
1712 return SourceFactory::create (*this, node, true);
1715 catch (failed_constructor& err) {
1716 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1717 return boost::shared_ptr<Source>();
1722 Session::save_template (string template_name)
1726 if (_state_of_the_state & CannotSave) {
1730 sys::path user_template_dir(user_template_directory());
1734 sys::create_directories (user_template_dir);
1736 catch(sys::filesystem_error& ex)
1738 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1739 user_template_dir.to_string(), ex.what()) << endmsg;
1743 tree.set_root (&get_template());
1745 sys::path template_file_path(user_template_dir);
1746 template_file_path /= template_name + template_suffix;
1748 if (sys::exists (template_file_path))
1750 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1751 template_file_path.to_string()) << endmsg;
1755 if (!tree.write (template_file_path.to_string())) {
1756 error << _("mix template not saved") << endmsg;
1764 Session::rename_template (string old_name, string new_name)
1766 sys::path old_path (user_template_directory());
1767 old_path /= old_name + template_suffix;
1769 sys::path new_path(user_template_directory());
1770 new_path /= new_name + template_suffix;
1772 if (sys::exists (new_path)) {
1773 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1774 new_path.to_string()) << endmsg;
1779 sys::rename (old_path, new_path);
1787 Session::delete_template (string name)
1789 sys::path path = user_template_directory();
1790 path /= name + template_suffix;
1801 Session::refresh_disk_space ()
1804 struct statfs statfsbuf;
1805 vector<space_and_path>::iterator i;
1806 Glib::Mutex::Lock lm (space_lock);
1809 /* get freespace on every FS that is part of the session path */
1811 _total_free_4k_blocks = 0;
1813 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1814 statfs ((*i).path.c_str(), &statfsbuf);
1816 scale = statfsbuf.f_bsize/4096.0;
1818 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1819 _total_free_4k_blocks += (*i).blocks;
1825 Session::get_best_session_directory_for_new_source ()
1827 vector<space_and_path>::iterator i;
1828 string result = _session_dir->root_path().to_string();
1830 /* handle common case without system calls */
1832 if (session_dirs.size() == 1) {
1836 /* OK, here's the algorithm we're following here:
1838 We want to select which directory to use for
1839 the next file source to be created. Ideally,
1840 we'd like to use a round-robin process so as to
1841 get maximum performance benefits from splitting
1842 the files across multiple disks.
1844 However, in situations without much diskspace, an
1845 RR approach may end up filling up a filesystem
1846 with new files while others still have space.
1847 Its therefore important to pay some attention to
1848 the freespace in the filesystem holding each
1849 directory as well. However, if we did that by
1850 itself, we'd keep creating new files in the file
1851 system with the most space until it was as full
1852 as all others, thus negating any performance
1853 benefits of this RAID-1 like approach.
1855 So, we use a user-configurable space threshold. If
1856 there are at least 2 filesystems with more than this
1857 much space available, we use RR selection between them.
1858 If not, then we pick the filesystem with the most space.
1860 This gets a good balance between the two
1864 refresh_disk_space ();
1866 int free_enough = 0;
1868 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1869 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1874 if (free_enough >= 2) {
1875 /* use RR selection process, ensuring that the one
1879 i = last_rr_session_dir;
1882 if (++i == session_dirs.end()) {
1883 i = session_dirs.begin();
1886 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1887 if (create_session_directory ((*i).path)) {
1889 last_rr_session_dir = i;
1894 } while (i != last_rr_session_dir);
1898 /* pick FS with the most freespace (and that
1899 seems to actually work ...)
1902 vector<space_and_path> sorted;
1903 space_and_path_ascending_cmp cmp;
1905 sorted = session_dirs;
1906 sort (sorted.begin(), sorted.end(), cmp);
1908 for (i = sorted.begin(); i != sorted.end(); ++i) {
1909 if (create_session_directory ((*i).path)) {
1911 last_rr_session_dir = i;
1921 Session::load_playlists (const XMLNode& node)
1924 XMLNodeConstIterator niter;
1925 boost::shared_ptr<Playlist> playlist;
1927 nlist = node.children();
1931 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1933 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1934 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1942 Session::load_unused_playlists (const XMLNode& node)
1945 XMLNodeConstIterator niter;
1946 boost::shared_ptr<Playlist> playlist;
1948 nlist = node.children();
1952 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1954 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1955 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1959 // now manually untrack it
1961 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1967 boost::shared_ptr<Playlist>
1968 Session::XMLPlaylistFactory (const XMLNode& node)
1971 return PlaylistFactory::create (*this, node);
1974 catch (failed_constructor& err) {
1975 return boost::shared_ptr<Playlist>();
1980 Session::load_named_selections (const XMLNode& node)
1983 XMLNodeConstIterator niter;
1986 nlist = node.children();
1990 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1992 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1993 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2001 Session::XMLNamedSelectionFactory (const XMLNode& node)
2004 return new NamedSelection (*this, node);
2007 catch (failed_constructor& err) {
2013 Session::automation_dir () const
2015 return Glib::build_filename (_path, "automation");
2019 Session::analysis_dir () const
2021 return Glib::build_filename (_path, "analysis");
2025 Session::load_bundles (XMLNode const & node)
2027 XMLNodeList nlist = node.children();
2028 XMLNodeConstIterator niter;
2032 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2033 if ((*niter)->name() == "InputBundle") {
2034 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2035 } else if ((*niter)->name() == "OutputBundle") {
2036 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2038 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2047 Session::load_edit_groups (const XMLNode& node)
2049 return load_route_groups (node, true);
2053 Session::load_mix_groups (const XMLNode& node)
2055 return load_route_groups (node, false);
2059 Session::load_route_groups (const XMLNode& node, bool edit)
2061 XMLNodeList nlist = node.children();
2062 XMLNodeConstIterator niter;
2067 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2068 if ((*niter)->name() == "RouteGroup") {
2070 rg = add_edit_group ("");
2071 rg->set_state (**niter);
2073 rg = add_mix_group ("");
2074 rg->set_state (**niter);
2083 Session::auto_save()
2085 save_state (_current_snapshot_name);
2089 state_file_filter (const string &str, void *arg)
2091 return (str.length() > strlen(statefile_suffix) &&
2092 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2096 bool operator()(const string* a, const string* b) {
2102 remove_end(string* state)
2104 string statename(*state);
2106 string::size_type start,end;
2107 if ((start = statename.find_last_of ('/')) != string::npos) {
2108 statename = statename.substr (start+1);
2111 if ((end = statename.rfind(".ardour")) == string::npos) {
2112 end = statename.length();
2115 return new string(statename.substr (0, end));
2119 Session::possible_states (string path)
2121 PathScanner scanner;
2122 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2124 transform(states->begin(), states->end(), states->begin(), remove_end);
2127 sort (states->begin(), states->end(), cmp);
2133 Session::possible_states () const
2135 return possible_states(_path);
2139 Session::add_edit_group (string name)
2141 RouteGroup* rg = new RouteGroup (*this, name);
2142 edit_groups.push_back (rg);
2143 edit_group_added (rg); /* EMIT SIGNAL */
2149 Session::add_mix_group (string name)
2151 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2152 mix_groups.push_back (rg);
2153 mix_group_added (rg); /* EMIT SIGNAL */
2159 Session::remove_edit_group (RouteGroup& rg)
2161 list<RouteGroup*>::iterator i;
2163 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2164 (*i)->apply (&Route::drop_edit_group, this);
2165 edit_groups.erase (i);
2166 edit_group_removed (); /* EMIT SIGNAL */
2173 Session::remove_mix_group (RouteGroup& rg)
2175 list<RouteGroup*>::iterator i;
2177 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2178 (*i)->apply (&Route::drop_mix_group, this);
2179 mix_groups.erase (i);
2180 mix_group_removed (); /* EMIT SIGNAL */
2187 Session::mix_group_by_name (string name)
2189 list<RouteGroup *>::iterator i;
2191 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2192 if ((*i)->name() == name) {
2200 Session::edit_group_by_name (string name)
2202 list<RouteGroup *>::iterator i;
2204 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2205 if ((*i)->name() == name) {
2213 Session::begin_reversible_command(const string& name)
2215 UndoTransaction* trans = new UndoTransaction();
2216 trans->set_name(name);
2217 if (!_current_trans.empty()) {
2218 _current_trans.top()->add_command(trans);
2220 _current_trans.push(trans);
2224 Session::commit_reversible_command(Command *cmd)
2226 assert(!_current_trans.empty());
2230 _current_trans.top()->add_command(cmd);
2233 if (_current_trans.top()->empty()) {
2234 _current_trans.pop();
2238 gettimeofday(&now, 0);
2239 _current_trans.top()->set_timestamp(now);
2241 _history.add(_current_trans.top());
2242 _current_trans.pop();
2245 Session::GlobalRouteBooleanState
2246 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2248 GlobalRouteBooleanState s;
2249 boost::shared_ptr<RouteList> r = routes.reader ();
2251 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2252 if (!(*i)->is_hidden()) {
2253 RouteBooleanState v;
2256 Route* r = (*i).get();
2257 v.second = (r->*method)();
2266 Session::GlobalRouteMeterState
2267 Session::get_global_route_metering ()
2269 GlobalRouteMeterState s;
2270 boost::shared_ptr<RouteList> r = routes.reader ();
2272 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2273 if (!(*i)->is_hidden()) {
2277 v.second = (*i)->meter_point();
2287 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2289 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2291 boost::shared_ptr<Route> r = (i->first.lock());
2294 r->set_meter_point (i->second, arg);
2300 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2302 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2304 boost::shared_ptr<Route> r = (i->first.lock());
2307 Route* rp = r.get();
2308 (rp->*method) (i->second, arg);
2314 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2316 set_global_route_boolean (s, &Route::set_mute, src);
2320 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2322 set_global_route_boolean (s, &Route::set_solo, src);
2326 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2328 set_global_route_boolean (s, &Route::set_record_enable, src);
2332 accept_all_non_peak_files (const string& path, void *arg)
2334 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2338 accept_all_state_files (const string& path, void *arg)
2340 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2344 Session::find_all_sources (string path, set<string>& result)
2349 if (!tree.read (path)) {
2353 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2358 XMLNodeConstIterator niter;
2360 nlist = node->children();
2364 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2368 if ((prop = (*niter)->property (X_("name"))) == 0) {
2372 if (prop->value()[0] == '/') {
2373 /* external file, ignore */
2377 sys::path source_path = _session_dir->sound_path ();
2379 source_path /= prop->value ();
2381 result.insert (source_path.to_string ());
2388 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2390 PathScanner scanner;
2391 vector<string*>* state_files;
2393 string this_snapshot_path;
2399 if (ripped[ripped.length()-1] == '/') {
2400 ripped = ripped.substr (0, ripped.length() - 1);
2403 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2405 if (state_files == 0) {
2410 this_snapshot_path = _path;
2411 this_snapshot_path += _current_snapshot_name;
2412 this_snapshot_path += statefile_suffix;
2414 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2416 if (exclude_this_snapshot && **i == this_snapshot_path) {
2420 if (find_all_sources (**i, result) < 0) {
2428 struct RegionCounter {
2429 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2430 AudioSourceList::iterator iter;
2431 boost::shared_ptr<Region> region;
2434 RegionCounter() : count (0) {}
2438 Session::cleanup_sources (Session::cleanup_report& rep)
2440 // FIXME: needs adaptation to midi
2442 vector<boost::shared_ptr<Source> > dead_sources;
2443 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2444 PathScanner scanner;
2446 vector<space_and_path>::iterator i;
2447 vector<space_and_path>::iterator nexti;
2448 vector<string*>* soundfiles;
2449 vector<string> unused;
2450 set<string> all_sources;
2455 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2458 /* step 1: consider deleting all unused playlists */
2460 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2463 status = AskAboutPlaylistDeletion (*x);
2472 playlists_tbd.push_back (*x);
2476 /* leave it alone */
2481 /* now delete any that were marked for deletion */
2483 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2484 (*x)->drop_references ();
2487 playlists_tbd.clear ();
2489 /* step 2: find all un-used sources */
2494 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2496 SourceMap::iterator tmp;
2501 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2505 if (!i->second->used() && i->second->length(i->second->timeline_position()) > 0) {
2506 dead_sources.push_back (i->second);
2507 i->second->GoingAway();
2513 /* build a list of all the possible sound directories for the session */
2515 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2520 SessionDirectory sdir ((*i).path);
2521 sound_path += sdir.sound_path().to_string();
2523 if (nexti != session_dirs.end()) {
2530 /* now do the same thing for the files that ended up in the sounds dir(s)
2531 but are not referenced as sources in any snapshot.
2534 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2536 if (soundfiles == 0) {
2540 /* find all sources, but don't use this snapshot because the
2541 state file on disk still references sources we may have already
2545 find_all_sources_across_snapshots (all_sources, true);
2547 /* add our current source list
2550 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2551 boost::shared_ptr<FileSource> fs;
2553 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2554 all_sources.insert (fs->path());
2558 char tmppath1[PATH_MAX+1];
2559 char tmppath2[PATH_MAX+1];
2561 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2566 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2568 realpath(spath.c_str(), tmppath1);
2569 realpath((*i).c_str(), tmppath2);
2571 if (strcmp(tmppath1, tmppath2) == 0) {
2578 unused.push_back (spath);
2582 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2584 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2585 struct stat statbuf;
2587 rep.paths.push_back (*x);
2588 if (stat ((*x).c_str(), &statbuf) == 0) {
2589 rep.space += statbuf.st_size;
2594 /* don't move the file across filesystems, just
2595 stick it in the `dead_sound_dir_name' directory
2596 on whichever filesystem it was already on.
2599 if ((*x).find ("/sounds/") != string::npos) {
2601 /* old school, go up 1 level */
2603 newpath = Glib::path_get_dirname (*x); // "sounds"
2604 newpath = Glib::path_get_dirname (newpath); // "session-name"
2608 /* new school, go up 4 levels */
2610 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2611 newpath = Glib::path_get_dirname (newpath); // "session-name"
2612 newpath = Glib::path_get_dirname (newpath); // "interchange"
2613 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2617 newpath += dead_sound_dir_name;
2619 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2620 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2625 newpath += Glib::path_get_basename ((*x));
2627 if (access (newpath.c_str(), F_OK) == 0) {
2629 /* the new path already exists, try versioning */
2631 char buf[PATH_MAX+1];
2635 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2638 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2639 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2643 if (version == 999) {
2644 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2648 newpath = newpath_v;
2653 /* it doesn't exist, or we can't read it or something */
2657 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2658 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2659 (*x), newpath, strerror (errno))
2664 /* see if there an easy to find peakfile for this file, and remove it.
2667 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2668 peakpath += peakfile_suffix;
2670 if (access (peakpath.c_str(), W_OK) == 0) {
2671 if (::unlink (peakpath.c_str()) != 0) {
2672 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2673 peakpath, _path, strerror (errno))
2675 /* try to back out */
2676 rename (newpath.c_str(), _path.c_str());
2684 /* dump the history list */
2688 /* save state so we don't end up a session file
2689 referring to non-existent sources.
2695 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2701 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2703 // FIXME: needs adaptation for MIDI
2705 vector<space_and_path>::iterator i;
2706 string dead_sound_dir;
2707 struct dirent* dentry;
2708 struct stat statbuf;
2714 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2716 dead_sound_dir = (*i).path;
2717 dead_sound_dir += dead_sound_dir_name;
2719 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2723 while ((dentry = readdir (dead)) != 0) {
2725 /* avoid '.' and '..' */
2727 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2728 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2734 fullpath = dead_sound_dir;
2736 fullpath += dentry->d_name;
2738 if (stat (fullpath.c_str(), &statbuf)) {
2742 if (!S_ISREG (statbuf.st_mode)) {
2746 if (unlink (fullpath.c_str())) {
2747 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2748 fullpath, strerror (errno))
2752 rep.paths.push_back (dentry->d_name);
2753 rep.space += statbuf.st_size;
2764 Session::set_dirty ()
2766 bool was_dirty = dirty();
2768 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2772 DirtyChanged(); /* EMIT SIGNAL */
2778 Session::set_clean ()
2780 bool was_dirty = dirty();
2782 _state_of_the_state = Clean;
2786 DirtyChanged(); /* EMIT SIGNAL */
2791 Session::set_deletion_in_progress ()
2793 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2797 Session::clear_deletion_in_progress ()
2799 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2803 Session::add_controllable (boost::shared_ptr<Controllable> c)
2805 /* this adds a controllable to the list managed by the Session.
2806 this is a subset of those managed by the Controllable class
2807 itself, and represents the only ones whose state will be saved
2808 as part of the session.
2811 Glib::Mutex::Lock lm (controllables_lock);
2812 controllables.insert (c);
2815 struct null_deleter { void operator()(void const *) const {} };
2818 Session::remove_controllable (Controllable* c)
2820 if (_state_of_the_state | Deletion) {
2824 Glib::Mutex::Lock lm (controllables_lock);
2826 Controllables::iterator x = controllables.find(
2827 boost::shared_ptr<Controllable>(c, null_deleter()));
2829 if (x != controllables.end()) {
2830 controllables.erase (x);
2834 boost::shared_ptr<Controllable>
2835 Session::controllable_by_id (const PBD::ID& id)
2837 Glib::Mutex::Lock lm (controllables_lock);
2839 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2840 if ((*i)->id() == id) {
2845 return boost::shared_ptr<Controllable>();
2849 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2851 Stateful::add_instant_xml (node, _path);
2852 if (write_to_config) {
2853 Config->add_instant_xml (node);
2858 Session::instant_xml (const string& node_name)
2860 return Stateful::instant_xml (node_name, _path);
2864 Session::save_history (string snapshot_name)
2868 if (snapshot_name.empty()) {
2869 snapshot_name = _current_snapshot_name;
2872 const string history_filename = snapshot_name + history_suffix;
2873 const string backup_filename = history_filename + backup_suffix;
2874 const sys::path xml_path = _session_dir->root_path() / history_filename;
2875 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2877 if (sys::exists (xml_path)) {
2880 sys::rename (xml_path, backup_path);
2882 catch (const sys::filesystem_error& err)
2884 error << _("could not backup old history file, current history not saved") << endmsg;
2890 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2894 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2896 if (!tree.write (xml_path.to_string()))
2898 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2902 sys::remove (xml_path);
2903 sys::rename (backup_path, xml_path);
2905 catch (const sys::filesystem_error& err)
2907 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2908 backup_path.to_string(), err.what()) << endmsg;
2918 Session::restore_history (string snapshot_name)
2922 if (snapshot_name.empty()) {
2923 snapshot_name = _current_snapshot_name;
2926 const string xml_filename = snapshot_name + history_suffix;
2927 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2929 cerr << "Loading history from " << xml_path.to_string() << endmsg;
2931 if (!sys::exists (xml_path)) {
2932 info << string_compose (_("%1: no history file \"%2\" for this session."),
2933 _name, xml_path.to_string()) << endmsg;
2937 if (!tree.read (xml_path.to_string())) {
2938 error << string_compose (_("Could not understand session history file \"%1\""),
2939 xml_path.to_string()) << endmsg;
2946 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2949 UndoTransaction* ut = new UndoTransaction ();
2952 ut->set_name(t->property("name")->value());
2953 stringstream ss(t->property("tv-sec")->value());
2955 ss.str(t->property("tv-usec")->value());
2957 ut->set_timestamp(tv);
2959 for (XMLNodeConstIterator child_it = t->children().begin();
2960 child_it != t->children().end(); child_it++)
2962 XMLNode *n = *child_it;
2965 if (n->name() == "MementoCommand" ||
2966 n->name() == "MementoUndoCommand" ||
2967 n->name() == "MementoRedoCommand") {
2969 if ((c = memento_command_factory(n))) {
2973 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2975 if ((c = global_state_command_factory (*n))) {
2976 ut->add_command (c);
2979 } else if (n->name() == "DeltaCommand") {
2980 PBD::ID id(n->property("midi-source")->value());
2981 boost::shared_ptr<MidiSource> midi_source =
2982 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2984 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
2986 error << "FIXME: Failed to downcast MidiSource for DeltaCommand" << endmsg;
2989 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3000 Session::config_changed (std::string p, bool ours)
3006 if (p == "seamless-loop") {
3008 } else if (p == "rf-speed") {
3010 } else if (p == "auto-loop") {
3012 } else if (p == "auto-input") {
3014 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3015 /* auto-input only makes a difference if we're rolling */
3017 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3019 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3020 if ((*i)->record_enabled ()) {
3021 (*i)->monitor_input (!config.get_auto_input());
3026 } else if (p == "punch-in") {
3030 if ((location = _locations.auto_punch_location()) != 0) {
3032 if (config.get_punch_in ()) {
3033 replace_event (Event::PunchIn, location->start());
3035 remove_event (location->start(), Event::PunchIn);
3039 } else if (p == "punch-out") {
3043 if ((location = _locations.auto_punch_location()) != 0) {
3045 if (config.get_punch_out()) {
3046 replace_event (Event::PunchOut, location->end());
3048 clear_events (Event::PunchOut);
3052 } else if (p == "edit-mode") {
3054 Glib::Mutex::Lock lm (playlist_lock);
3056 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3057 (*i)->set_edit_mode (Config->get_edit_mode ());
3060 } else if (p == "use-video-sync") {
3062 waiting_for_sync_offset = config.get_use_video_sync();
3064 } else if (p == "mmc-control") {
3066 //poke_midi_thread ();
3068 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3071 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3074 } else if (p == "mmc-send-id") {
3077 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3080 } else if (p == "midi-control") {
3082 //poke_midi_thread ();
3084 } else if (p == "raid-path") {
3086 setup_raid_path (config.get_raid_path());
3088 } else if (p == "smpte-format") {
3092 } else if (p == "video-pullup") {
3096 } else if (p == "seamless-loop") {
3098 if (play_loop && transport_rolling()) {
3099 // to reset diskstreams etc
3100 request_play_loop (true);
3103 } else if (p == "rf-speed") {
3105 cumulative_rf_motion = 0;
3108 } else if (p == "click-sound") {
3110 setup_click_sounds (1);
3112 } else if (p == "click-emphasis-sound") {
3114 setup_click_sounds (-1);
3116 } else if (p == "clicking") {
3118 if (Config->get_clicking()) {
3119 if (_click_io && click_data) { // don't require emphasis data
3126 } else if (p == "send-mtc") {
3128 /* only set the internal flag if we have
3132 if (_mtc_port != 0) {
3133 session_send_mtc = Config->get_send_mtc();
3134 if (session_send_mtc) {
3135 /* mark us ready to send */
3136 next_quarter_frame_to_send = 0;
3139 session_send_mtc = false;
3142 } else if (p == "send-mmc") {
3144 /* only set the internal flag if we have
3148 if (_mmc_port != 0) {
3149 session_send_mmc = Config->get_send_mmc();
3152 session_send_mmc = false;
3155 } else if (p == "midi-feedback") {
3157 /* only set the internal flag if we have
3161 if (_mtc_port != 0) {
3162 session_midi_feedback = Config->get_midi_feedback();
3165 } else if (p == "jack-time-master") {
3167 engine().reset_timebase ();
3169 } else if (p == "native-file-header-format") {
3171 if (!first_file_header_format_reset) {
3172 reset_native_file_format ();
3175 first_file_header_format_reset = false;
3177 } else if (p == "native-file-data-format") {
3179 if (!first_file_data_format_reset) {
3180 reset_native_file_format ();
3183 first_file_data_format_reset = false;
3185 } else if (p == "slave-source") {
3186 set_slave_source (Config->get_slave_source());
3187 } else if (p == "remote-model") {
3188 set_remote_control_ids ();
3189 } else if (p == "denormal-model") {
3191 } else if (p == "history-depth") {
3192 set_history_depth (Config->get_history_depth());
3193 } else if (p == "sync-all-route-ordering") {
3194 sync_order_keys ("session");
3195 } else if (p == "initial-program-change") {
3197 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3200 buf[0] = MIDI::program; // channel zero by default
3201 buf[1] = (Config->get_initial_program_change() & 0x7f);
3203 _mmc_port->midimsg (buf, sizeof (buf), 0);
3205 } else if (p == "initial-program-change") {
3207 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3208 MIDI::byte* buf = new MIDI::byte[2];
3210 buf[0] = MIDI::program; // channel zero by default
3211 buf[1] = (Config->get_initial_program_change() & 0x7f);
3212 // deliver_midi (_mmc_port, buf, 2);
3214 } else if (p == "solo-mute-override") {
3215 // catch_up_on_solo_mute_override ();
3222 Session::set_history_depth (uint32_t d)
3224 _history.set_depth (d);