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/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 audio_dstream_buffer_size = 0;
172 midi_dstream_buffer_size = 0;
174 state_was_pending = false;
176 outbound_mtc_smpte_frame = 0;
177 next_quarter_frame_to_send = -1;
178 current_block_size = 0;
179 solo_update_disabled = false;
180 currently_soloing = false;
181 _have_captured = false;
182 _worst_output_latency = 0;
183 _worst_input_latency = 0;
184 _worst_track_latency = 0;
185 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
188 butler_mixdown_buffer = 0;
189 butler_gain_buffer = 0;
191 session_send_mmc = false;
192 session_send_mtc = false;
193 post_transport_work = PostTransportWork (0);
194 g_atomic_int_set (&butler_should_do_transport_work, 0);
195 g_atomic_int_set (&butler_active, 0);
196 g_atomic_int_set (&_playback_load, 100);
197 g_atomic_int_set (&_capture_load, 100);
198 g_atomic_int_set (&_playback_load_min, 100);
199 g_atomic_int_set (&_capture_load_min, 100);
201 waiting_to_start = false;
203 _exporting_realtime = false;
204 _gain_automation_buffer = 0;
205 _pan_automation_buffer = 0;
207 pending_abort = false;
208 destructive_index = 0;
210 first_file_data_format_reset = true;
211 first_file_header_format_reset = true;
212 butler_thread = (pthread_t) 0;
213 //midi_thread = (pthread_t) 0;
215 AudioDiskstream::allocate_working_buffers();
217 /* default short fade = 15ms */
219 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
220 SndFileSource::setup_standard_crossfades (frame_rate());
222 last_mmc_step.tv_sec = 0;
223 last_mmc_step.tv_usec = 0;
226 /* click sounds are unset by default, which causes us to internal
227 waveforms for clicks.
231 click_emphasis_data = 0;
233 click_emphasis_length = 0;
236 process_function = &Session::process_with_events;
238 if (Config->get_use_video_sync()) {
239 waiting_for_sync_offset = true;
241 waiting_for_sync_offset = false;
246 _smpte_offset_negative = true;
247 last_smpte_valid = false;
251 last_rr_session_dir = session_dirs.begin();
252 refresh_disk_space ();
254 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
258 average_slave_delta = 1800;
259 have_first_delta_accumulator = false;
260 delta_accumulator_cnt = 0;
261 slave_state = Stopped;
263 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
265 /* These are all static "per-class" signals */
267 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
268 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
269 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
270 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
271 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
272 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
274 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
276 IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
278 /* stop IO objects from doing stuff until we're ready for them */
280 IO::disable_panners ();
281 IO::disable_ports ();
282 IO::disable_connecting ();
286 Session::second_stage_init (bool new_session)
288 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
291 if (load_state (_current_snapshot_name)) {
294 remove_empty_sounds ();
297 if (start_butler_thread()) {
301 if (start_midi_thread ()) {
305 // set_state() will call setup_raid_path(), but if it's a new session we need
306 // to call setup_raid_path() here.
309 if (set_state (*state_tree->root())) {
313 setup_raid_path(_path);
316 /* we can't save till after ::when_engine_running() is called,
317 because otherwise we save state with no connections made.
318 therefore, we reset _state_of_the_state because ::set_state()
319 will have cleared it.
321 we also have to include Loading so that any events that get
322 generated between here and the end of ::when_engine_running()
323 will be processed directly rather than queued.
326 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
329 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
330 _locations.added.connect (mem_fun (this, &Session::locations_added));
331 setup_click_sounds (0);
332 setup_midi_control ();
334 /* Pay attention ... */
336 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
337 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
340 when_engine_running();
343 /* handle this one in a different way than all others, so that its clear what happened */
345 catch (AudioEngine::PortRegistrationFailure& err) {
346 error << _("Unable to create all required ports")
355 BootMessage (_("Reset Remote Controls"));
357 send_full_time_code (0);
358 _engine.transport_locate (0);
359 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
360 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
362 BootMessage (_("Reset Control Protocols"));
364 ControlProtocolManager::instance().set_session (*this);
367 _end_location_is_free = true;
369 _end_location_is_free = false;
372 _state_of_the_state = Clean;
374 DirtyChanged (); /* EMIT SIGNAL */
376 if (state_was_pending) {
377 save_state (_current_snapshot_name);
378 remove_pending_capture_state ();
379 state_was_pending = false;
382 BootMessage (_("Session loading complete"));
388 Session::raid_path () const
390 SearchPath raid_search_path;
392 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
393 raid_search_path += sys::path((*i).path);
396 return raid_search_path.to_string ();
400 Session::setup_raid_path (string path)
409 session_dirs.clear ();
411 SearchPath search_path(path);
412 SearchPath sound_search_path;
413 SearchPath midi_search_path;
416 SearchPath::const_iterator i = search_path.begin();
417 i != search_path.end();
421 sp.path = (*i).to_string ();
422 sp.blocks = 0; // not needed
423 session_dirs.push_back (sp);
425 SessionDirectory sdir(sp.path);
427 sound_search_path += sdir.sound_path ();
428 midi_search_path += sdir.midi_path ();
431 // set the AudioFileSource and SMFSource search path
433 AudioFileSource::set_search_path (sound_search_path.to_string ());
434 SMFSource::set_search_path (midi_search_path.to_string ());
437 // reset the round-robin soundfile path thingie
439 last_rr_session_dir = session_dirs.begin();
443 Session::ensure_subdirs ()
447 dir = session_directory().peak_path().to_string();
449 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
450 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
454 dir = session_directory().sound_path().to_string();
456 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
457 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
461 dir = session_directory().midi_path().to_string();
463 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
464 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
468 dir = session_directory().dead_sound_path().to_string();
470 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
471 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
475 dir = session_directory().export_path().to_string();
477 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
478 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
482 dir = analysis_dir ();
484 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
485 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
493 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
496 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
497 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
501 if (ensure_subdirs ()) {
505 /* check new_session so we don't overwrite an existing one */
507 if (!mix_template.empty()) {
508 std::string in_path = mix_template;
510 ifstream in(in_path.c_str());
513 string out_path = _path;
515 out_path += statefile_suffix;
517 ofstream out(out_path.c_str());
522 // okay, session is set up. Treat like normal saved
523 // session from now on.
529 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
535 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
542 /* Instantiate metadata */
544 _metadata = new SessionMetadata ();
546 /* set initial start + end point */
548 start_location->set_end (0);
549 _locations.add (start_location);
551 end_location->set_end (initial_length);
552 _locations.add (end_location);
554 _state_of_the_state = Clean;
563 Session::load_diskstreams (const XMLNode& node)
566 XMLNodeConstIterator citer;
568 clist = node.children();
570 for (citer = clist.begin(); citer != clist.end(); ++citer) {
573 /* diskstreams added automatically by DiskstreamCreated handler */
574 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
575 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
576 add_diskstream (dstream);
577 } else if ((*citer)->name() == "MidiDiskstream") {
578 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
579 add_diskstream (dstream);
581 error << _("Session: unknown diskstream type in XML") << endmsg;
585 catch (failed_constructor& err) {
586 error << _("Session: could not load diskstream via XML state") << endmsg;
595 Session::maybe_write_autosave()
597 if (dirty() && record_status() != Recording) {
598 save_state("", true);
603 Session::remove_pending_capture_state ()
605 sys::path pending_state_file_path(_session_dir->root_path());
607 pending_state_file_path /= _current_snapshot_name + pending_suffix;
611 sys::remove (pending_state_file_path);
613 catch(sys::filesystem_error& ex)
615 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
616 pending_state_file_path.to_string(), ex.what()) << endmsg;
620 /** Rename a state file.
621 * @param snapshot_name Snapshot name.
624 Session::rename_state (string old_name, string new_name)
626 if (old_name == _current_snapshot_name || old_name == _name) {
627 /* refuse to rename the current snapshot or the "main" one */
631 const string old_xml_filename = old_name + statefile_suffix;
632 const string new_xml_filename = new_name + statefile_suffix;
634 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
635 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
639 sys::rename (old_xml_path, new_xml_path);
641 catch (const sys::filesystem_error& err)
643 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
644 old_name, new_name, err.what()) << endmsg;
648 /** Remove a state file.
649 * @param snapshot_name Snapshot name.
652 Session::remove_state (string snapshot_name)
654 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
655 // refuse to remove the current snapshot or the "main" one
659 sys::path xml_path(_session_dir->root_path());
661 xml_path /= snapshot_name + statefile_suffix;
663 if (!create_backup_file (xml_path)) {
664 // don't remove it if a backup can't be made
665 // create_backup_file will log the error.
670 sys::remove (xml_path);
674 Session::save_state (string snapshot_name, bool pending)
677 sys::path xml_path(_session_dir->root_path());
679 if (_state_of_the_state & CannotSave) {
683 if (!_engine.connected ()) {
684 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
689 /* tell sources we're saving first, in case they write out to a new file
690 * which should be saved with the state rather than the old one */
691 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
692 i->second->session_saved();
694 tree.set_root (&get_state());
696 if (snapshot_name.empty()) {
697 snapshot_name = _current_snapshot_name;
702 /* proper save: use statefile_suffix (.ardour in English) */
704 xml_path /= snapshot_name + statefile_suffix;
706 /* make a backup copy of the old file */
708 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
709 // create_backup_file will log the error
715 /* pending save: use pending_suffix (.pending in English) */
716 xml_path /= snapshot_name + pending_suffix;
719 sys::path tmp_path(_session_dir->root_path());
721 tmp_path /= snapshot_name + temp_suffix;
723 // cerr << "actually writing state to " << xml_path.to_string() << endl;
725 if (!tree.write (tmp_path.to_string())) {
726 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
727 sys::remove (tmp_path);
732 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
733 error << string_compose (_("could not rename temporary session file %1 to %2"),
734 tmp_path.to_string(), xml_path.to_string()) << endmsg;
735 sys::remove (tmp_path);
742 save_history (snapshot_name);
744 bool was_dirty = dirty();
746 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
749 DirtyChanged (); /* EMIT SIGNAL */
752 StateSaved (snapshot_name); /* EMIT SIGNAL */
759 Session::restore_state (string snapshot_name)
761 if (load_state (snapshot_name) == 0) {
762 set_state (*state_tree->root());
769 Session::load_state (string snapshot_name)
776 state_was_pending = false;
778 /* check for leftover pending state from a crashed capture attempt */
780 sys::path xmlpath(_session_dir->root_path());
781 xmlpath /= snapshot_name + pending_suffix;
783 if (sys::exists (xmlpath)) {
785 /* there is pending state from a crashed capture attempt */
787 if (AskAboutPendingState()) {
788 state_was_pending = true;
792 if (!state_was_pending) {
793 xmlpath = _session_dir->root_path();
794 xmlpath /= snapshot_name + statefile_suffix;
797 if (!sys::exists (xmlpath)) {
798 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
802 state_tree = new XMLTree;
806 if (!state_tree->read (xmlpath.to_string())) {
807 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
813 XMLNode& root (*state_tree->root());
815 if (root.name() != X_("Session")) {
816 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
822 const XMLProperty* prop;
825 if ((prop = root.property ("version")) == 0) {
826 /* no version implies very old version of Ardour */
830 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
831 if (major_version < 2) {
838 sys::path backup_path(_session_dir->root_path());
840 backup_path /= snapshot_name + "-1" + statefile_suffix;
842 // only create a backup once
843 if (sys::exists (backup_path)) {
847 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
848 xmlpath.to_string(), backup_path.to_string())
853 sys::copy_file (xmlpath, backup_path);
855 catch(sys::filesystem_error& ex)
857 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
858 xmlpath.to_string(), ex.what())
868 Session::load_options (const XMLNode& node)
872 LocaleGuard lg (X_("POSIX"));
874 Config->set_variables (node, ConfigVariableBase::Session);
876 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
877 if ((prop = child->property ("val")) != 0) {
878 _end_location_is_free = (prop->value() == "yes");
886 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
888 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
889 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
891 return owner & modified_by_session_or_user;
895 Session::get_options () const
898 LocaleGuard lg (X_("POSIX"));
900 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
902 child = option_root.add_child ("end-marker-is-free");
903 child->add_property ("val", _end_location_is_free ? "yes" : "no");
915 Session::get_template()
917 /* if we don't disable rec-enable, diskstreams
918 will believe they need to store their capture
919 sources in their state node.
922 disable_record (false);
928 Session::state(bool full_state)
930 XMLNode* node = new XMLNode("Session");
933 // store libardour version, just in case
935 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
936 node->add_property("version", string(buf));
938 /* store configuration settings */
942 node->add_property ("name", _name);
943 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
944 node->add_property ("sample-rate", buf);
946 if (session_dirs.size() > 1) {
950 vector<space_and_path>::iterator i = session_dirs.begin();
951 vector<space_and_path>::iterator next;
953 ++i; /* skip the first one */
957 while (i != session_dirs.end()) {
961 if (next != session_dirs.end()) {
971 child = node->add_child ("Path");
972 child->add_content (p);
976 /* save the ID counter */
978 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
979 node->add_property ("id-counter", buf);
981 /* various options */
983 node->add_child_nocopy (get_options());
985 node->add_child_nocopy (_metadata->get_state());
987 child = node->add_child ("Sources");
990 Glib::Mutex::Lock sl (source_lock);
992 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
994 /* Don't save information about AudioFileSources that are empty */
996 boost::shared_ptr<AudioFileSource> fs;
998 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
1000 /* Don't save sources that are empty, unless they're destructive (which are OK
1001 if they are empty, because we will re-use them every time.)
1004 if (!fs->destructive()) {
1005 if (fs->length() == 0) {
1011 child->add_child_nocopy (siter->second->get_state());
1015 child = node->add_child ("Regions");
1018 Glib::Mutex::Lock rl (region_lock);
1020 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
1022 /* only store regions not attached to playlists */
1024 if (i->second->playlist() == 0) {
1025 child->add_child_nocopy (i->second->state (true));
1030 child = node->add_child ("DiskStreams");
1033 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1034 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1035 if (!(*i)->hidden()) {
1036 child->add_child_nocopy ((*i)->get_state());
1042 node->add_child_nocopy (_locations.get_state());
1044 // for a template, just create a new Locations, populate it
1045 // with the default start and end, and get the state for that.
1047 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1048 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1051 end->set_end(compute_initial_length());
1053 node->add_child_nocopy (loc.get_state());
1056 child = node->add_child ("Bundles");
1058 Glib::Mutex::Lock lm (bundle_lock);
1059 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
1060 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1062 child->add_child_nocopy (b->get_state());
1067 child = node->add_child ("Routes");
1069 boost::shared_ptr<RouteList> r = routes.reader ();
1071 RoutePublicOrderSorter cmp;
1072 RouteList public_order (*r);
1073 public_order.sort (cmp);
1075 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1076 if (!(*i)->is_hidden()) {
1078 child->add_child_nocopy ((*i)->get_state());
1080 child->add_child_nocopy ((*i)->get_template());
1087 child = node->add_child ("EditGroups");
1088 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1089 child->add_child_nocopy ((*i)->get_state());
1092 child = node->add_child ("MixGroups");
1093 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1094 child->add_child_nocopy ((*i)->get_state());
1097 child = node->add_child ("Playlists");
1098 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1099 if (!(*i)->hidden()) {
1100 if (!(*i)->empty()) {
1102 child->add_child_nocopy ((*i)->get_state());
1104 child->add_child_nocopy ((*i)->get_template());
1110 child = node->add_child ("UnusedPlaylists");
1111 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1112 if (!(*i)->hidden()) {
1113 if (!(*i)->empty()) {
1115 child->add_child_nocopy ((*i)->get_state());
1117 child->add_child_nocopy ((*i)->get_template());
1125 child = node->add_child ("Click");
1126 child->add_child_nocopy (_click_io->state (full_state));
1130 child = node->add_child ("NamedSelections");
1131 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1133 child->add_child_nocopy ((*i)->get_state());
1138 node->add_child_nocopy (_tempo_map->get_state());
1140 node->add_child_nocopy (get_control_protocol_state());
1143 node->add_child_copy (*_extra_xml);
1150 Session::get_control_protocol_state ()
1152 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1153 return cpm.get_state();
1157 Session::set_state (const XMLNode& node)
1161 const XMLProperty* prop;
1164 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1166 if (node.name() != X_("Session")){
1167 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1171 if ((prop = node.property ("name")) != 0) {
1172 _name = prop->value ();
1175 if ((prop = node.property (X_("sample-rate"))) != 0) {
1177 _nominal_frame_rate = atoi (prop->value());
1179 if (_nominal_frame_rate != _current_frame_rate) {
1180 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1186 setup_raid_path(_session_dir->root_path().to_string());
1188 if ((prop = node.property (X_("id-counter"))) != 0) {
1190 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1191 ID::init_counter (x);
1193 /* old sessions used a timebased counter, so fake
1194 the startup ID counter based on a standard
1199 ID::init_counter (now);
1203 IO::disable_ports ();
1204 IO::disable_connecting ();
1206 /* Object loading order:
1225 if (use_config_midi_ports ()) {
1228 if ((child = find_named_node (node, "extra")) != 0) {
1229 _extra_xml = new XMLNode (*child);
1232 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1233 load_options (*child);
1234 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1235 load_options (*child);
1237 error << _("Session: XML state has no options section") << endmsg;
1240 if ((child = find_named_node (node, "Metadata")) == 0) {
1241 warning << _("Session: XML state has no metadata section (2.0 session?)") << endmsg;
1242 } else if (_metadata->set_state (*child)) {
1246 if ((child = find_named_node (node, "Locations")) == 0) {
1247 error << _("Session: XML state has no locations section") << endmsg;
1249 } else if (_locations.set_state (*child)) {
1255 if ((location = _locations.auto_loop_location()) != 0) {
1256 set_auto_loop_location (location);
1259 if ((location = _locations.auto_punch_location()) != 0) {
1260 set_auto_punch_location (location);
1263 if ((location = _locations.end_location()) == 0) {
1264 _locations.add (end_location);
1266 delete end_location;
1267 end_location = location;
1270 if ((location = _locations.start_location()) == 0) {
1271 _locations.add (start_location);
1273 delete start_location;
1274 start_location = location;
1277 AudioFileSource::set_header_position_offset (start_location->start());
1279 if ((child = find_named_node (node, "Sources")) == 0) {
1280 error << _("Session: XML state has no sources section") << endmsg;
1282 } else if (load_sources (*child)) {
1286 if ((child = find_named_node (node, "Regions")) == 0) {
1287 error << _("Session: XML state has no Regions section") << endmsg;
1289 } else if (load_regions (*child)) {
1293 if ((child = find_named_node (node, "Playlists")) == 0) {
1294 error << _("Session: XML state has no playlists section") << endmsg;
1296 } else if (load_playlists (*child)) {
1300 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1302 } else if (load_unused_playlists (*child)) {
1306 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1307 if (load_named_selections (*child)) {
1312 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1313 error << _("Session: XML state has no diskstreams section") << endmsg;
1315 } else if (load_diskstreams (*child)) {
1319 if ((child = find_named_node (node, "Bundles")) == 0) {
1320 warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg;
1323 /* We can't load Bundles yet as they need to be able
1324 to convert from port names to Port objects, which can't happen until
1326 _bundle_xml_node = new XMLNode (*child);
1329 if ((child = find_named_node (node, "EditGroups")) == 0) {
1330 error << _("Session: XML state has no edit groups section") << endmsg;
1332 } else if (load_edit_groups (*child)) {
1336 if ((child = find_named_node (node, "MixGroups")) == 0) {
1337 error << _("Session: XML state has no mix groups section") << endmsg;
1339 } else if (load_mix_groups (*child)) {
1343 if ((child = find_named_node (node, "TempoMap")) == 0) {
1344 error << _("Session: XML state has no Tempo Map section") << endmsg;
1346 } else if (_tempo_map->set_state (*child)) {
1350 if ((child = find_named_node (node, "Routes")) == 0) {
1351 error << _("Session: XML state has no routes section") << endmsg;
1353 } else if (load_routes (*child)) {
1357 if ((child = find_named_node (node, "Click")) == 0) {
1358 warning << _("Session: XML state has no click section") << endmsg;
1359 } else if (_click_io) {
1360 _click_io->set_state (*child);
1363 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1364 ControlProtocolManager::instance().set_protocol_states (*child);
1367 /* here beginneth the second phase ... */
1369 StateReady (); /* EMIT SIGNAL */
1378 Session::load_routes (const XMLNode& node)
1381 XMLNodeConstIterator niter;
1382 RouteList new_routes;
1384 nlist = node.children();
1388 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1390 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1393 error << _("Session: cannot create Route from XML description.") << endmsg;
1397 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1399 new_routes.push_back (route);
1402 add_routes (new_routes, false);
1407 boost::shared_ptr<Route>
1408 Session::XMLRouteFactory (const XMLNode& node)
1410 if (node.name() != "Route") {
1411 return boost::shared_ptr<Route> ((Route*) 0);
1414 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1416 DataType type = DataType::AUDIO;
1417 const XMLProperty* prop = node.property("default-type");
1419 type = DataType(prop->value());
1421 assert(type != DataType::NIL);
1423 if (has_diskstream) {
1424 if (type == DataType::AUDIO) {
1425 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1428 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1432 boost::shared_ptr<Route> ret (new Route (*this, node));
1438 Session::load_regions (const XMLNode& node)
1441 XMLNodeConstIterator niter;
1442 boost::shared_ptr<Region> region;
1444 nlist = node.children();
1448 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1449 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1450 error << _("Session: cannot create Region from XML description.");
1451 const XMLProperty *name = (**niter).property("name");
1454 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1464 boost::shared_ptr<Region>
1465 Session::XMLRegionFactory (const XMLNode& node, bool full)
1467 const XMLProperty* type = node.property("type");
1471 if ( !type || type->value() == "audio" ) {
1473 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1475 } else if (type->value() == "midi") {
1477 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1481 } catch (failed_constructor& err) {
1482 return boost::shared_ptr<Region> ();
1485 return boost::shared_ptr<Region> ();
1488 boost::shared_ptr<AudioRegion>
1489 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1491 const XMLProperty* prop;
1492 boost::shared_ptr<Source> source;
1493 boost::shared_ptr<AudioSource> as;
1495 SourceList master_sources;
1496 uint32_t nchans = 1;
1499 if (node.name() != X_("Region")) {
1500 return boost::shared_ptr<AudioRegion>();
1503 if ((prop = node.property (X_("channels"))) != 0) {
1504 nchans = atoi (prop->value().c_str());
1507 if ((prop = node.property ("name")) == 0) {
1508 cerr << "no name for this region\n";
1512 if ((prop = node.property (X_("source-0"))) == 0) {
1513 if ((prop = node.property ("source")) == 0) {
1514 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1515 return boost::shared_ptr<AudioRegion>();
1519 PBD::ID s_id (prop->value());
1521 if ((source = source_by_id (s_id)) == 0) {
1522 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1523 return boost::shared_ptr<AudioRegion>();
1526 as = boost::dynamic_pointer_cast<AudioSource>(source);
1528 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1529 return boost::shared_ptr<AudioRegion>();
1532 sources.push_back (as);
1534 /* pickup other channels */
1536 for (uint32_t n=1; n < nchans; ++n) {
1537 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1538 if ((prop = node.property (buf)) != 0) {
1540 PBD::ID id2 (prop->value());
1542 if ((source = source_by_id (id2)) == 0) {
1543 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1544 return boost::shared_ptr<AudioRegion>();
1547 as = boost::dynamic_pointer_cast<AudioSource>(source);
1549 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1550 return boost::shared_ptr<AudioRegion>();
1552 sources.push_back (as);
1556 for (uint32_t n=1; n < nchans; ++n) {
1557 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1558 if ((prop = node.property (buf)) != 0) {
1560 PBD::ID id2 (prop->value());
1562 if ((source = source_by_id (id2)) == 0) {
1563 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1564 return boost::shared_ptr<AudioRegion>();
1567 as = boost::dynamic_pointer_cast<AudioSource>(source);
1569 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1570 return boost::shared_ptr<AudioRegion>();
1572 master_sources.push_back (as);
1577 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1579 /* a final detail: this is the one and only place that we know how long missing files are */
1581 if (region->whole_file()) {
1582 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1583 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1585 sfp->set_length (region->length());
1590 if (!master_sources.empty()) {
1591 if (master_sources.size() == nchans) {
1592 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1594 region->set_master_sources (master_sources);
1602 catch (failed_constructor& err) {
1603 return boost::shared_ptr<AudioRegion>();
1607 boost::shared_ptr<MidiRegion>
1608 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1610 const XMLProperty* prop;
1611 boost::shared_ptr<Source> source;
1612 boost::shared_ptr<MidiSource> ms;
1614 uint32_t nchans = 1;
1616 if (node.name() != X_("Region")) {
1617 return boost::shared_ptr<MidiRegion>();
1620 if ((prop = node.property (X_("channels"))) != 0) {
1621 nchans = atoi (prop->value().c_str());
1624 if ((prop = node.property ("name")) == 0) {
1625 cerr << "no name for this region\n";
1629 // Multiple midi channels? that's just crazy talk
1630 assert(nchans == 1);
1632 if ((prop = node.property (X_("source-0"))) == 0) {
1633 if ((prop = node.property ("source")) == 0) {
1634 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1635 return boost::shared_ptr<MidiRegion>();
1639 PBD::ID s_id (prop->value());
1641 if ((source = source_by_id (s_id)) == 0) {
1642 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1643 return boost::shared_ptr<MidiRegion>();
1646 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1648 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1649 return boost::shared_ptr<MidiRegion>();
1652 sources.push_back (ms);
1655 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1656 /* a final detail: this is the one and only place that we know how long missing files are */
1658 if (region->whole_file()) {
1659 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1660 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1662 sfp->set_length (region->length());
1670 catch (failed_constructor& err) {
1671 return boost::shared_ptr<MidiRegion>();
1676 Session::get_sources_as_xml ()
1679 XMLNode* node = new XMLNode (X_("Sources"));
1680 Glib::Mutex::Lock lm (source_lock);
1682 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1683 node->add_child_nocopy (i->second->get_state());
1690 Session::path_from_region_name (DataType type, string name, string identifier)
1692 char buf[PATH_MAX+1];
1694 SessionDirectory sdir(get_best_session_directory_for_new_source());
1695 sys::path source_dir = ((type == DataType::AUDIO)
1696 ? sdir.sound_path() : sdir.midi_path());
1698 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1700 for (n = 0; n < 999999; ++n) {
1701 if (identifier.length()) {
1702 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1703 identifier.c_str(), n, ext.c_str());
1705 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1709 sys::path source_path = source_dir / buf;
1711 if (!sys::exists (source_path)) {
1712 return source_path.to_string();
1716 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1725 Session::load_sources (const XMLNode& node)
1728 XMLNodeConstIterator niter;
1729 boost::shared_ptr<Source> source;
1731 nlist = node.children();
1735 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1738 if ((source = XMLSourceFactory (**niter)) == 0) {
1739 error << _("Session: cannot create Source from XML description.") << endmsg;
1743 catch (non_existent_source& err) {
1744 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1745 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1752 boost::shared_ptr<Source>
1753 Session::XMLSourceFactory (const XMLNode& node)
1755 if (node.name() != "Source") {
1756 return boost::shared_ptr<Source>();
1760 /* note: do peak building in another thread when loading session state */
1761 return SourceFactory::create (*this, node, true);
1764 catch (failed_constructor& err) {
1765 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1766 return boost::shared_ptr<Source>();
1771 Session::save_template (string template_name)
1775 if (_state_of_the_state & CannotSave) {
1779 sys::path user_template_dir(user_template_directory());
1783 sys::create_directories (user_template_dir);
1785 catch(sys::filesystem_error& ex)
1787 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1788 user_template_dir.to_string(), ex.what()) << endmsg;
1792 tree.set_root (&get_template());
1794 sys::path template_file_path(user_template_dir);
1795 template_file_path /= template_name + template_suffix;
1797 if (sys::exists (template_file_path))
1799 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1800 template_file_path.to_string()) << endmsg;
1804 if (!tree.write (template_file_path.to_string())) {
1805 error << _("mix template not saved") << endmsg;
1813 Session::rename_template (string old_name, string new_name)
1815 sys::path old_path (user_template_directory());
1816 old_path /= old_name + template_suffix;
1818 sys::path new_path(user_template_directory());
1819 new_path /= new_name + template_suffix;
1821 if (sys::exists (new_path)) {
1822 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1823 new_path.to_string()) << endmsg;
1828 sys::rename (old_path, new_path);
1836 Session::delete_template (string name)
1838 sys::path path = user_template_directory();
1839 path /= name + template_suffix;
1850 Session::refresh_disk_space ()
1853 struct statfs statfsbuf;
1854 vector<space_and_path>::iterator i;
1855 Glib::Mutex::Lock lm (space_lock);
1858 /* get freespace on every FS that is part of the session path */
1860 _total_free_4k_blocks = 0;
1862 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1863 statfs ((*i).path.c_str(), &statfsbuf);
1865 scale = statfsbuf.f_bsize/4096.0;
1867 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1868 _total_free_4k_blocks += (*i).blocks;
1874 Session::get_best_session_directory_for_new_source ()
1876 vector<space_and_path>::iterator i;
1877 string result = _session_dir->root_path().to_string();
1879 /* handle common case without system calls */
1881 if (session_dirs.size() == 1) {
1885 /* OK, here's the algorithm we're following here:
1887 We want to select which directory to use for
1888 the next file source to be created. Ideally,
1889 we'd like to use a round-robin process so as to
1890 get maximum performance benefits from splitting
1891 the files across multiple disks.
1893 However, in situations without much diskspace, an
1894 RR approach may end up filling up a filesystem
1895 with new files while others still have space.
1896 Its therefore important to pay some attention to
1897 the freespace in the filesystem holding each
1898 directory as well. However, if we did that by
1899 itself, we'd keep creating new files in the file
1900 system with the most space until it was as full
1901 as all others, thus negating any performance
1902 benefits of this RAID-1 like approach.
1904 So, we use a user-configurable space threshold. If
1905 there are at least 2 filesystems with more than this
1906 much space available, we use RR selection between them.
1907 If not, then we pick the filesystem with the most space.
1909 This gets a good balance between the two
1913 refresh_disk_space ();
1915 int free_enough = 0;
1917 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1918 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1923 if (free_enough >= 2) {
1924 /* use RR selection process, ensuring that the one
1928 i = last_rr_session_dir;
1931 if (++i == session_dirs.end()) {
1932 i = session_dirs.begin();
1935 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1936 if (create_session_directory ((*i).path)) {
1938 last_rr_session_dir = i;
1943 } while (i != last_rr_session_dir);
1947 /* pick FS with the most freespace (and that
1948 seems to actually work ...)
1951 vector<space_and_path> sorted;
1952 space_and_path_ascending_cmp cmp;
1954 sorted = session_dirs;
1955 sort (sorted.begin(), sorted.end(), cmp);
1957 for (i = sorted.begin(); i != sorted.end(); ++i) {
1958 if (create_session_directory ((*i).path)) {
1960 last_rr_session_dir = i;
1970 Session::load_playlists (const XMLNode& node)
1973 XMLNodeConstIterator niter;
1974 boost::shared_ptr<Playlist> playlist;
1976 nlist = node.children();
1980 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1982 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1983 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1991 Session::load_unused_playlists (const XMLNode& node)
1994 XMLNodeConstIterator niter;
1995 boost::shared_ptr<Playlist> playlist;
1997 nlist = node.children();
2001 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2003 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2004 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2008 // now manually untrack it
2010 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
2016 boost::shared_ptr<Playlist>
2017 Session::XMLPlaylistFactory (const XMLNode& node)
2020 return PlaylistFactory::create (*this, node);
2023 catch (failed_constructor& err) {
2024 return boost::shared_ptr<Playlist>();
2029 Session::load_named_selections (const XMLNode& node)
2032 XMLNodeConstIterator niter;
2035 nlist = node.children();
2039 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2041 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2042 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2050 Session::XMLNamedSelectionFactory (const XMLNode& node)
2053 return new NamedSelection (*this, node);
2056 catch (failed_constructor& err) {
2062 Session::automation_dir () const
2064 return Glib::build_filename (_path, "automation");
2068 Session::analysis_dir () const
2070 return Glib::build_filename (_path, "analysis");
2074 Session::load_bundles (XMLNode const & node)
2076 XMLNodeList nlist = node.children();
2077 XMLNodeConstIterator niter;
2081 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2082 if ((*niter)->name() == "InputBundle") {
2083 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2084 } else if ((*niter)->name() == "OutputBundle") {
2085 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2087 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2096 Session::load_edit_groups (const XMLNode& node)
2098 return load_route_groups (node, true);
2102 Session::load_mix_groups (const XMLNode& node)
2104 return load_route_groups (node, false);
2108 Session::load_route_groups (const XMLNode& node, bool edit)
2110 XMLNodeList nlist = node.children();
2111 XMLNodeConstIterator niter;
2116 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2117 if ((*niter)->name() == "RouteGroup") {
2119 rg = add_edit_group ("");
2120 rg->set_state (**niter);
2122 rg = add_mix_group ("");
2123 rg->set_state (**niter);
2132 Session::auto_save()
2134 save_state (_current_snapshot_name);
2138 state_file_filter (const string &str, void *arg)
2140 return (str.length() > strlen(statefile_suffix) &&
2141 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2145 bool operator()(const string* a, const string* b) {
2151 remove_end(string* state)
2153 string statename(*state);
2155 string::size_type start,end;
2156 if ((start = statename.find_last_of ('/')) != string::npos) {
2157 statename = statename.substr (start+1);
2160 if ((end = statename.rfind(".ardour")) == string::npos) {
2161 end = statename.length();
2164 return new string(statename.substr (0, end));
2168 Session::possible_states (string path)
2170 PathScanner scanner;
2171 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2173 transform(states->begin(), states->end(), states->begin(), remove_end);
2176 sort (states->begin(), states->end(), cmp);
2182 Session::possible_states () const
2184 return possible_states(_path);
2188 Session::add_edit_group (string name)
2190 RouteGroup* rg = new RouteGroup (*this, name);
2191 edit_groups.push_back (rg);
2192 edit_group_added (rg); /* EMIT SIGNAL */
2198 Session::add_mix_group (string name)
2200 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2201 mix_groups.push_back (rg);
2202 mix_group_added (rg); /* EMIT SIGNAL */
2208 Session::remove_edit_group (RouteGroup& rg)
2210 list<RouteGroup*>::iterator i;
2212 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2213 (*i)->apply (&Route::drop_edit_group, this);
2214 edit_groups.erase (i);
2215 edit_group_removed (); /* EMIT SIGNAL */
2222 Session::remove_mix_group (RouteGroup& rg)
2224 list<RouteGroup*>::iterator i;
2226 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2227 (*i)->apply (&Route::drop_mix_group, this);
2228 mix_groups.erase (i);
2229 mix_group_removed (); /* EMIT SIGNAL */
2236 Session::mix_group_by_name (string name)
2238 list<RouteGroup *>::iterator i;
2240 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2241 if ((*i)->name() == name) {
2249 Session::edit_group_by_name (string name)
2251 list<RouteGroup *>::iterator i;
2253 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2254 if ((*i)->name() == name) {
2262 Session::begin_reversible_command (const string& name)
2264 current_trans = new UndoTransaction;
2265 current_trans->set_name (name);
2269 Session::commit_reversible_command (Command *cmd)
2274 current_trans->add_command (cmd);
2277 if (current_trans->empty()) {
2281 gettimeofday (&now, 0);
2282 current_trans->set_timestamp (now);
2284 _history.add (current_trans);
2287 Session::GlobalRouteBooleanState
2288 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2290 GlobalRouteBooleanState s;
2291 boost::shared_ptr<RouteList> r = routes.reader ();
2293 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2294 if (!(*i)->is_hidden()) {
2295 RouteBooleanState v;
2298 Route* r = (*i).get();
2299 v.second = (r->*method)();
2308 Session::GlobalRouteMeterState
2309 Session::get_global_route_metering ()
2311 GlobalRouteMeterState s;
2312 boost::shared_ptr<RouteList> r = routes.reader ();
2314 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2315 if (!(*i)->is_hidden()) {
2319 v.second = (*i)->meter_point();
2329 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2331 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2333 boost::shared_ptr<Route> r = (i->first.lock());
2336 r->set_meter_point (i->second, arg);
2342 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2344 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2346 boost::shared_ptr<Route> r = (i->first.lock());
2349 Route* rp = r.get();
2350 (rp->*method) (i->second, arg);
2356 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2358 set_global_route_boolean (s, &Route::set_mute, src);
2362 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2364 set_global_route_boolean (s, &Route::set_solo, src);
2368 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2370 set_global_route_boolean (s, &Route::set_record_enable, src);
2375 Session::global_mute_memento (void* src)
2377 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2381 Session::global_metering_memento (void* src)
2383 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2387 Session::global_solo_memento (void* src)
2389 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2393 Session::global_record_enable_memento (void* src)
2395 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2400 accept_all_non_peak_files (const string& path, void *arg)
2402 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2406 accept_all_state_files (const string& path, void *arg)
2408 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2412 Session::find_all_sources (string path, set<string>& result)
2417 if (!tree.read (path)) {
2421 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2426 XMLNodeConstIterator niter;
2428 nlist = node->children();
2432 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2436 if ((prop = (*niter)->property (X_("name"))) == 0) {
2440 if (prop->value()[0] == '/') {
2441 /* external file, ignore */
2445 sys::path source_path = _session_dir->sound_path ();
2447 source_path /= prop->value ();
2449 result.insert (source_path.to_string ());
2456 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2458 PathScanner scanner;
2459 vector<string*>* state_files;
2461 string this_snapshot_path;
2467 if (ripped[ripped.length()-1] == '/') {
2468 ripped = ripped.substr (0, ripped.length() - 1);
2471 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2473 if (state_files == 0) {
2478 this_snapshot_path = _path;
2479 this_snapshot_path += _current_snapshot_name;
2480 this_snapshot_path += statefile_suffix;
2482 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2484 if (exclude_this_snapshot && **i == this_snapshot_path) {
2488 if (find_all_sources (**i, result) < 0) {
2496 struct RegionCounter {
2497 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2498 AudioSourceList::iterator iter;
2499 boost::shared_ptr<Region> region;
2502 RegionCounter() : count (0) {}
2506 Session::cleanup_sources (Session::cleanup_report& rep)
2508 // FIXME: needs adaptation to midi
2510 vector<boost::shared_ptr<Source> > dead_sources;
2511 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2512 PathScanner scanner;
2514 vector<space_and_path>::iterator i;
2515 vector<space_and_path>::iterator nexti;
2516 vector<string*>* soundfiles;
2517 vector<string> unused;
2518 set<string> all_sources;
2523 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2526 /* step 1: consider deleting all unused playlists */
2528 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2531 status = AskAboutPlaylistDeletion (*x);
2540 playlists_tbd.push_back (*x);
2544 /* leave it alone */
2549 /* now delete any that were marked for deletion */
2551 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2552 (*x)->drop_references ();
2555 playlists_tbd.clear ();
2557 /* step 2: find all un-used sources */
2562 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2564 SourceMap::iterator tmp;
2569 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2573 if (!i->second->used() && i->second->length() > 0) {
2574 dead_sources.push_back (i->second);
2575 i->second->GoingAway();
2581 /* build a list of all the possible sound directories for the session */
2583 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2588 SessionDirectory sdir ((*i).path);
2589 sound_path += sdir.sound_path().to_string();
2591 if (nexti != session_dirs.end()) {
2598 /* now do the same thing for the files that ended up in the sounds dir(s)
2599 but are not referenced as sources in any snapshot.
2602 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2604 if (soundfiles == 0) {
2608 /* find all sources, but don't use this snapshot because the
2609 state file on disk still references sources we may have already
2613 find_all_sources_across_snapshots (all_sources, true);
2615 /* add our current source list
2618 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2619 boost::shared_ptr<AudioFileSource> fs;
2621 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2622 all_sources.insert (fs->path());
2626 char tmppath1[PATH_MAX+1];
2627 char tmppath2[PATH_MAX+1];
2629 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2634 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2636 realpath(spath.c_str(), tmppath1);
2637 realpath((*i).c_str(), tmppath2);
2639 if (strcmp(tmppath1, tmppath2) == 0) {
2646 unused.push_back (spath);
2650 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2652 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2653 struct stat statbuf;
2655 rep.paths.push_back (*x);
2656 if (stat ((*x).c_str(), &statbuf) == 0) {
2657 rep.space += statbuf.st_size;
2662 /* don't move the file across filesystems, just
2663 stick it in the `dead_sound_dir_name' directory
2664 on whichever filesystem it was already on.
2667 if ((*x).find ("/sounds/") != string::npos) {
2669 /* old school, go up 1 level */
2671 newpath = Glib::path_get_dirname (*x); // "sounds"
2672 newpath = Glib::path_get_dirname (newpath); // "session-name"
2676 /* new school, go up 4 levels */
2678 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2679 newpath = Glib::path_get_dirname (newpath); // "session-name"
2680 newpath = Glib::path_get_dirname (newpath); // "interchange"
2681 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2685 newpath += dead_sound_dir_name;
2687 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2688 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2693 newpath += Glib::path_get_basename ((*x));
2695 if (access (newpath.c_str(), F_OK) == 0) {
2697 /* the new path already exists, try versioning */
2699 char buf[PATH_MAX+1];
2703 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2706 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2707 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2711 if (version == 999) {
2712 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2716 newpath = newpath_v;
2721 /* it doesn't exist, or we can't read it or something */
2725 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2726 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2727 (*x), newpath, strerror (errno))
2732 /* see if there an easy to find peakfile for this file, and remove it.
2735 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2736 peakpath += peakfile_suffix;
2738 if (access (peakpath.c_str(), W_OK) == 0) {
2739 if (::unlink (peakpath.c_str()) != 0) {
2740 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2741 peakpath, _path, strerror (errno))
2743 /* try to back out */
2744 rename (newpath.c_str(), _path.c_str());
2752 /* dump the history list */
2756 /* save state so we don't end up a session file
2757 referring to non-existent sources.
2763 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2769 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2771 // FIXME: needs adaptation for MIDI
2773 vector<space_and_path>::iterator i;
2774 string dead_sound_dir;
2775 struct dirent* dentry;
2776 struct stat statbuf;
2782 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2784 dead_sound_dir = (*i).path;
2785 dead_sound_dir += dead_sound_dir_name;
2787 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2791 while ((dentry = readdir (dead)) != 0) {
2793 /* avoid '.' and '..' */
2795 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2796 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2802 fullpath = dead_sound_dir;
2804 fullpath += dentry->d_name;
2806 if (stat (fullpath.c_str(), &statbuf)) {
2810 if (!S_ISREG (statbuf.st_mode)) {
2814 if (unlink (fullpath.c_str())) {
2815 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2816 fullpath, strerror (errno))
2820 rep.paths.push_back (dentry->d_name);
2821 rep.space += statbuf.st_size;
2832 Session::set_dirty ()
2834 bool was_dirty = dirty();
2836 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2840 DirtyChanged(); /* EMIT SIGNAL */
2846 Session::set_clean ()
2848 bool was_dirty = dirty();
2850 _state_of_the_state = Clean;
2854 DirtyChanged(); /* EMIT SIGNAL */
2859 Session::set_deletion_in_progress ()
2861 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2866 Session::add_controllable (boost::shared_ptr<Controllable> c)
2868 /* this adds a controllable to the list managed by the Session.
2869 this is a subset of those managed by the Controllable class
2870 itself, and represents the only ones whose state will be saved
2871 as part of the session.
2874 Glib::Mutex::Lock lm (controllables_lock);
2875 controllables.insert (c);
2878 struct null_deleter { void operator()(void const *) const {} };
2881 Session::remove_controllable (Controllable* c)
2883 if (_state_of_the_state | Deletion) {
2887 Glib::Mutex::Lock lm (controllables_lock);
2889 Controllables::iterator x = controllables.find(
2890 boost::shared_ptr<Controllable>(c, null_deleter()));
2892 if (x != controllables.end()) {
2893 controllables.erase (x);
2897 boost::shared_ptr<Controllable>
2898 Session::controllable_by_id (const PBD::ID& id)
2900 Glib::Mutex::Lock lm (controllables_lock);
2902 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2903 if ((*i)->id() == id) {
2908 return boost::shared_ptr<Controllable>();
2912 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2914 Stateful::add_instant_xml (node, _path);
2915 if (write_to_config) {
2916 Config->add_instant_xml (node);
2921 Session::instant_xml (const string& node_name)
2923 return Stateful::instant_xml (node_name, _path);
2927 Session::save_history (string snapshot_name)
2931 if (snapshot_name.empty()) {
2932 snapshot_name = _current_snapshot_name;
2935 const string history_filename = snapshot_name + history_suffix;
2936 const string backup_filename = history_filename + backup_suffix;
2937 const sys::path xml_path = _session_dir->root_path() / history_filename;
2938 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2940 if (sys::exists (xml_path)) {
2943 sys::rename (xml_path, backup_path);
2945 catch (const sys::filesystem_error& err)
2947 error << _("could not backup old history file, current history not saved") << endmsg;
2953 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2957 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2959 if (!tree.write (xml_path.to_string()))
2961 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2965 sys::remove (xml_path);
2966 sys::rename (backup_path, xml_path);
2968 catch (const sys::filesystem_error& err)
2970 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2971 backup_path.to_string(), err.what()) << endmsg;
2981 Session::restore_history (string snapshot_name)
2985 if (snapshot_name.empty()) {
2986 snapshot_name = _current_snapshot_name;
2989 const string xml_filename = snapshot_name + history_suffix;
2990 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2992 cerr << "Loading history from " << xml_path.to_string() << endmsg;
2994 if (!sys::exists (xml_path)) {
2995 info << string_compose (_("%1: no history file \"%2\" for this session."),
2996 _name, xml_path.to_string()) << endmsg;
3000 if (!tree.read (xml_path.to_string())) {
3001 error << string_compose (_("Could not understand session history file \"%1\""),
3002 xml_path.to_string()) << endmsg;
3009 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3012 UndoTransaction* ut = new UndoTransaction ();
3015 ut->set_name(t->property("name")->value());
3016 stringstream ss(t->property("tv_sec")->value());
3018 ss.str(t->property("tv_usec")->value());
3020 ut->set_timestamp(tv);
3022 for (XMLNodeConstIterator child_it = t->children().begin();
3023 child_it != t->children().end();
3026 XMLNode *n = *child_it;
3029 if (n->name() == "MementoCommand" ||
3030 n->name() == "MementoUndoCommand" ||
3031 n->name() == "MementoRedoCommand") {
3033 if ((c = memento_command_factory(n))) {
3037 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3039 if ((c = global_state_command_factory (*n))) {
3040 ut->add_command (c);
3043 } else if (n->name() == "DeltaCommand") {
3044 PBD::ID id(n->property("midi_source")->value());
3045 boost::shared_ptr<MidiSource> midi_source =
3046 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3048 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
3050 error << "FIXME: Failed to downcast MidiSource for DeltaCommand" << endmsg;
3053 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3064 Session::config_changed (const char* parameter_name)
3066 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3068 if (PARAM_IS ("seamless-loop")) {
3070 } else if (PARAM_IS ("rf-speed")) {
3072 } else if (PARAM_IS ("auto-loop")) {
3074 } else if (PARAM_IS ("auto-input")) {
3076 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3077 /* auto-input only makes a difference if we're rolling */
3079 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3081 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3082 if ((*i)->record_enabled ()) {
3083 (*i)->monitor_input (!Config->get_auto_input());
3088 } else if (PARAM_IS ("punch-in")) {
3092 if ((location = _locations.auto_punch_location()) != 0) {
3094 if (Config->get_punch_in ()) {
3095 replace_event (Event::PunchIn, location->start());
3097 remove_event (location->start(), Event::PunchIn);
3101 } else if (PARAM_IS ("punch-out")) {
3105 if ((location = _locations.auto_punch_location()) != 0) {
3107 if (Config->get_punch_out()) {
3108 replace_event (Event::PunchOut, location->end());
3110 clear_events (Event::PunchOut);
3114 } else if (PARAM_IS ("edit-mode")) {
3116 Glib::Mutex::Lock lm (playlist_lock);
3118 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3119 (*i)->set_edit_mode (Config->get_edit_mode ());
3122 } else if (PARAM_IS ("use-video-sync")) {
3124 waiting_for_sync_offset = Config->get_use_video_sync();
3126 } else if (PARAM_IS ("mmc-control")) {
3128 //poke_midi_thread ();
3130 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
3133 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3136 } else if (PARAM_IS ("mmc-send-id")) {
3139 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3142 } else if (PARAM_IS ("midi-control")) {
3144 //poke_midi_thread ();
3146 } else if (PARAM_IS ("raid-path")) {
3148 setup_raid_path (Config->get_raid_path());
3150 } else if (PARAM_IS ("smpte-format")) {
3154 } else if (PARAM_IS ("video-pullup")) {
3158 } else if (PARAM_IS ("seamless-loop")) {
3160 if (play_loop && transport_rolling()) {
3161 // to reset diskstreams etc
3162 request_play_loop (true);
3165 } else if (PARAM_IS ("rf-speed")) {
3167 cumulative_rf_motion = 0;
3170 } else if (PARAM_IS ("click-sound")) {
3172 setup_click_sounds (1);
3174 } else if (PARAM_IS ("click-emphasis-sound")) {
3176 setup_click_sounds (-1);
3178 } else if (PARAM_IS ("clicking")) {
3180 if (Config->get_clicking()) {
3181 if (_click_io && click_data) { // don't require emphasis data
3188 } else if (PARAM_IS ("send-mtc")) {
3190 /* only set the internal flag if we have
3194 if (_mtc_port != 0) {
3195 session_send_mtc = Config->get_send_mtc();
3196 if (session_send_mtc) {
3197 /* mark us ready to send */
3198 next_quarter_frame_to_send = 0;
3201 session_send_mtc = false;
3204 } else if (PARAM_IS ("send-mmc")) {
3206 /* only set the internal flag if we have
3210 if (_mmc_port != 0) {
3211 session_send_mmc = Config->get_send_mmc();
3214 session_send_mmc = false;
3217 } else if (PARAM_IS ("midi-feedback")) {
3219 /* only set the internal flag if we have
3223 if (_mtc_port != 0) {
3224 session_midi_feedback = Config->get_midi_feedback();
3227 } else if (PARAM_IS ("jack-time-master")) {
3229 engine().reset_timebase ();
3231 } else if (PARAM_IS ("native-file-header-format")) {
3233 if (!first_file_header_format_reset) {
3234 reset_native_file_format ();
3237 first_file_header_format_reset = false;
3239 } else if (PARAM_IS ("native-file-data-format")) {
3241 if (!first_file_data_format_reset) {
3242 reset_native_file_format ();
3245 first_file_data_format_reset = false;
3247 } else if (PARAM_IS ("slave-source")) {
3248 set_slave_source (Config->get_slave_source());
3249 } else if (PARAM_IS ("remote-model")) {
3250 set_remote_control_ids ();
3251 } else if (PARAM_IS ("denormal-model")) {
3253 } else if (PARAM_IS ("history-depth")) {
3254 set_history_depth (Config->get_history_depth());
3255 } else if (PARAM_IS ("sync-all-route-ordering")) {
3266 Session::set_history_depth (uint32_t d)
3268 _history.set_depth (d);