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/buffer.h>
68 #include <ardour/audio_diskstream.h>
69 #include <ardour/midi_diskstream.h>
70 #include <ardour/utils.h>
71 #include <ardour/audioplaylist.h>
72 #include <ardour/midi_playlist.h>
73 #include <ardour/smf_source.h>
74 #include <ardour/audiofilesource.h>
75 #include <ardour/silentfilesource.h>
76 #include <ardour/sndfilesource.h>
77 #include <ardour/midi_source.h>
78 #include <ardour/sndfile_helpers.h>
79 #include <ardour/auditioner.h>
80 #include <ardour/export.h>
81 #include <ardour/io_processor.h>
82 #include <ardour/send.h>
83 #include <ardour/processor.h>
84 #include <ardour/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/cycle_timer.h>
90 #include <ardour/utils.h>
91 #include <ardour/named_selection.h>
92 #include <ardour/version.h>
93 #include <ardour/location.h>
94 #include <ardour/audioregion.h>
95 #include <ardour/midi_region.h>
96 #include <ardour/crossfade.h>
97 #include <ardour/control_protocol_manager.h>
98 #include <ardour/region_factory.h>
99 #include <ardour/source_factory.h>
100 #include <ardour/playlist_factory.h>
101 #include <ardour/filename_extensions.h>
102 #include <ardour/directory_names.h>
103 #include <ardour/template_utils.h>
105 #include <control_protocol/control_protocol.h>
111 using namespace ARDOUR;
115 Session::first_stage_init (string fullpath, string snapshot_name)
117 if (fullpath.length() == 0) {
119 throw failed_constructor();
122 char buf[PATH_MAX+1];
123 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
124 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
126 throw failed_constructor();
131 if (_path[_path.length()-1] != '/') {
135 /* these two are just provisional settings. set_state()
136 will likely override them.
139 _name = _current_snapshot_name = snapshot_name;
141 set_history_depth (Config->get_history_depth());
143 _current_frame_rate = _engine.frame_rate ();
144 _nominal_frame_rate = _current_frame_rate;
145 _base_frame_rate = _current_frame_rate;
147 _tempo_map = new TempoMap (_current_frame_rate);
148 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
152 g_atomic_int_set (&processing_prohibited, 0);
154 _transport_speed = 0;
155 _last_transport_speed = 0;
156 auto_play_legal = false;
157 transport_sub_state = 0;
158 _transport_frame = 0;
160 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
161 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
162 _end_location_is_free = true;
163 g_atomic_int_set (&_record_status, Disabled);
164 loop_changing = false;
166 _last_roll_location = 0;
167 _last_record_location = 0;
168 pending_locate_frame = 0;
169 pending_locate_roll = false;
170 pending_locate_flush = false;
171 dstream_buffer_size = 0;
173 state_was_pending = false;
175 outbound_mtc_smpte_frame = 0;
176 next_quarter_frame_to_send = -1;
177 current_block_size = 0;
178 solo_update_disabled = false;
179 currently_soloing = false;
180 _have_captured = false;
181 _worst_output_latency = 0;
182 _worst_input_latency = 0;
183 _worst_track_latency = 0;
184 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
187 butler_mixdown_buffer = 0;
188 butler_gain_buffer = 0;
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 (&butler_active, 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);
200 waiting_to_start = false;
202 _gain_automation_buffer = 0;
203 _pan_automation_buffer = 0;
205 pending_abort = false;
206 destructive_index = 0;
208 first_file_data_format_reset = true;
209 first_file_header_format_reset = true;
210 butler_thread = (pthread_t) 0;
211 //midi_thread = (pthread_t) 0;
213 AudioDiskstream::allocate_working_buffers();
215 /* default short fade = 15ms */
217 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
218 SndFileSource::setup_standard_crossfades (frame_rate());
220 last_mmc_step.tv_sec = 0;
221 last_mmc_step.tv_usec = 0;
224 /* click sounds are unset by default, which causes us to internal
225 waveforms for clicks.
229 click_emphasis_data = 0;
231 click_emphasis_length = 0;
234 process_function = &Session::process_with_events;
236 if (Config->get_use_video_sync()) {
237 waiting_for_sync_offset = true;
239 waiting_for_sync_offset = false;
244 _smpte_offset_negative = true;
245 last_smpte_valid = false;
249 last_rr_session_dir = session_dirs.begin();
250 refresh_disk_space ();
252 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
256 average_slave_delta = 1800;
257 have_first_delta_accumulator = false;
258 delta_accumulator_cnt = 0;
259 slave_state = Stopped;
261 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
263 /* These are all static "per-class" signals */
265 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
266 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
267 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
268 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
269 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
270 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
272 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
274 IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
276 /* stop IO objects from doing stuff until we're ready for them */
278 IO::disable_panners ();
279 IO::disable_ports ();
280 IO::disable_connecting ();
284 Session::second_stage_init (bool new_session)
286 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
289 if (load_state (_current_snapshot_name)) {
292 remove_empty_sounds ();
295 if (start_butler_thread()) {
299 /*if (start_midi_thread ()) {
303 // set_state() will call setup_raid_path(), but if it's a new session we need
304 // to call setup_raid_path() here.
307 if (set_state (*state_tree->root())) {
311 setup_raid_path(_path);
314 /* we can't save till after ::when_engine_running() is called,
315 because otherwise we save state with no connections made.
316 therefore, we reset _state_of_the_state because ::set_state()
317 will have cleared it.
319 we also have to include Loading so that any events that get
320 generated between here and the end of ::when_engine_running()
321 will be processed directly rather than queued.
324 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
327 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
328 _locations.added.connect (mem_fun (this, &Session::locations_added));
329 setup_click_sounds (0);
330 setup_midi_control ();
332 /* Pay attention ... */
334 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
335 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
338 when_engine_running();
341 /* handle this one in a different way than all others, so that its clear what happened */
343 catch (AudioEngine::PortRegistrationFailure& err) {
344 error << _("Unable to create all required ports")
353 BootMessage (_("Reset Remote Controls"));
355 //send_full_time_code ();
356 _engine.transport_locate (0);
357 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
358 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
360 BootMessage (_("Reset Control Protocols"));
362 ControlProtocolManager::instance().set_session (*this);
365 _end_location_is_free = true;
367 _end_location_is_free = false;
370 _state_of_the_state = Clean;
372 DirtyChanged (); /* EMIT SIGNAL */
374 if (state_was_pending) {
375 save_state (_current_snapshot_name);
376 remove_pending_capture_state ();
377 state_was_pending = false;
380 BootMessage (_("Session loading complete"));
386 Session::raid_path () const
388 SearchPath raid_search_path;
390 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
391 raid_search_path += sys::path((*i).path);
394 return raid_search_path.to_string ();
398 Session::setup_raid_path (string path)
407 session_dirs.clear ();
409 SearchPath search_path(path);
410 SearchPath sound_search_path;
411 SearchPath midi_search_path;
414 SearchPath::const_iterator i = search_path.begin();
415 i != search_path.end();
419 sp.path = (*i).to_string ();
420 sp.blocks = 0; // not needed
421 session_dirs.push_back (sp);
423 SessionDirectory sdir(sp.path);
425 sound_search_path += sdir.sound_path ();
426 midi_search_path += sdir.midi_path ();
429 // set the AudioFileSource and SMFSource search path
431 AudioFileSource::set_search_path (sound_search_path.to_string ());
432 SMFSource::set_search_path (midi_search_path.to_string ());
434 // reset the round-robin soundfile path thingie
436 last_rr_session_dir = session_dirs.begin();
440 Session::ensure_subdirs ()
444 dir = session_directory().peak_path().to_string();
446 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
447 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
451 dir = session_directory().sound_path().to_string();
453 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
454 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
458 dir = session_directory().midi_path().to_string();
460 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
461 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
465 dir = session_directory().dead_sound_path().to_string();
467 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
468 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
472 dir = session_directory().export_path().to_string();
474 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
475 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
479 dir = analysis_dir ();
481 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
482 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
490 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
493 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
494 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
498 if (ensure_subdirs ()) {
502 /* check new_session so we don't overwrite an existing one */
504 if (!mix_template.empty()) {
505 std::string in_path = mix_template;
507 ifstream in(in_path.c_str());
510 string out_path = _path;
512 out_path += statefile_suffix;
514 ofstream out(out_path.c_str());
519 // okay, session is set up. Treat like normal saved
520 // session from now on.
526 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
532 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
539 /* set initial start + end point */
541 start_location->set_end (0);
542 _locations.add (start_location);
544 end_location->set_end (initial_length);
545 _locations.add (end_location);
547 _state_of_the_state = Clean;
556 Session::load_diskstreams (const XMLNode& node)
559 XMLNodeConstIterator citer;
561 clist = node.children();
563 for (citer = clist.begin(); citer != clist.end(); ++citer) {
566 /* diskstreams added automatically by DiskstreamCreated handler */
567 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
568 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
569 add_diskstream (dstream);
570 } else if ((*citer)->name() == "MidiDiskstream") {
571 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
572 add_diskstream (dstream);
574 error << _("Session: unknown diskstream type in XML") << endmsg;
578 catch (failed_constructor& err) {
579 error << _("Session: could not load diskstream via XML state") << endmsg;
588 Session::maybe_write_autosave()
590 if (dirty() && record_status() != Recording) {
591 save_state("", true);
596 Session::remove_pending_capture_state ()
598 sys::path pending_state_file_path(_session_dir->root_path());
600 pending_state_file_path /= _current_snapshot_name + pending_suffix;
604 sys::remove (pending_state_file_path);
606 catch(sys::filesystem_error& ex)
608 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
609 pending_state_file_path.to_string(), ex.what()) << endmsg;
613 /** Rename a state file.
614 * @param snapshot_name Snapshot name.
617 Session::rename_state (string old_name, string new_name)
619 if (old_name == _current_snapshot_name || old_name == _name) {
620 /* refuse to rename the current snapshot or the "main" one */
624 const string old_xml_filename = old_name + statefile_suffix;
625 const string new_xml_filename = new_name + statefile_suffix;
627 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
628 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
632 sys::rename (old_xml_path, new_xml_path);
634 catch (const sys::filesystem_error& err)
636 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
637 old_name, new_name, err.what()) << endmsg;
641 /** Remove a state file.
642 * @param snapshot_name Snapshot name.
645 Session::remove_state (string snapshot_name)
647 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
648 // refuse to remove the current snapshot or the "main" one
652 sys::path xml_path(_session_dir->root_path());
654 xml_path /= snapshot_name + statefile_suffix;
656 if (!create_backup_file (xml_path)) {
657 // don't remove it if a backup can't be made
658 // create_backup_file will log the error.
663 sys::remove (xml_path);
667 Session::save_state (string snapshot_name, bool pending)
670 sys::path xml_path(_session_dir->root_path());
672 if (_state_of_the_state & CannotSave) {
676 if (!_engine.connected ()) {
677 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
682 /* tell sources we're saving first, in case they write out to a new file
683 * which should be saved with the state rather than the old one */
684 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
685 i->second->session_saved();
687 tree.set_root (&get_state());
689 if (snapshot_name.empty()) {
690 snapshot_name = _current_snapshot_name;
695 /* proper save: use statefile_suffix (.ardour in English) */
697 xml_path /= snapshot_name + statefile_suffix;
699 /* make a backup copy of the old file */
701 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
702 // create_backup_file will log the error
708 /* pending save: use pending_suffix (.pending in English) */
709 xml_path /= snapshot_name + pending_suffix;
712 sys::path tmp_path(_session_dir->root_path());
714 tmp_path /= snapshot_name + temp_suffix;
716 // cerr << "actually writing state to " << xml_path.to_string() << endl;
718 if (!tree.write (tmp_path.to_string())) {
719 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
720 sys::remove (tmp_path);
725 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
726 error << string_compose (_("could not rename temporary session file %1 to %2"),
727 tmp_path.to_string(), xml_path.to_string()) << endmsg;
728 sys::remove (tmp_path);
735 save_history (snapshot_name);
737 bool was_dirty = dirty();
739 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
742 DirtyChanged (); /* EMIT SIGNAL */
745 StateSaved (snapshot_name); /* EMIT SIGNAL */
752 Session::restore_state (string snapshot_name)
754 if (load_state (snapshot_name) == 0) {
755 set_state (*state_tree->root());
762 Session::load_state (string snapshot_name)
769 state_was_pending = false;
771 /* check for leftover pending state from a crashed capture attempt */
773 sys::path xmlpath(_session_dir->root_path());
774 xmlpath /= snapshot_name + pending_suffix;
776 if (sys::exists (xmlpath)) {
778 /* there is pending state from a crashed capture attempt */
780 if (AskAboutPendingState()) {
781 state_was_pending = true;
785 if (!state_was_pending) {
786 xmlpath = _session_dir->root_path();
787 xmlpath /= snapshot_name + statefile_suffix;
790 if (!sys::exists (xmlpath)) {
791 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
795 state_tree = new XMLTree;
799 if (!state_tree->read (xmlpath.to_string())) {
800 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
806 XMLNode& root (*state_tree->root());
808 if (root.name() != X_("Session")) {
809 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
815 const XMLProperty* prop;
818 if ((prop = root.property ("version")) == 0) {
819 /* no version implies very old version of Ardour */
823 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
824 if (major_version < 2) {
831 sys::path backup_path(_session_dir->root_path());
833 backup_path /= snapshot_name + "-1" + statefile_suffix;
835 // only create a backup once
836 if (sys::exists (backup_path)) {
840 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
841 xmlpath.to_string(), backup_path.to_string())
846 sys::copy_file (xmlpath, backup_path);
848 catch(sys::filesystem_error& ex)
850 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
851 xmlpath.to_string(), ex.what())
861 Session::load_options (const XMLNode& node)
865 LocaleGuard lg (X_("POSIX"));
867 Config->set_variables (node, ConfigVariableBase::Session);
869 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
870 if ((prop = child->property ("val")) != 0) {
871 _end_location_is_free = (prop->value() == "yes");
879 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
881 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
882 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
884 return owner & modified_by_session_or_user;
888 Session::get_options () const
891 LocaleGuard lg (X_("POSIX"));
893 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
895 child = option_root.add_child ("end-marker-is-free");
896 child->add_property ("val", _end_location_is_free ? "yes" : "no");
908 Session::get_template()
910 /* if we don't disable rec-enable, diskstreams
911 will believe they need to store their capture
912 sources in their state node.
915 disable_record (false);
921 Session::state(bool full_state)
923 XMLNode* node = new XMLNode("Session");
926 // store libardour version, just in case
928 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
929 node->add_property("version", string(buf));
931 /* store configuration settings */
935 node->add_property ("name", _name);
936 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
937 node->add_property ("sample-rate", buf);
939 if (session_dirs.size() > 1) {
943 vector<space_and_path>::iterator i = session_dirs.begin();
944 vector<space_and_path>::iterator next;
946 ++i; /* skip the first one */
950 while (i != session_dirs.end()) {
954 if (next != session_dirs.end()) {
964 child = node->add_child ("Path");
965 child->add_content (p);
969 /* save the ID counter */
971 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
972 node->add_property ("id-counter", buf);
974 /* various options */
976 node->add_child_nocopy (get_options());
978 child = node->add_child ("Sources");
981 Glib::Mutex::Lock sl (source_lock);
983 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
985 /* Don't save information about AudioFileSources that are empty */
987 boost::shared_ptr<AudioFileSource> fs;
989 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
991 /* Don't save sources that are empty, unless they're destructive (which are OK
992 if they are empty, because we will re-use them every time.)
995 if (!fs->destructive()) {
996 if (fs->length() == 0) {
1002 child->add_child_nocopy (siter->second->get_state());
1006 child = node->add_child ("Regions");
1009 Glib::Mutex::Lock rl (region_lock);
1011 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
1013 /* only store regions not attached to playlists */
1015 if (i->second->playlist() == 0) {
1016 child->add_child_nocopy (i->second->state (true));
1021 child = node->add_child ("DiskStreams");
1024 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1025 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1026 if (!(*i)->hidden()) {
1027 child->add_child_nocopy ((*i)->get_state());
1033 node->add_child_nocopy (_locations.get_state());
1035 // for a template, just create a new Locations, populate it
1036 // with the default start and end, and get the state for that.
1038 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1039 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1042 end->set_end(compute_initial_length());
1044 node->add_child_nocopy (loc.get_state());
1047 child = node->add_child ("Bundles");
1049 Glib::Mutex::Lock lm (bundle_lock);
1050 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
1051 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1053 child->add_child_nocopy (b->get_state());
1058 child = node->add_child ("Routes");
1060 boost::shared_ptr<RouteList> r = routes.reader ();
1062 RoutePublicOrderSorter cmp;
1063 RouteList public_order (*r);
1064 public_order.sort (cmp);
1066 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1067 if (!(*i)->is_hidden()) {
1069 child->add_child_nocopy ((*i)->get_state());
1071 child->add_child_nocopy ((*i)->get_template());
1078 child = node->add_child ("EditGroups");
1079 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1080 child->add_child_nocopy ((*i)->get_state());
1083 child = node->add_child ("MixGroups");
1084 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1085 child->add_child_nocopy ((*i)->get_state());
1088 child = node->add_child ("Playlists");
1089 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1090 if (!(*i)->hidden()) {
1091 if (!(*i)->empty()) {
1093 child->add_child_nocopy ((*i)->get_state());
1095 child->add_child_nocopy ((*i)->get_template());
1101 child = node->add_child ("UnusedPlaylists");
1102 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1103 if (!(*i)->hidden()) {
1104 if (!(*i)->empty()) {
1106 child->add_child_nocopy ((*i)->get_state());
1108 child->add_child_nocopy ((*i)->get_template());
1116 child = node->add_child ("Click");
1117 child->add_child_nocopy (_click_io->state (full_state));
1121 child = node->add_child ("NamedSelections");
1122 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1124 child->add_child_nocopy ((*i)->get_state());
1129 node->add_child_nocopy (_tempo_map->get_state());
1131 node->add_child_nocopy (get_control_protocol_state());
1134 node->add_child_copy (*_extra_xml);
1141 Session::get_control_protocol_state ()
1143 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1144 return cpm.get_state();
1148 Session::set_state (const XMLNode& node)
1152 const XMLProperty* prop;
1155 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1157 if (node.name() != X_("Session")){
1158 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1162 if ((prop = node.property ("name")) != 0) {
1163 _name = prop->value ();
1166 if ((prop = node.property (X_("sample-rate"))) != 0) {
1168 _nominal_frame_rate = atoi (prop->value());
1170 if (_nominal_frame_rate != _current_frame_rate) {
1171 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1177 setup_raid_path(_session_dir->root_path().to_string());
1179 if ((prop = node.property (X_("id-counter"))) != 0) {
1181 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1182 ID::init_counter (x);
1184 /* old sessions used a timebased counter, so fake
1185 the startup ID counter based on a standard
1190 ID::init_counter (now);
1194 IO::disable_ports ();
1195 IO::disable_connecting ();
1197 /* Object loading order:
1215 if (use_config_midi_ports ()) {
1218 if ((child = find_named_node (node, "extra")) != 0) {
1219 _extra_xml = new XMLNode (*child);
1222 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1223 load_options (*child);
1224 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1225 load_options (*child);
1227 error << _("Session: XML state has no options section") << endmsg;
1230 if ((child = find_named_node (node, "Locations")) == 0) {
1231 error << _("Session: XML state has no locations section") << endmsg;
1233 } else if (_locations.set_state (*child)) {
1239 if ((location = _locations.auto_loop_location()) != 0) {
1240 set_auto_loop_location (location);
1243 if ((location = _locations.auto_punch_location()) != 0) {
1244 set_auto_punch_location (location);
1247 if ((location = _locations.end_location()) == 0) {
1248 _locations.add (end_location);
1250 delete end_location;
1251 end_location = location;
1254 if ((location = _locations.start_location()) == 0) {
1255 _locations.add (start_location);
1257 delete start_location;
1258 start_location = location;
1261 AudioFileSource::set_header_position_offset (start_location->start());
1263 if ((child = find_named_node (node, "Sources")) == 0) {
1264 error << _("Session: XML state has no sources section") << endmsg;
1266 } else if (load_sources (*child)) {
1270 if ((child = find_named_node (node, "Regions")) == 0) {
1271 error << _("Session: XML state has no Regions section") << endmsg;
1273 } else if (load_regions (*child)) {
1277 if ((child = find_named_node (node, "Playlists")) == 0) {
1278 error << _("Session: XML state has no playlists section") << endmsg;
1280 } else if (load_playlists (*child)) {
1284 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1286 } else if (load_unused_playlists (*child)) {
1290 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1291 if (load_named_selections (*child)) {
1296 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1297 error << _("Session: XML state has no diskstreams section") << endmsg;
1299 } else if (load_diskstreams (*child)) {
1303 if ((child = find_named_node (node, "Bundles")) == 0) {
1304 warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg;
1307 /* We can't load Bundles yet as they need to be able
1308 to convert from port names to Port objects, which can't happen until
1310 _bundle_xml_node = new XMLNode (*child);
1313 if ((child = find_named_node (node, "EditGroups")) == 0) {
1314 error << _("Session: XML state has no edit groups section") << endmsg;
1316 } else if (load_edit_groups (*child)) {
1320 if ((child = find_named_node (node, "MixGroups")) == 0) {
1321 error << _("Session: XML state has no mix groups section") << endmsg;
1323 } else if (load_mix_groups (*child)) {
1327 if ((child = find_named_node (node, "TempoMap")) == 0) {
1328 error << _("Session: XML state has no Tempo Map section") << endmsg;
1330 } else if (_tempo_map->set_state (*child)) {
1334 if ((child = find_named_node (node, "Routes")) == 0) {
1335 error << _("Session: XML state has no routes section") << endmsg;
1337 } else if (load_routes (*child)) {
1341 if ((child = find_named_node (node, "Click")) == 0) {
1342 warning << _("Session: XML state has no click section") << endmsg;
1343 } else if (_click_io) {
1344 _click_io->set_state (*child);
1347 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1348 ControlProtocolManager::instance().set_protocol_states (*child);
1351 /* here beginneth the second phase ... */
1353 StateReady (); /* EMIT SIGNAL */
1362 Session::load_routes (const XMLNode& node)
1365 XMLNodeConstIterator niter;
1366 RouteList new_routes;
1368 nlist = node.children();
1372 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1374 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1377 error << _("Session: cannot create Route from XML description.") << endmsg;
1381 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1383 new_routes.push_back (route);
1386 add_routes (new_routes, false);
1391 boost::shared_ptr<Route>
1392 Session::XMLRouteFactory (const XMLNode& node)
1394 if (node.name() != "Route") {
1395 return boost::shared_ptr<Route> ((Route*) 0);
1398 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1400 DataType type = DataType::AUDIO;
1401 const XMLProperty* prop = node.property("default-type");
1403 type = DataType(prop->value());
1405 assert(type != DataType::NIL);
1407 if (has_diskstream) {
1408 if (type == DataType::AUDIO) {
1409 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1412 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1416 boost::shared_ptr<Route> ret (new Route (*this, node));
1422 Session::load_regions (const XMLNode& node)
1425 XMLNodeConstIterator niter;
1426 boost::shared_ptr<Region> region;
1428 nlist = node.children();
1432 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1433 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1434 error << _("Session: cannot create Region from XML description.");
1435 const XMLProperty *name = (**niter).property("name");
1438 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1448 boost::shared_ptr<Region>
1449 Session::XMLRegionFactory (const XMLNode& node, bool full)
1451 const XMLProperty* type = node.property("type");
1455 if ( !type || type->value() == "audio" ) {
1457 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1459 } else if (type->value() == "midi") {
1461 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1465 } catch (failed_constructor& err) {
1466 return boost::shared_ptr<Region> ();
1469 return boost::shared_ptr<Region> ();
1472 boost::shared_ptr<AudioRegion>
1473 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1475 const XMLProperty* prop;
1476 boost::shared_ptr<Source> source;
1477 boost::shared_ptr<AudioSource> as;
1479 SourceList master_sources;
1480 uint32_t nchans = 1;
1483 if (node.name() != X_("Region")) {
1484 return boost::shared_ptr<AudioRegion>();
1487 if ((prop = node.property (X_("channels"))) != 0) {
1488 nchans = atoi (prop->value().c_str());
1491 if ((prop = node.property ("name")) == 0) {
1492 cerr << "no name for this region\n";
1496 if ((prop = node.property (X_("source-0"))) == 0) {
1497 if ((prop = node.property ("source")) == 0) {
1498 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1499 return boost::shared_ptr<AudioRegion>();
1503 PBD::ID s_id (prop->value());
1505 if ((source = source_by_id (s_id)) == 0) {
1506 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1507 return boost::shared_ptr<AudioRegion>();
1510 as = boost::dynamic_pointer_cast<AudioSource>(source);
1512 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1513 return boost::shared_ptr<AudioRegion>();
1516 sources.push_back (as);
1518 /* pickup other channels */
1520 for (uint32_t n=1; n < nchans; ++n) {
1521 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1522 if ((prop = node.property (buf)) != 0) {
1524 PBD::ID id2 (prop->value());
1526 if ((source = source_by_id (id2)) == 0) {
1527 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1528 return boost::shared_ptr<AudioRegion>();
1531 as = boost::dynamic_pointer_cast<AudioSource>(source);
1533 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1534 return boost::shared_ptr<AudioRegion>();
1536 sources.push_back (as);
1540 for (uint32_t n=1; n < nchans; ++n) {
1541 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1542 if ((prop = node.property (buf)) != 0) {
1544 PBD::ID id2 (prop->value());
1546 if ((source = source_by_id (id2)) == 0) {
1547 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1548 return boost::shared_ptr<AudioRegion>();
1551 as = boost::dynamic_pointer_cast<AudioSource>(source);
1553 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1554 return boost::shared_ptr<AudioRegion>();
1556 master_sources.push_back (as);
1561 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1563 /* a final detail: this is the one and only place that we know how long missing files are */
1565 if (region->whole_file()) {
1566 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1567 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1569 sfp->set_length (region->length());
1574 if (!master_sources.empty()) {
1575 if (master_sources.size() == nchans) {
1576 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1578 region->set_master_sources (master_sources);
1586 catch (failed_constructor& err) {
1587 return boost::shared_ptr<AudioRegion>();
1591 boost::shared_ptr<MidiRegion>
1592 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1594 const XMLProperty* prop;
1595 boost::shared_ptr<Source> source;
1596 boost::shared_ptr<MidiSource> ms;
1598 uint32_t nchans = 1;
1600 if (node.name() != X_("Region")) {
1601 return boost::shared_ptr<MidiRegion>();
1604 if ((prop = node.property (X_("channels"))) != 0) {
1605 nchans = atoi (prop->value().c_str());
1608 if ((prop = node.property ("name")) == 0) {
1609 cerr << "no name for this region\n";
1613 // Multiple midi channels? that's just crazy talk
1614 assert(nchans == 1);
1616 if ((prop = node.property (X_("source-0"))) == 0) {
1617 if ((prop = node.property ("source")) == 0) {
1618 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1619 return boost::shared_ptr<MidiRegion>();
1623 PBD::ID s_id (prop->value());
1625 if ((source = source_by_id (s_id)) == 0) {
1626 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1627 return boost::shared_ptr<MidiRegion>();
1630 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1632 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1633 return boost::shared_ptr<MidiRegion>();
1636 sources.push_back (ms);
1639 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1640 /* a final detail: this is the one and only place that we know how long missing files are */
1642 if (region->whole_file()) {
1643 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1644 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1646 sfp->set_length (region->length());
1654 catch (failed_constructor& err) {
1655 return boost::shared_ptr<MidiRegion>();
1660 Session::get_sources_as_xml ()
1663 XMLNode* node = new XMLNode (X_("Sources"));
1664 Glib::Mutex::Lock lm (source_lock);
1666 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1667 node->add_child_nocopy (i->second->get_state());
1674 Session::path_from_region_name (DataType type, string name, string identifier)
1676 char buf[PATH_MAX+1];
1678 SessionDirectory sdir(get_best_session_directory_for_new_source());
1679 sys::path source_dir = ((type == DataType::AUDIO)
1680 ? sdir.sound_path() : sdir.midi_path());
1682 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1684 for (n = 0; n < 999999; ++n) {
1685 if (identifier.length()) {
1686 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1687 identifier.c_str(), n, ext.c_str());
1689 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1693 sys::path source_path = source_dir / buf;
1695 if (!sys::exists (source_path)) {
1696 return source_path.to_string();
1700 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1709 Session::load_sources (const XMLNode& node)
1712 XMLNodeConstIterator niter;
1713 boost::shared_ptr<Source> source;
1715 nlist = node.children();
1719 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1722 if ((source = XMLSourceFactory (**niter)) == 0) {
1723 error << _("Session: cannot create Source from XML description.") << endmsg;
1727 catch (non_existent_source& err) {
1728 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1729 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1736 boost::shared_ptr<Source>
1737 Session::XMLSourceFactory (const XMLNode& node)
1739 if (node.name() != "Source") {
1740 return boost::shared_ptr<Source>();
1744 /* note: do peak building in another thread when loading session state */
1745 return SourceFactory::create (*this, node, true);
1748 catch (failed_constructor& err) {
1749 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1750 return boost::shared_ptr<Source>();
1755 Session::save_template (string template_name)
1759 if (_state_of_the_state & CannotSave) {
1763 sys::path user_template_dir(user_template_directory());
1767 sys::create_directories (user_template_dir);
1769 catch(sys::filesystem_error& ex)
1771 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1772 user_template_dir.to_string(), ex.what()) << endmsg;
1776 tree.set_root (&get_template());
1778 sys::path template_file_path(user_template_dir);
1779 template_file_path /= template_name + template_suffix;
1781 if (sys::exists (template_file_path))
1783 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1784 template_file_path.to_string()) << endmsg;
1788 if (!tree.write (template_file_path.to_string())) {
1789 error << _("mix template not saved") << endmsg;
1797 Session::refresh_disk_space ()
1800 struct statfs statfsbuf;
1801 vector<space_and_path>::iterator i;
1802 Glib::Mutex::Lock lm (space_lock);
1805 /* get freespace on every FS that is part of the session path */
1807 _total_free_4k_blocks = 0;
1809 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1810 statfs ((*i).path.c_str(), &statfsbuf);
1812 scale = statfsbuf.f_bsize/4096.0;
1814 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1815 _total_free_4k_blocks += (*i).blocks;
1821 Session::get_best_session_directory_for_new_source ()
1823 vector<space_and_path>::iterator i;
1824 string result = _session_dir->root_path().to_string();
1826 /* handle common case without system calls */
1828 if (session_dirs.size() == 1) {
1832 /* OK, here's the algorithm we're following here:
1834 We want to select which directory to use for
1835 the next file source to be created. Ideally,
1836 we'd like to use a round-robin process so as to
1837 get maximum performance benefits from splitting
1838 the files across multiple disks.
1840 However, in situations without much diskspace, an
1841 RR approach may end up filling up a filesystem
1842 with new files while others still have space.
1843 Its therefore important to pay some attention to
1844 the freespace in the filesystem holding each
1845 directory as well. However, if we did that by
1846 itself, we'd keep creating new files in the file
1847 system with the most space until it was as full
1848 as all others, thus negating any performance
1849 benefits of this RAID-1 like approach.
1851 So, we use a user-configurable space threshold. If
1852 there are at least 2 filesystems with more than this
1853 much space available, we use RR selection between them.
1854 If not, then we pick the filesystem with the most space.
1856 This gets a good balance between the two
1860 refresh_disk_space ();
1862 int free_enough = 0;
1864 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1865 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1870 if (free_enough >= 2) {
1871 /* use RR selection process, ensuring that the one
1875 i = last_rr_session_dir;
1878 if (++i == session_dirs.end()) {
1879 i = session_dirs.begin();
1882 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1883 if (create_session_directory ((*i).path)) {
1885 last_rr_session_dir = i;
1890 } while (i != last_rr_session_dir);
1894 /* pick FS with the most freespace (and that
1895 seems to actually work ...)
1898 vector<space_and_path> sorted;
1899 space_and_path_ascending_cmp cmp;
1901 sorted = session_dirs;
1902 sort (sorted.begin(), sorted.end(), cmp);
1904 for (i = sorted.begin(); i != sorted.end(); ++i) {
1905 if (create_session_directory ((*i).path)) {
1907 last_rr_session_dir = i;
1917 Session::load_playlists (const XMLNode& node)
1920 XMLNodeConstIterator niter;
1921 boost::shared_ptr<Playlist> playlist;
1923 nlist = node.children();
1927 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1929 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1930 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1938 Session::load_unused_playlists (const XMLNode& node)
1941 XMLNodeConstIterator niter;
1942 boost::shared_ptr<Playlist> playlist;
1944 nlist = node.children();
1948 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1950 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1951 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1955 // now manually untrack it
1957 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1963 boost::shared_ptr<Playlist>
1964 Session::XMLPlaylistFactory (const XMLNode& node)
1967 return PlaylistFactory::create (*this, node);
1970 catch (failed_constructor& err) {
1971 return boost::shared_ptr<Playlist>();
1976 Session::load_named_selections (const XMLNode& node)
1979 XMLNodeConstIterator niter;
1982 nlist = node.children();
1986 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1988 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1989 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1997 Session::XMLNamedSelectionFactory (const XMLNode& node)
2000 return new NamedSelection (*this, node);
2003 catch (failed_constructor& err) {
2009 Session::automation_dir () const
2012 res += "automation/";
2017 Session::analysis_dir () const
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 current_trans = new UndoTransaction;
2216 current_trans->set_name (name);
2220 Session::commit_reversible_command (Command *cmd)
2225 current_trans->add_command (cmd);
2228 if (current_trans->empty()) {
2232 gettimeofday (&now, 0);
2233 current_trans->set_timestamp (now);
2235 _history.add (current_trans);
2238 Session::GlobalRouteBooleanState
2239 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2241 GlobalRouteBooleanState s;
2242 boost::shared_ptr<RouteList> r = routes.reader ();
2244 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2245 if (!(*i)->is_hidden()) {
2246 RouteBooleanState v;
2249 Route* r = (*i).get();
2250 v.second = (r->*method)();
2259 Session::GlobalRouteMeterState
2260 Session::get_global_route_metering ()
2262 GlobalRouteMeterState s;
2263 boost::shared_ptr<RouteList> r = routes.reader ();
2265 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2266 if (!(*i)->is_hidden()) {
2270 v.second = (*i)->meter_point();
2280 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2282 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2284 boost::shared_ptr<Route> r = (i->first.lock());
2287 r->set_meter_point (i->second, arg);
2293 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2295 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2297 boost::shared_ptr<Route> r = (i->first.lock());
2300 Route* rp = r.get();
2301 (rp->*method) (i->second, arg);
2307 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2309 set_global_route_boolean (s, &Route::set_mute, src);
2313 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2315 set_global_route_boolean (s, &Route::set_solo, src);
2319 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2321 set_global_route_boolean (s, &Route::set_record_enable, src);
2326 Session::global_mute_memento (void* src)
2328 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2332 Session::global_metering_memento (void* src)
2334 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2338 Session::global_solo_memento (void* src)
2340 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2344 Session::global_record_enable_memento (void* src)
2346 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2351 accept_all_non_peak_files (const string& path, void *arg)
2353 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2357 accept_all_state_files (const string& path, void *arg)
2359 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2363 Session::find_all_sources (string path, set<string>& result)
2368 if (!tree.read (path)) {
2372 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2377 XMLNodeConstIterator niter;
2379 nlist = node->children();
2383 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2387 if ((prop = (*niter)->property (X_("name"))) == 0) {
2391 if (prop->value()[0] == '/') {
2392 /* external file, ignore */
2396 sys::path source_path = _session_dir->sound_path ();
2398 source_path /= prop->value ();
2400 result.insert (source_path.to_string ());
2407 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2409 PathScanner scanner;
2410 vector<string*>* state_files;
2412 string this_snapshot_path;
2418 if (ripped[ripped.length()-1] == '/') {
2419 ripped = ripped.substr (0, ripped.length() - 1);
2422 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2424 if (state_files == 0) {
2429 this_snapshot_path = _path;
2430 this_snapshot_path += _current_snapshot_name;
2431 this_snapshot_path += statefile_suffix;
2433 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2435 if (exclude_this_snapshot && **i == this_snapshot_path) {
2439 if (find_all_sources (**i, result) < 0) {
2447 struct RegionCounter {
2448 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2449 AudioSourceList::iterator iter;
2450 boost::shared_ptr<Region> region;
2453 RegionCounter() : count (0) {}
2457 Session::cleanup_sources (Session::cleanup_report& rep)
2459 // FIXME: needs adaptation to midi
2461 vector<boost::shared_ptr<Source> > dead_sources;
2462 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2463 PathScanner scanner;
2465 vector<space_and_path>::iterator i;
2466 vector<space_and_path>::iterator nexti;
2467 vector<string*>* soundfiles;
2468 vector<string> unused;
2469 set<string> all_sources;
2474 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2477 /* step 1: consider deleting all unused playlists */
2479 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2482 status = AskAboutPlaylistDeletion (*x);
2491 playlists_tbd.push_back (*x);
2495 /* leave it alone */
2500 /* now delete any that were marked for deletion */
2502 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2503 (*x)->drop_references ();
2506 playlists_tbd.clear ();
2508 /* step 2: find all un-used sources */
2513 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2515 SourceMap::iterator tmp;
2520 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2524 if (!i->second->used() && i->second->length() > 0) {
2525 dead_sources.push_back (i->second);
2526 i->second->GoingAway();
2532 /* build a list of all the possible sound directories for the session */
2534 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2539 SessionDirectory sdir ((*i).path);
2540 sound_path += sdir.sound_path().to_string();
2542 if (nexti != session_dirs.end()) {
2549 /* now do the same thing for the files that ended up in the sounds dir(s)
2550 but are not referenced as sources in any snapshot.
2553 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2555 if (soundfiles == 0) {
2559 /* find all sources, but don't use this snapshot because the
2560 state file on disk still references sources we may have already
2564 find_all_sources_across_snapshots (all_sources, true);
2566 /* add our current source list
2569 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2570 boost::shared_ptr<AudioFileSource> fs;
2572 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2573 all_sources.insert (fs->path());
2577 char tmppath1[PATH_MAX+1];
2578 char tmppath2[PATH_MAX+1];
2580 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2585 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2587 realpath(spath.c_str(), tmppath1);
2588 realpath((*i).c_str(), tmppath2);
2590 if (strcmp(tmppath1, tmppath2) == 0) {
2597 unused.push_back (spath);
2601 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2603 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2604 struct stat statbuf;
2606 rep.paths.push_back (*x);
2607 if (stat ((*x).c_str(), &statbuf) == 0) {
2608 rep.space += statbuf.st_size;
2613 /* don't move the file across filesystems, just
2614 stick it in the `dead_sound_dir_name' directory
2615 on whichever filesystem it was already on.
2618 if ((*x).find ("/sounds/") != string::npos) {
2620 /* old school, go up 1 level */
2622 newpath = Glib::path_get_dirname (*x); // "sounds"
2623 newpath = Glib::path_get_dirname (newpath); // "session-name"
2627 /* new school, go up 4 levels */
2629 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2630 newpath = Glib::path_get_dirname (newpath); // "session-name"
2631 newpath = Glib::path_get_dirname (newpath); // "interchange"
2632 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2636 newpath += dead_sound_dir_name;
2638 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2639 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2644 newpath += Glib::path_get_basename ((*x));
2646 if (access (newpath.c_str(), F_OK) == 0) {
2648 /* the new path already exists, try versioning */
2650 char buf[PATH_MAX+1];
2654 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2657 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2658 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2662 if (version == 999) {
2663 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2667 newpath = newpath_v;
2672 /* it doesn't exist, or we can't read it or something */
2676 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2677 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2678 (*x), newpath, strerror (errno))
2683 /* see if there an easy to find peakfile for this file, and remove it.
2686 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2687 peakpath += peakfile_suffix;
2689 if (access (peakpath.c_str(), W_OK) == 0) {
2690 if (::unlink (peakpath.c_str()) != 0) {
2691 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2692 peakpath, _path, strerror (errno))
2694 /* try to back out */
2695 rename (newpath.c_str(), _path.c_str());
2703 /* dump the history list */
2707 /* save state so we don't end up a session file
2708 referring to non-existent sources.
2714 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2720 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2722 // FIXME: needs adaptation for MIDI
2724 vector<space_and_path>::iterator i;
2725 string dead_sound_dir;
2726 struct dirent* dentry;
2727 struct stat statbuf;
2733 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2735 dead_sound_dir = (*i).path;
2736 dead_sound_dir += dead_sound_dir_name;
2738 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2742 while ((dentry = readdir (dead)) != 0) {
2744 /* avoid '.' and '..' */
2746 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2747 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2753 fullpath = dead_sound_dir;
2755 fullpath += dentry->d_name;
2757 if (stat (fullpath.c_str(), &statbuf)) {
2761 if (!S_ISREG (statbuf.st_mode)) {
2765 if (unlink (fullpath.c_str())) {
2766 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2767 fullpath, strerror (errno))
2771 rep.paths.push_back (dentry->d_name);
2772 rep.space += statbuf.st_size;
2783 Session::set_dirty ()
2785 bool was_dirty = dirty();
2787 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2791 DirtyChanged(); /* EMIT SIGNAL */
2797 Session::set_clean ()
2799 bool was_dirty = dirty();
2801 _state_of_the_state = Clean;
2805 DirtyChanged(); /* EMIT SIGNAL */
2810 Session::set_deletion_in_progress ()
2812 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2817 Session::add_controllable (boost::shared_ptr<Controllable> c)
2819 /* this adds a controllable to the list managed by the Session.
2820 this is a subset of those managed by the Controllable class
2821 itself, and represents the only ones whose state will be saved
2822 as part of the session.
2825 Glib::Mutex::Lock lm (controllables_lock);
2826 controllables.insert (c);
2829 struct null_deleter { void operator()(void const *) const {} };
2832 Session::remove_controllable (Controllable* c)
2834 if (_state_of_the_state | Deletion) {
2838 Glib::Mutex::Lock lm (controllables_lock);
2840 Controllables::iterator x = controllables.find(
2841 boost::shared_ptr<Controllable>(c, null_deleter()));
2843 if (x != controllables.end()) {
2844 controllables.erase (x);
2848 boost::shared_ptr<Controllable>
2849 Session::controllable_by_id (const PBD::ID& id)
2851 Glib::Mutex::Lock lm (controllables_lock);
2853 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2854 if ((*i)->id() == id) {
2859 return boost::shared_ptr<Controllable>();
2863 Session::add_instant_xml (XMLNode& node)
2865 Stateful::add_instant_xml (node, _path);
2866 Config->add_instant_xml (node);
2870 Session::instant_xml (const string& node_name)
2872 return Stateful::instant_xml (node_name, _path);
2876 Session::save_history (string snapshot_name)
2880 if (snapshot_name.empty()) {
2881 snapshot_name = _current_snapshot_name;
2884 const string history_filename = snapshot_name + history_suffix;
2885 const string backup_filename = history_filename + backup_suffix;
2886 const sys::path xml_path = _session_dir->root_path() / history_filename;
2887 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2889 if (sys::exists (xml_path)) {
2892 sys::rename (xml_path, backup_path);
2894 catch (const sys::filesystem_error& err)
2896 error << _("could not backup old history file, current history not saved") << endmsg;
2902 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2906 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2908 if (!tree.write (xml_path.to_string()))
2910 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2914 sys::remove (xml_path);
2915 sys::rename (backup_path, xml_path);
2917 catch (const sys::filesystem_error& err)
2919 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2920 backup_path.to_string(), err.what()) << endmsg;
2930 Session::restore_history (string snapshot_name)
2934 if (snapshot_name.empty()) {
2935 snapshot_name = _current_snapshot_name;
2938 const string xml_filename = snapshot_name + history_suffix;
2939 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2941 cerr << "Loading history from " << xml_path.to_string() << endmsg;
2943 if (!sys::exists (xml_path)) {
2944 info << string_compose (_("%1: no history file \"%2\" for this session."),
2945 _name, xml_path.to_string()) << endmsg;
2949 if (!tree.read (xml_path.to_string())) {
2950 error << string_compose (_("Could not understand session history file \"%1\""),
2951 xml_path.to_string()) << endmsg;
2958 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2961 UndoTransaction* ut = new UndoTransaction ();
2964 ut->set_name(t->property("name")->value());
2965 stringstream ss(t->property("tv_sec")->value());
2967 ss.str(t->property("tv_usec")->value());
2969 ut->set_timestamp(tv);
2971 for (XMLNodeConstIterator child_it = t->children().begin();
2972 child_it != t->children().end();
2975 XMLNode *n = *child_it;
2978 if (n->name() == "MementoCommand" ||
2979 n->name() == "MementoUndoCommand" ||
2980 n->name() == "MementoRedoCommand") {
2982 if ((c = memento_command_factory(n))) {
2986 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2988 if ((c = global_state_command_factory (*n))) {
2989 ut->add_command (c);
2994 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3005 Session::config_changed (const char* parameter_name)
3007 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3009 if (PARAM_IS ("seamless-loop")) {
3011 } else if (PARAM_IS ("rf-speed")) {
3013 } else if (PARAM_IS ("auto-loop")) {
3015 } else if (PARAM_IS ("auto-input")) {
3017 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3018 /* auto-input only makes a difference if we're rolling */
3020 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3022 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3023 if ((*i)->record_enabled ()) {
3024 (*i)->monitor_input (!Config->get_auto_input());
3029 } else if (PARAM_IS ("punch-in")) {
3033 if ((location = _locations.auto_punch_location()) != 0) {
3035 if (Config->get_punch_in ()) {
3036 replace_event (Event::PunchIn, location->start());
3038 remove_event (location->start(), Event::PunchIn);
3042 } else if (PARAM_IS ("punch-out")) {
3046 if ((location = _locations.auto_punch_location()) != 0) {
3048 if (Config->get_punch_out()) {
3049 replace_event (Event::PunchOut, location->end());
3051 clear_events (Event::PunchOut);
3055 } else if (PARAM_IS ("edit-mode")) {
3057 Glib::Mutex::Lock lm (playlist_lock);
3059 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3060 (*i)->set_edit_mode (Config->get_edit_mode ());
3063 } else if (PARAM_IS ("use-video-sync")) {
3065 waiting_for_sync_offset = Config->get_use_video_sync();
3067 } else if (PARAM_IS ("mmc-control")) {
3069 //poke_midi_thread ();
3071 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
3074 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3077 } else if (PARAM_IS ("mmc-send-id")) {
3080 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3083 } else if (PARAM_IS ("midi-control")) {
3085 //poke_midi_thread ();
3087 } else if (PARAM_IS ("raid-path")) {
3089 setup_raid_path (Config->get_raid_path());
3091 } else if (PARAM_IS ("smpte-format")) {
3095 } else if (PARAM_IS ("video-pullup")) {
3099 } else if (PARAM_IS ("seamless-loop")) {
3101 if (play_loop && transport_rolling()) {
3102 // to reset diskstreams etc
3103 request_play_loop (true);
3106 } else if (PARAM_IS ("rf-speed")) {
3108 cumulative_rf_motion = 0;
3111 } else if (PARAM_IS ("click-sound")) {
3113 setup_click_sounds (1);
3115 } else if (PARAM_IS ("click-emphasis-sound")) {
3117 setup_click_sounds (-1);
3119 } else if (PARAM_IS ("clicking")) {
3121 if (Config->get_clicking()) {
3122 if (_click_io && click_data) { // don't require emphasis data
3129 } else if (PARAM_IS ("send-mtc")) {
3131 /* only set the internal flag if we have
3135 if (_mtc_port != 0) {
3136 session_send_mtc = Config->get_send_mtc();
3137 if (session_send_mtc) {
3138 /* mark us ready to send */
3139 next_quarter_frame_to_send = 0;
3142 session_send_mtc = false;
3145 } else if (PARAM_IS ("send-mmc")) {
3147 /* only set the internal flag if we have
3151 if (_mmc_port != 0) {
3152 session_send_mmc = Config->get_send_mmc();
3155 session_send_mmc = false;
3158 } else if (PARAM_IS ("midi-feedback")) {
3160 /* only set the internal flag if we have
3164 if (_mtc_port != 0) {
3165 session_midi_feedback = Config->get_midi_feedback();
3168 } else if (PARAM_IS ("jack-time-master")) {
3170 engine().reset_timebase ();
3172 } else if (PARAM_IS ("native-file-header-format")) {
3174 if (!first_file_header_format_reset) {
3175 reset_native_file_format ();
3178 first_file_header_format_reset = false;
3180 } else if (PARAM_IS ("native-file-data-format")) {
3182 if (!first_file_data_format_reset) {
3183 reset_native_file_format ();
3186 first_file_data_format_reset = false;
3188 } else if (PARAM_IS ("slave-source")) {
3189 set_slave_source (Config->get_slave_source());
3190 } else if (PARAM_IS ("remote-model")) {
3191 set_remote_control_ids ();
3192 } else if (PARAM_IS ("denormal-model")) {
3194 } else if (PARAM_IS ("history-depth")) {
3195 set_history_depth (Config->get_history_depth());
3196 } else if (PARAM_IS ("sync-all-route-ordering")) {
3207 Session::set_history_depth (uint32_t d)
3209 _history.set_depth (d);