2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #define __STDC_FORMAT_MACROS 1
28 #include <sigc++/bind.h>
30 #include <cstdio> /* snprintf(3) ... grrr */
45 #include <sys/param.h>
46 #include <sys/mount.h>
50 #include <glibmm/thread.h>
52 #include "midi++/mmc.h"
53 #include "midi++/port.h"
55 #include "pbd/error.h"
56 #include "pbd/pathscanner.h"
57 #include "pbd/pthread_utils.h"
58 #include "pbd/search_path.h"
59 #include "pbd/stacktrace.h"
61 #include "ardour/audioengine.h"
62 #include "ardour/configuration.h"
63 #include "ardour/session.h"
64 #include "ardour/session_directory.h"
65 #include "ardour/session_utils.h"
66 #include "ardour/session_state_utils.h"
67 #include "ardour/session_metadata.h"
68 #include "ardour/buffer.h"
69 #include "ardour/audio_diskstream.h"
70 #include "ardour/midi_diskstream.h"
71 #include "ardour/utils.h"
72 #include "ardour/audioplaylist.h"
73 #include "ardour/midi_playlist.h"
74 #include "ardour/smf_source.h"
75 #include "ardour/audiofilesource.h"
76 #include "ardour/silentfilesource.h"
77 #include "ardour/sndfilesource.h"
78 #include "ardour/midi_source.h"
79 #include "ardour/sndfile_helpers.h"
80 #include "ardour/auditioner.h"
81 #include "ardour/io_processor.h"
82 #include "ardour/send.h"
83 #include "ardour/processor.h"
84 #include "ardour/user_bundle.h"
85 #include "ardour/slave.h"
86 #include "ardour/tempo.h"
87 #include "ardour/audio_track.h"
88 #include "ardour/midi_track.h"
89 #include "ardour/midi_patch_manager.h"
90 #include "ardour/cycle_timer.h"
91 #include "ardour/utils.h"
92 #include "ardour/named_selection.h"
93 #include "ardour/version.h"
94 #include "ardour/location.h"
95 #include "ardour/audioregion.h"
96 #include "ardour/midi_region.h"
97 #include "ardour/crossfade.h"
98 #include "ardour/control_protocol_manager.h"
99 #include "ardour/region_factory.h"
100 #include "ardour/source_factory.h"
101 #include "ardour/playlist_factory.h"
102 #include "ardour/filename_extensions.h"
103 #include "ardour/directory_names.h"
104 #include "ardour/template_utils.h"
105 #include "ardour/ticker.h"
106 #include "ardour/route_group.h"
108 #include "control_protocol/control_protocol.h"
114 using namespace ARDOUR;
118 Session::first_stage_init (string fullpath, string snapshot_name)
120 if (fullpath.length() == 0) {
122 throw failed_constructor();
125 char buf[PATH_MAX+1];
126 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
127 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
129 throw failed_constructor();
134 if (_path[_path.length()-1] != '/') {
138 /* these two are just provisional settings. set_state()
139 will likely override them.
142 _name = _current_snapshot_name = snapshot_name;
144 set_history_depth (Config->get_history_depth());
146 _current_frame_rate = _engine.frame_rate ();
147 _nominal_frame_rate = _current_frame_rate;
148 _base_frame_rate = _current_frame_rate;
150 _tempo_map = new TempoMap (_current_frame_rate);
151 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
155 g_atomic_int_set (&processing_prohibited, 0);
157 _transport_speed = 0;
158 _last_transport_speed = 0;
159 phi = (uint64_t) (0x1000000);
161 auto_play_legal = false;
162 transport_sub_state = 0;
163 _transport_frame = 0;
164 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
165 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
166 _end_location_is_free = true;
167 g_atomic_int_set (&_record_status, Disabled);
168 loop_changing = false;
171 _last_roll_location = 0;
172 _last_record_location = 0;
173 pending_locate_frame = 0;
174 pending_locate_roll = false;
175 pending_locate_flush = false;
176 audio_dstream_buffer_size = 0;
177 midi_dstream_buffer_size = 0;
178 state_was_pending = false;
180 outbound_mtc_smpte_frame = 0;
181 next_quarter_frame_to_send = -1;
182 current_block_size = 0;
183 solo_update_disabled = false;
184 currently_soloing = false;
185 _have_captured = false;
186 _worst_output_latency = 0;
187 _worst_input_latency = 0;
188 _worst_track_latency = 0;
189 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
192 session_send_mmc = false;
193 session_send_mtc = false;
194 post_transport_work = PostTransportWork (0);
195 g_atomic_int_set (&butler_should_do_transport_work, 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);
202 _exporting_realtime = false;
203 _gain_automation_buffer = 0;
204 _pan_automation_buffer = 0;
206 pending_abort = false;
207 destructive_index = 0;
209 first_file_data_format_reset = true;
210 first_file_header_format_reset = true;
211 butler_thread = (pthread_t) 0;
212 //midi_thread = (pthread_t) 0;
214 AudioDiskstream::allocate_working_buffers();
216 /* default short fade = 15ms */
218 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
219 SndFileSource::setup_standard_crossfades (frame_rate());
221 last_mmc_step.tv_sec = 0;
222 last_mmc_step.tv_usec = 0;
225 /* click sounds are unset by default, which causes us to internal
226 waveforms for clicks.
230 click_emphasis_length = 0;
233 process_function = &Session::process_with_events;
235 if (Config->get_use_video_sync()) {
236 waiting_for_sync_offset = true;
238 waiting_for_sync_offset = false;
243 _smpte_offset_negative = true;
244 last_smpte_valid = false;
248 last_rr_session_dir = session_dirs.begin();
249 refresh_disk_space ();
251 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
255 average_slave_delta = 1800; // !!! why 1800 ????
256 have_first_delta_accumulator = false;
257 delta_accumulator_cnt = 0;
258 slave_state = Stopped;
260 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
262 /* These are all static "per-class" signals */
264 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
265 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
266 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
267 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
268 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
269 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
271 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
273 IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
275 /* stop IO objects from doing stuff until we're ready for them */
277 IO::disable_panners ();
278 IO::disable_ports ();
279 IO::disable_connecting ();
283 Session::second_stage_init (bool new_session)
285 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
288 if (load_state (_current_snapshot_name)) {
291 remove_empty_sounds ();
294 if (start_butler_thread()) {
298 if (start_midi_thread ()) {
302 // set_state() will call setup_raid_path(), but if it's a new session we need
303 // to call setup_raid_path() here.
306 if (set_state (*state_tree->root())) {
310 setup_raid_path(_path);
313 /* we can't save till after ::when_engine_running() is called,
314 because otherwise we save state with no connections made.
315 therefore, we reset _state_of_the_state because ::set_state()
316 will have cleared it.
318 we also have to include Loading so that any events that get
319 generated between here and the end of ::when_engine_running()
320 will be processed directly rather than queued.
323 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
326 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
327 _locations.added.connect (mem_fun (this, &Session::locations_added));
328 setup_click_sounds (0);
329 setup_midi_control ();
331 /* Pay attention ... */
333 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
334 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
337 when_engine_running();
340 /* handle this one in a different way than all others, so that its clear what happened */
342 catch (AudioEngine::PortRegistrationFailure& err) {
343 error << _("Unable to create all required ports")
352 BootMessage (_("Reset Remote Controls"));
354 send_full_time_code (0);
355 _engine.transport_locate (0);
356 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
357 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
359 MidiClockTicker::instance().set_session(*this);
360 MIDI::Name::MidiPatchManager::instance().set_session(*this);
362 /* initial program change will be delivered later; see ::config_changed() */
364 BootMessage (_("Reset Control Protocols"));
366 ControlProtocolManager::instance().set_session (*this);
369 _end_location_is_free = true;
371 _end_location_is_free = false;
374 _state_of_the_state = Clean;
376 DirtyChanged (); /* EMIT SIGNAL */
378 if (state_was_pending) {
379 save_state (_current_snapshot_name);
380 remove_pending_capture_state ();
381 state_was_pending = false;
384 BootMessage (_("Session loading complete"));
390 Session::raid_path () const
392 SearchPath raid_search_path;
394 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
395 raid_search_path += sys::path((*i).path);
398 return raid_search_path.to_string ();
402 Session::setup_raid_path (string path)
411 session_dirs.clear ();
413 SearchPath search_path(path);
414 SearchPath sound_search_path;
415 SearchPath midi_search_path;
417 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
418 sp.path = (*i).to_string ();
419 sp.blocks = 0; // not needed
420 session_dirs.push_back (sp);
422 SessionDirectory sdir(sp.path);
424 sound_search_path += sdir.sound_path ();
425 midi_search_path += sdir.midi_path ();
428 // set the search path for each data type
429 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
430 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
432 // reset the round-robin soundfile path thingie
433 last_rr_session_dir = session_dirs.begin();
437 Session::ensure_subdirs ()
441 dir = session_directory().peak_path().to_string();
443 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
444 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
448 dir = session_directory().sound_path().to_string();
450 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
451 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
455 dir = session_directory().midi_path().to_string();
457 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
458 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
462 dir = session_directory().dead_sound_path().to_string();
464 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
465 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
469 dir = session_directory().export_path().to_string();
471 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
472 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
476 dir = analysis_dir ();
478 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
479 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
487 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
490 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
491 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
495 if (ensure_subdirs ()) {
499 /* check new_session so we don't overwrite an existing one */
501 if (!mix_template.empty()) {
502 std::string in_path = mix_template;
504 ifstream in(in_path.c_str());
507 string out_path = _path;
509 out_path += statefile_suffix;
511 ofstream out(out_path.c_str());
516 // okay, session is set up. Treat like normal saved
517 // session from now on.
523 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
529 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
536 /* Instantiate metadata */
538 _metadata = new SessionMetadata ();
540 /* set initial start + end point */
542 start_location->set_end (0);
543 _locations.add (start_location);
545 end_location->set_end (initial_length);
546 _locations.add (end_location);
548 _state_of_the_state = Clean;
557 Session::load_diskstreams (const XMLNode& node)
560 XMLNodeConstIterator citer;
562 clist = node.children();
564 for (citer = clist.begin(); citer != clist.end(); ++citer) {
567 /* diskstreams added automatically by DiskstreamCreated handler */
568 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
569 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
570 add_diskstream (dstream);
571 } else if ((*citer)->name() == "MidiDiskstream") {
572 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
573 add_diskstream (dstream);
575 error << _("Session: unknown diskstream type in XML") << endmsg;
579 catch (failed_constructor& err) {
580 error << _("Session: could not load diskstream via XML state") << endmsg;
589 Session::maybe_write_autosave()
591 if (dirty() && record_status() != Recording) {
592 save_state("", true);
597 Session::remove_pending_capture_state ()
599 sys::path pending_state_file_path(_session_dir->root_path());
601 pending_state_file_path /= _current_snapshot_name + pending_suffix;
605 sys::remove (pending_state_file_path);
607 catch(sys::filesystem_error& ex)
609 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
610 pending_state_file_path.to_string(), ex.what()) << endmsg;
614 /** Rename a state file.
615 * @param snapshot_name Snapshot name.
618 Session::rename_state (string old_name, string new_name)
620 if (old_name == _current_snapshot_name || old_name == _name) {
621 /* refuse to rename the current snapshot or the "main" one */
625 const string old_xml_filename = old_name + statefile_suffix;
626 const string new_xml_filename = new_name + statefile_suffix;
628 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
629 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
633 sys::rename (old_xml_path, new_xml_path);
635 catch (const sys::filesystem_error& err)
637 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
638 old_name, new_name, err.what()) << endmsg;
642 /** Remove a state file.
643 * @param snapshot_name Snapshot name.
646 Session::remove_state (string snapshot_name)
648 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
649 // refuse to remove the current snapshot or the "main" one
653 sys::path xml_path(_session_dir->root_path());
655 xml_path /= snapshot_name + statefile_suffix;
657 if (!create_backup_file (xml_path)) {
658 // don't remove it if a backup can't be made
659 // create_backup_file will log the error.
664 sys::remove (xml_path);
668 Session::save_state (string snapshot_name, bool pending)
671 sys::path xml_path(_session_dir->root_path());
673 if (_state_of_the_state & CannotSave) {
677 if (!_engine.connected ()) {
678 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
683 /* tell sources we're saving first, in case they write out to a new file
684 * which should be saved with the state rather than the old one */
685 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
686 i->second->session_saved();
688 tree.set_root (&get_state());
690 if (snapshot_name.empty()) {
691 snapshot_name = _current_snapshot_name;
696 /* proper save: use statefile_suffix (.ardour in English) */
698 xml_path /= snapshot_name + statefile_suffix;
700 /* make a backup copy of the old file */
702 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
703 // create_backup_file will log the error
709 /* pending save: use pending_suffix (.pending in English) */
710 xml_path /= snapshot_name + pending_suffix;
713 sys::path tmp_path(_session_dir->root_path());
715 tmp_path /= snapshot_name + temp_suffix;
717 // cerr << "actually writing state to " << xml_path.to_string() << endl;
719 if (!tree.write (tmp_path.to_string())) {
720 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
721 sys::remove (tmp_path);
726 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
727 error << string_compose (_("could not rename temporary session file %1 to %2"),
728 tmp_path.to_string(), xml_path.to_string()) << endmsg;
729 sys::remove (tmp_path);
736 save_history (snapshot_name);
738 bool was_dirty = dirty();
740 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
743 DirtyChanged (); /* EMIT SIGNAL */
746 StateSaved (snapshot_name); /* EMIT SIGNAL */
753 Session::restore_state (string snapshot_name)
755 if (load_state (snapshot_name) == 0) {
756 set_state (*state_tree->root());
763 Session::load_state (string snapshot_name)
768 state_was_pending = false;
770 /* check for leftover pending state from a crashed capture attempt */
772 sys::path xmlpath(_session_dir->root_path());
773 xmlpath /= snapshot_name + pending_suffix;
775 if (sys::exists (xmlpath)) {
777 /* there is pending state from a crashed capture attempt */
779 if (AskAboutPendingState()) {
780 state_was_pending = true;
784 if (!state_was_pending) {
785 xmlpath = _session_dir->root_path();
786 xmlpath /= snapshot_name + statefile_suffix;
789 if (!sys::exists (xmlpath)) {
790 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
794 state_tree = new XMLTree;
798 if (!state_tree->read (xmlpath.to_string())) {
799 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
805 XMLNode& root (*state_tree->root());
807 if (root.name() != X_("Session")) {
808 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
814 const XMLProperty* prop;
815 bool is_old = false; // session is _very_ old (pre-2.0)
817 if ((prop = root.property ("version")) == 0) {
818 /* no version implies very old version of Ardour */
822 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
823 if (major_version < 2) {
830 sys::path backup_path(_session_dir->root_path());
832 backup_path /= snapshot_name + "-1" + statefile_suffix;
834 // only create a backup once
835 if (sys::exists (backup_path)) {
839 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
840 xmlpath.to_string(), backup_path.to_string())
845 sys::copy_file (xmlpath, backup_path);
847 catch(sys::filesystem_error& ex)
849 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
850 xmlpath.to_string(), ex.what())
860 Session::load_options (const XMLNode& node)
864 LocaleGuard lg (X_("POSIX"));
866 Config->set_variables (node, ConfigVariableBase::Session);
868 /* now reset MIDI ports because the session can have its own
874 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
875 if ((prop = child->property ("val")) != 0) {
876 _end_location_is_free = (prop->value() == "yes");
884 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
886 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
887 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
889 return owner & modified_by_session_or_user;
893 Session::get_options () const
896 LocaleGuard lg (X_("POSIX"));
898 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
900 child = option_root.add_child ("end-marker-is-free");
901 child->add_property ("val", _end_location_is_free ? "yes" : "no");
913 Session::get_template()
915 /* if we don't disable rec-enable, diskstreams
916 will believe they need to store their capture
917 sources in their state node.
920 disable_record (false);
926 Session::state(bool full_state)
928 XMLNode* node = new XMLNode("Session");
931 // store libardour version, just in case
933 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
934 node->add_property("version", string(buf));
936 /* store configuration settings */
940 node->add_property ("name", _name);
941 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
942 node->add_property ("sample-rate", buf);
944 if (session_dirs.size() > 1) {
948 vector<space_and_path>::iterator i = session_dirs.begin();
949 vector<space_and_path>::iterator next;
951 ++i; /* skip the first one */
955 while (i != session_dirs.end()) {
959 if (next != session_dirs.end()) {
969 child = node->add_child ("Path");
970 child->add_content (p);
974 /* save the ID counter */
976 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
977 node->add_property ("id-counter", buf);
979 /* various options */
981 node->add_child_nocopy (get_options());
983 node->add_child_nocopy (_metadata->get_state());
985 child = node->add_child ("Sources");
988 Glib::Mutex::Lock sl (source_lock);
990 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
992 /* Don't save information about non-destructive file sources that are empty */
993 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
995 boost::shared_ptr<AudioFileSource> fs;
996 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
997 if (!fs->destructive()) {
998 if (fs->length(fs->timeline_position()) == 0) {
1004 child->add_child_nocopy (siter->second->get_state());
1008 child = node->add_child ("Regions");
1011 Glib::Mutex::Lock rl (region_lock);
1013 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
1015 /* only store regions not attached to playlists */
1017 if (i->second->playlist() == 0) {
1018 child->add_child_nocopy (i->second->state (true));
1023 child = node->add_child ("DiskStreams");
1026 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1027 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1028 if (!(*i)->hidden()) {
1029 child->add_child_nocopy ((*i)->get_state());
1035 node->add_child_nocopy (_locations.get_state());
1037 // for a template, just create a new Locations, populate it
1038 // with the default start and end, and get the state for that.
1040 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1041 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1044 end->set_end(compute_initial_length());
1046 node->add_child_nocopy (loc.get_state());
1049 child = node->add_child ("Bundles");
1051 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1052 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1053 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1055 child->add_child_nocopy (b->get_state());
1060 child = node->add_child ("Routes");
1062 boost::shared_ptr<RouteList> r = routes.reader ();
1064 RoutePublicOrderSorter cmp;
1065 RouteList public_order (*r);
1066 public_order.sort (cmp);
1068 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1069 if (!(*i)->is_hidden()) {
1071 child->add_child_nocopy ((*i)->get_state());
1073 child->add_child_nocopy ((*i)->get_template());
1080 child = node->add_child ("EditGroups");
1081 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1082 child->add_child_nocopy ((*i)->get_state());
1085 child = node->add_child ("MixGroups");
1086 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1087 child->add_child_nocopy ((*i)->get_state());
1090 child = node->add_child ("Playlists");
1091 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1092 if (!(*i)->hidden()) {
1093 if (!(*i)->empty()) {
1095 child->add_child_nocopy ((*i)->get_state());
1097 child->add_child_nocopy ((*i)->get_template());
1103 child = node->add_child ("UnusedPlaylists");
1104 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1105 if (!(*i)->hidden()) {
1106 if (!(*i)->empty()) {
1108 child->add_child_nocopy ((*i)->get_state());
1110 child->add_child_nocopy ((*i)->get_template());
1118 child = node->add_child ("Click");
1119 child->add_child_nocopy (_click_io->state (full_state));
1123 child = node->add_child ("NamedSelections");
1124 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1126 child->add_child_nocopy ((*i)->get_state());
1131 node->add_child_nocopy (_tempo_map->get_state());
1133 node->add_child_nocopy (get_control_protocol_state());
1136 node->add_child_copy (*_extra_xml);
1143 Session::get_control_protocol_state ()
1145 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1146 return cpm.get_state();
1150 Session::set_state (const XMLNode& node)
1154 const XMLProperty* prop;
1157 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1159 if (node.name() != X_("Session")){
1160 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1164 if ((prop = node.property ("name")) != 0) {
1165 _name = prop->value ();
1168 if ((prop = node.property (X_("sample-rate"))) != 0) {
1170 _nominal_frame_rate = atoi (prop->value());
1172 if (_nominal_frame_rate != _current_frame_rate) {
1173 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1179 setup_raid_path(_session_dir->root_path().to_string());
1181 if ((prop = node.property (X_("id-counter"))) != 0) {
1183 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1184 ID::init_counter (x);
1186 /* old sessions used a timebased counter, so fake
1187 the startup ID counter based on a standard
1192 ID::init_counter (now);
1196 IO::disable_ports ();
1197 IO::disable_connecting ();
1199 /* Object loading order:
1204 MIDI Control // relies on data from Options/Config
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 (use_config_midi_ports ()) {
1233 if ((child = find_named_node (node, "Metadata")) == 0) {
1234 warning << _("Session: XML state has no metadata section (2.0 session?)") << endmsg;
1235 } else if (_metadata->set_state (*child)) {
1239 if ((child = find_named_node (node, "Locations")) == 0) {
1240 error << _("Session: XML state has no locations section") << endmsg;
1242 } else if (_locations.set_state (*child)) {
1248 if ((location = _locations.auto_loop_location()) != 0) {
1249 set_auto_loop_location (location);
1252 if ((location = _locations.auto_punch_location()) != 0) {
1253 set_auto_punch_location (location);
1256 if ((location = _locations.end_location()) == 0) {
1257 _locations.add (end_location);
1259 delete end_location;
1260 end_location = location;
1263 if ((location = _locations.start_location()) == 0) {
1264 _locations.add (start_location);
1266 delete start_location;
1267 start_location = location;
1270 AudioFileSource::set_header_position_offset (start_location->start());
1272 if ((child = find_named_node (node, "Sources")) == 0) {
1273 error << _("Session: XML state has no sources section") << endmsg;
1275 } else if (load_sources (*child)) {
1279 if ((child = find_named_node (node, "Regions")) == 0) {
1280 error << _("Session: XML state has no Regions section") << endmsg;
1282 } else if (load_regions (*child)) {
1286 if ((child = find_named_node (node, "Playlists")) == 0) {
1287 error << _("Session: XML state has no playlists section") << endmsg;
1289 } else if (load_playlists (*child)) {
1293 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1295 } else if (load_unused_playlists (*child)) {
1299 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1300 if (load_named_selections (*child)) {
1305 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1306 error << _("Session: XML state has no diskstreams section") << endmsg;
1308 } else if (load_diskstreams (*child)) {
1312 if ((child = find_named_node (node, "Bundles")) == 0) {
1313 warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg;
1316 /* We can't load Bundles yet as they need to be able
1317 to convert from port names to Port objects, which can't happen until
1319 _bundle_xml_node = new XMLNode (*child);
1322 if ((child = find_named_node (node, "EditGroups")) == 0) {
1323 error << _("Session: XML state has no edit groups section") << endmsg;
1325 } else if (load_edit_groups (*child)) {
1329 if ((child = find_named_node (node, "MixGroups")) == 0) {
1330 error << _("Session: XML state has no mix groups section") << endmsg;
1332 } else if (load_mix_groups (*child)) {
1336 if ((child = find_named_node (node, "TempoMap")) == 0) {
1337 error << _("Session: XML state has no Tempo Map section") << endmsg;
1339 } else if (_tempo_map->set_state (*child)) {
1343 if ((child = find_named_node (node, "Routes")) == 0) {
1344 error << _("Session: XML state has no routes section") << endmsg;
1346 } else if (load_routes (*child)) {
1350 if ((child = find_named_node (node, "Click")) == 0) {
1351 warning << _("Session: XML state has no click section") << endmsg;
1352 } else if (_click_io) {
1353 _click_io->set_state (*child);
1356 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1357 ControlProtocolManager::instance().set_protocol_states (*child);
1360 /* here beginneth the second phase ... */
1362 StateReady (); /* EMIT SIGNAL */
1371 Session::load_routes (const XMLNode& node)
1374 XMLNodeConstIterator niter;
1375 RouteList new_routes;
1377 nlist = node.children();
1381 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1383 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1386 error << _("Session: cannot create Route from XML description.") << endmsg;
1390 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1392 new_routes.push_back (route);
1395 add_routes (new_routes, false);
1400 boost::shared_ptr<Route>
1401 Session::XMLRouteFactory (const XMLNode& node)
1403 if (node.name() != "Route") {
1404 return boost::shared_ptr<Route> ((Route*) 0);
1407 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1409 DataType type = DataType::AUDIO;
1410 const XMLProperty* prop = node.property("default-type");
1412 type = DataType(prop->value());
1414 assert(type != DataType::NIL);
1416 if (has_diskstream) {
1417 if (type == DataType::AUDIO) {
1418 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1421 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1425 boost::shared_ptr<Route> ret (new Route (*this, node));
1431 Session::load_regions (const XMLNode& node)
1434 XMLNodeConstIterator niter;
1435 boost::shared_ptr<Region> region;
1437 nlist = node.children();
1441 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1442 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1443 error << _("Session: cannot create Region from XML description.");
1444 const XMLProperty *name = (**niter).property("name");
1447 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1457 boost::shared_ptr<Region>
1458 Session::XMLRegionFactory (const XMLNode& node, bool full)
1460 const XMLProperty* type = node.property("type");
1464 if ( !type || type->value() == "audio" ) {
1466 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1468 } else if (type->value() == "midi") {
1470 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1474 } catch (failed_constructor& err) {
1475 return boost::shared_ptr<Region> ();
1478 return boost::shared_ptr<Region> ();
1481 boost::shared_ptr<AudioRegion>
1482 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1484 const XMLProperty* prop;
1485 boost::shared_ptr<Source> source;
1486 boost::shared_ptr<AudioSource> as;
1488 SourceList master_sources;
1489 uint32_t nchans = 1;
1492 if (node.name() != X_("Region")) {
1493 return boost::shared_ptr<AudioRegion>();
1496 if ((prop = node.property (X_("channels"))) != 0) {
1497 nchans = atoi (prop->value().c_str());
1500 if ((prop = node.property ("name")) == 0) {
1501 cerr << "no name for this region\n";
1505 if ((prop = node.property (X_("source-0"))) == 0) {
1506 if ((prop = node.property ("source")) == 0) {
1507 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1508 return boost::shared_ptr<AudioRegion>();
1512 PBD::ID s_id (prop->value());
1514 if ((source = source_by_id (s_id)) == 0) {
1515 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1516 return boost::shared_ptr<AudioRegion>();
1519 as = boost::dynamic_pointer_cast<AudioSource>(source);
1521 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1522 return boost::shared_ptr<AudioRegion>();
1525 sources.push_back (as);
1527 /* pickup other channels */
1529 for (uint32_t n=1; n < nchans; ++n) {
1530 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1531 if ((prop = node.property (buf)) != 0) {
1533 PBD::ID id2 (prop->value());
1535 if ((source = source_by_id (id2)) == 0) {
1536 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1537 return boost::shared_ptr<AudioRegion>();
1540 as = boost::dynamic_pointer_cast<AudioSource>(source);
1542 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1543 return boost::shared_ptr<AudioRegion>();
1545 sources.push_back (as);
1549 for (uint32_t n=1; n < nchans; ++n) {
1550 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1551 if ((prop = node.property (buf)) != 0) {
1553 PBD::ID id2 (prop->value());
1555 if ((source = source_by_id (id2)) == 0) {
1556 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1557 return boost::shared_ptr<AudioRegion>();
1560 as = boost::dynamic_pointer_cast<AudioSource>(source);
1562 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1563 return boost::shared_ptr<AudioRegion>();
1565 master_sources.push_back (as);
1570 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1572 /* a final detail: this is the one and only place that we know how long missing files are */
1574 if (region->whole_file()) {
1575 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1576 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1578 sfp->set_length (region->length());
1583 if (!master_sources.empty()) {
1584 if (master_sources.size() == nchans) {
1585 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1587 region->set_master_sources (master_sources);
1595 catch (failed_constructor& err) {
1596 return boost::shared_ptr<AudioRegion>();
1600 boost::shared_ptr<MidiRegion>
1601 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1603 const XMLProperty* prop;
1604 boost::shared_ptr<Source> source;
1605 boost::shared_ptr<MidiSource> ms;
1607 uint32_t nchans = 1;
1609 if (node.name() != X_("Region")) {
1610 return boost::shared_ptr<MidiRegion>();
1613 if ((prop = node.property (X_("channels"))) != 0) {
1614 nchans = atoi (prop->value().c_str());
1617 if ((prop = node.property ("name")) == 0) {
1618 cerr << "no name for this region\n";
1622 // Multiple midi channels? that's just crazy talk
1623 assert(nchans == 1);
1625 if ((prop = node.property (X_("source-0"))) == 0) {
1626 if ((prop = node.property ("source")) == 0) {
1627 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1628 return boost::shared_ptr<MidiRegion>();
1632 PBD::ID s_id (prop->value());
1634 if ((source = source_by_id (s_id)) == 0) {
1635 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1636 return boost::shared_ptr<MidiRegion>();
1639 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1641 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1642 return boost::shared_ptr<MidiRegion>();
1645 sources.push_back (ms);
1648 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1649 /* a final detail: this is the one and only place that we know how long missing files are */
1651 if (region->whole_file()) {
1652 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1653 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1655 sfp->set_length (region->length());
1663 catch (failed_constructor& err) {
1664 return boost::shared_ptr<MidiRegion>();
1669 Session::get_sources_as_xml ()
1672 XMLNode* node = new XMLNode (X_("Sources"));
1673 Glib::Mutex::Lock lm (source_lock);
1675 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1676 node->add_child_nocopy (i->second->get_state());
1683 Session::path_from_region_name (DataType type, string name, string identifier)
1685 char buf[PATH_MAX+1];
1687 SessionDirectory sdir(get_best_session_directory_for_new_source());
1688 sys::path source_dir = ((type == DataType::AUDIO)
1689 ? sdir.sound_path() : sdir.midi_path());
1691 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1693 for (n = 0; n < 999999; ++n) {
1694 if (identifier.length()) {
1695 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1696 identifier.c_str(), n, ext.c_str());
1698 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1702 sys::path source_path = source_dir / buf;
1704 if (!sys::exists (source_path)) {
1705 return source_path.to_string();
1709 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1718 Session::load_sources (const XMLNode& node)
1721 XMLNodeConstIterator niter;
1722 boost::shared_ptr<Source> source;
1724 nlist = node.children();
1728 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1730 if ((source = XMLSourceFactory (**niter)) == 0) {
1731 error << _("Session: cannot create Source from XML description.") << endmsg;
1733 } catch (MissingSource& err) {
1734 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1735 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1742 boost::shared_ptr<Source>
1743 Session::XMLSourceFactory (const XMLNode& node)
1745 if (node.name() != "Source") {
1746 return boost::shared_ptr<Source>();
1750 /* note: do peak building in another thread when loading session state */
1751 return SourceFactory::create (*this, node, true);
1754 catch (failed_constructor& err) {
1755 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1756 return boost::shared_ptr<Source>();
1761 Session::save_template (string template_name)
1765 if (_state_of_the_state & CannotSave) {
1769 sys::path user_template_dir(user_template_directory());
1773 sys::create_directories (user_template_dir);
1775 catch(sys::filesystem_error& ex)
1777 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1778 user_template_dir.to_string(), ex.what()) << endmsg;
1782 tree.set_root (&get_template());
1784 sys::path template_file_path(user_template_dir);
1785 template_file_path /= template_name + template_suffix;
1787 if (sys::exists (template_file_path))
1789 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1790 template_file_path.to_string()) << endmsg;
1794 if (!tree.write (template_file_path.to_string())) {
1795 error << _("mix template not saved") << endmsg;
1803 Session::rename_template (string old_name, string new_name)
1805 sys::path old_path (user_template_directory());
1806 old_path /= old_name + template_suffix;
1808 sys::path new_path(user_template_directory());
1809 new_path /= new_name + template_suffix;
1811 if (sys::exists (new_path)) {
1812 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1813 new_path.to_string()) << endmsg;
1818 sys::rename (old_path, new_path);
1826 Session::delete_template (string name)
1828 sys::path path = user_template_directory();
1829 path /= name + template_suffix;
1840 Session::refresh_disk_space ()
1843 struct statfs statfsbuf;
1844 vector<space_and_path>::iterator i;
1845 Glib::Mutex::Lock lm (space_lock);
1848 /* get freespace on every FS that is part of the session path */
1850 _total_free_4k_blocks = 0;
1852 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1853 statfs ((*i).path.c_str(), &statfsbuf);
1855 scale = statfsbuf.f_bsize/4096.0;
1857 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1858 _total_free_4k_blocks += (*i).blocks;
1864 Session::get_best_session_directory_for_new_source ()
1866 vector<space_and_path>::iterator i;
1867 string result = _session_dir->root_path().to_string();
1869 /* handle common case without system calls */
1871 if (session_dirs.size() == 1) {
1875 /* OK, here's the algorithm we're following here:
1877 We want to select which directory to use for
1878 the next file source to be created. Ideally,
1879 we'd like to use a round-robin process so as to
1880 get maximum performance benefits from splitting
1881 the files across multiple disks.
1883 However, in situations without much diskspace, an
1884 RR approach may end up filling up a filesystem
1885 with new files while others still have space.
1886 Its therefore important to pay some attention to
1887 the freespace in the filesystem holding each
1888 directory as well. However, if we did that by
1889 itself, we'd keep creating new files in the file
1890 system with the most space until it was as full
1891 as all others, thus negating any performance
1892 benefits of this RAID-1 like approach.
1894 So, we use a user-configurable space threshold. If
1895 there are at least 2 filesystems with more than this
1896 much space available, we use RR selection between them.
1897 If not, then we pick the filesystem with the most space.
1899 This gets a good balance between the two
1903 refresh_disk_space ();
1905 int free_enough = 0;
1907 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1908 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1913 if (free_enough >= 2) {
1914 /* use RR selection process, ensuring that the one
1918 i = last_rr_session_dir;
1921 if (++i == session_dirs.end()) {
1922 i = session_dirs.begin();
1925 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1926 if (create_session_directory ((*i).path)) {
1928 last_rr_session_dir = i;
1933 } while (i != last_rr_session_dir);
1937 /* pick FS with the most freespace (and that
1938 seems to actually work ...)
1941 vector<space_and_path> sorted;
1942 space_and_path_ascending_cmp cmp;
1944 sorted = session_dirs;
1945 sort (sorted.begin(), sorted.end(), cmp);
1947 for (i = sorted.begin(); i != sorted.end(); ++i) {
1948 if (create_session_directory ((*i).path)) {
1950 last_rr_session_dir = i;
1960 Session::load_playlists (const XMLNode& node)
1963 XMLNodeConstIterator niter;
1964 boost::shared_ptr<Playlist> playlist;
1966 nlist = node.children();
1970 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1972 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1973 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1981 Session::load_unused_playlists (const XMLNode& node)
1984 XMLNodeConstIterator niter;
1985 boost::shared_ptr<Playlist> playlist;
1987 nlist = node.children();
1991 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1993 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1994 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1998 // now manually untrack it
2000 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
2006 boost::shared_ptr<Playlist>
2007 Session::XMLPlaylistFactory (const XMLNode& node)
2010 return PlaylistFactory::create (*this, node);
2013 catch (failed_constructor& err) {
2014 return boost::shared_ptr<Playlist>();
2019 Session::load_named_selections (const XMLNode& node)
2022 XMLNodeConstIterator niter;
2025 nlist = node.children();
2029 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2031 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2032 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2040 Session::XMLNamedSelectionFactory (const XMLNode& node)
2043 return new NamedSelection (*this, node);
2046 catch (failed_constructor& err) {
2052 Session::automation_dir () const
2054 return Glib::build_filename (_path, "automation");
2058 Session::analysis_dir () const
2060 return Glib::build_filename (_path, "analysis");
2064 Session::load_bundles (XMLNode const & node)
2066 XMLNodeList nlist = node.children();
2067 XMLNodeConstIterator niter;
2071 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2072 if ((*niter)->name() == "InputBundle") {
2073 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2074 } else if ((*niter)->name() == "OutputBundle") {
2075 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2077 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2086 Session::load_edit_groups (const XMLNode& node)
2088 return load_route_groups (node, true);
2092 Session::load_mix_groups (const XMLNode& node)
2094 return load_route_groups (node, false);
2098 Session::load_route_groups (const XMLNode& node, bool edit)
2100 XMLNodeList nlist = node.children();
2101 XMLNodeConstIterator niter;
2106 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2107 if ((*niter)->name() == "RouteGroup") {
2109 rg = add_edit_group ("");
2110 rg->set_state (**niter);
2112 rg = add_mix_group ("");
2113 rg->set_state (**niter);
2122 Session::auto_save()
2124 save_state (_current_snapshot_name);
2128 state_file_filter (const string &str, void *arg)
2130 return (str.length() > strlen(statefile_suffix) &&
2131 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2135 bool operator()(const string* a, const string* b) {
2141 remove_end(string* state)
2143 string statename(*state);
2145 string::size_type start,end;
2146 if ((start = statename.find_last_of ('/')) != string::npos) {
2147 statename = statename.substr (start+1);
2150 if ((end = statename.rfind(".ardour")) == string::npos) {
2151 end = statename.length();
2154 return new string(statename.substr (0, end));
2158 Session::possible_states (string path)
2160 PathScanner scanner;
2161 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2163 transform(states->begin(), states->end(), states->begin(), remove_end);
2166 sort (states->begin(), states->end(), cmp);
2172 Session::possible_states () const
2174 return possible_states(_path);
2178 Session::add_edit_group (string name)
2180 RouteGroup* rg = new RouteGroup (*this, name);
2181 edit_groups.push_back (rg);
2182 edit_group_added (rg); /* EMIT SIGNAL */
2188 Session::add_mix_group (string name)
2190 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2191 mix_groups.push_back (rg);
2192 mix_group_added (rg); /* EMIT SIGNAL */
2198 Session::remove_edit_group (RouteGroup& rg)
2200 list<RouteGroup*>::iterator i;
2202 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2203 (*i)->apply (&Route::drop_edit_group, this);
2204 edit_groups.erase (i);
2205 edit_group_removed (); /* EMIT SIGNAL */
2212 Session::remove_mix_group (RouteGroup& rg)
2214 list<RouteGroup*>::iterator i;
2216 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2217 (*i)->apply (&Route::drop_mix_group, this);
2218 mix_groups.erase (i);
2219 mix_group_removed (); /* EMIT SIGNAL */
2226 Session::mix_group_by_name (string name)
2228 list<RouteGroup *>::iterator i;
2230 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2231 if ((*i)->name() == name) {
2239 Session::edit_group_by_name (string name)
2241 list<RouteGroup *>::iterator i;
2243 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2244 if ((*i)->name() == name) {
2252 Session::begin_reversible_command (const string& name)
2254 current_trans = new UndoTransaction;
2255 current_trans->set_name (name);
2259 Session::commit_reversible_command (Command *cmd)
2264 current_trans->add_command (cmd);
2267 if (current_trans->empty()) {
2271 gettimeofday (&now, 0);
2272 current_trans->set_timestamp (now);
2274 _history.add (current_trans);
2277 Session::GlobalRouteBooleanState
2278 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2280 GlobalRouteBooleanState s;
2281 boost::shared_ptr<RouteList> r = routes.reader ();
2283 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2284 if (!(*i)->is_hidden()) {
2285 RouteBooleanState v;
2288 Route* r = (*i).get();
2289 v.second = (r->*method)();
2298 Session::GlobalRouteMeterState
2299 Session::get_global_route_metering ()
2301 GlobalRouteMeterState s;
2302 boost::shared_ptr<RouteList> r = routes.reader ();
2304 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2305 if (!(*i)->is_hidden()) {
2309 v.second = (*i)->meter_point();
2319 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2321 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2323 boost::shared_ptr<Route> r = (i->first.lock());
2326 r->set_meter_point (i->second, arg);
2332 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2334 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2336 boost::shared_ptr<Route> r = (i->first.lock());
2339 Route* rp = r.get();
2340 (rp->*method) (i->second, arg);
2346 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2348 set_global_route_boolean (s, &Route::set_mute, src);
2352 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2354 set_global_route_boolean (s, &Route::set_solo, src);
2358 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2360 set_global_route_boolean (s, &Route::set_record_enable, src);
2364 accept_all_non_peak_files (const string& path, void *arg)
2366 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2370 accept_all_state_files (const string& path, void *arg)
2372 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2376 Session::find_all_sources (string path, set<string>& result)
2381 if (!tree.read (path)) {
2385 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2390 XMLNodeConstIterator niter;
2392 nlist = node->children();
2396 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2400 if ((prop = (*niter)->property (X_("name"))) == 0) {
2404 if (prop->value()[0] == '/') {
2405 /* external file, ignore */
2409 sys::path source_path = _session_dir->sound_path ();
2411 source_path /= prop->value ();
2413 result.insert (source_path.to_string ());
2420 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2422 PathScanner scanner;
2423 vector<string*>* state_files;
2425 string this_snapshot_path;
2431 if (ripped[ripped.length()-1] == '/') {
2432 ripped = ripped.substr (0, ripped.length() - 1);
2435 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2437 if (state_files == 0) {
2442 this_snapshot_path = _path;
2443 this_snapshot_path += _current_snapshot_name;
2444 this_snapshot_path += statefile_suffix;
2446 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2448 if (exclude_this_snapshot && **i == this_snapshot_path) {
2452 if (find_all_sources (**i, result) < 0) {
2460 struct RegionCounter {
2461 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2462 AudioSourceList::iterator iter;
2463 boost::shared_ptr<Region> region;
2466 RegionCounter() : count (0) {}
2470 Session::cleanup_sources (Session::cleanup_report& rep)
2472 // FIXME: needs adaptation to midi
2474 vector<boost::shared_ptr<Source> > dead_sources;
2475 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2476 PathScanner scanner;
2478 vector<space_and_path>::iterator i;
2479 vector<space_and_path>::iterator nexti;
2480 vector<string*>* soundfiles;
2481 vector<string> unused;
2482 set<string> all_sources;
2487 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2490 /* step 1: consider deleting all unused playlists */
2492 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2495 status = AskAboutPlaylistDeletion (*x);
2504 playlists_tbd.push_back (*x);
2508 /* leave it alone */
2513 /* now delete any that were marked for deletion */
2515 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2516 (*x)->drop_references ();
2519 playlists_tbd.clear ();
2521 /* step 2: find all un-used sources */
2526 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2528 SourceMap::iterator tmp;
2533 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2537 if (!i->second->used() && i->second->length(i->second->timeline_position()) > 0) {
2538 dead_sources.push_back (i->second);
2539 i->second->GoingAway();
2545 /* build a list of all the possible sound directories for the session */
2547 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2552 SessionDirectory sdir ((*i).path);
2553 sound_path += sdir.sound_path().to_string();
2555 if (nexti != session_dirs.end()) {
2562 /* now do the same thing for the files that ended up in the sounds dir(s)
2563 but are not referenced as sources in any snapshot.
2566 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2568 if (soundfiles == 0) {
2572 /* find all sources, but don't use this snapshot because the
2573 state file on disk still references sources we may have already
2577 find_all_sources_across_snapshots (all_sources, true);
2579 /* add our current source list
2582 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2583 boost::shared_ptr<FileSource> fs;
2585 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2586 all_sources.insert (fs->path());
2590 char tmppath1[PATH_MAX+1];
2591 char tmppath2[PATH_MAX+1];
2593 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2598 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2600 realpath(spath.c_str(), tmppath1);
2601 realpath((*i).c_str(), tmppath2);
2603 if (strcmp(tmppath1, tmppath2) == 0) {
2610 unused.push_back (spath);
2614 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2616 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2617 struct stat statbuf;
2619 rep.paths.push_back (*x);
2620 if (stat ((*x).c_str(), &statbuf) == 0) {
2621 rep.space += statbuf.st_size;
2626 /* don't move the file across filesystems, just
2627 stick it in the `dead_sound_dir_name' directory
2628 on whichever filesystem it was already on.
2631 if ((*x).find ("/sounds/") != string::npos) {
2633 /* old school, go up 1 level */
2635 newpath = Glib::path_get_dirname (*x); // "sounds"
2636 newpath = Glib::path_get_dirname (newpath); // "session-name"
2640 /* new school, go up 4 levels */
2642 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2643 newpath = Glib::path_get_dirname (newpath); // "session-name"
2644 newpath = Glib::path_get_dirname (newpath); // "interchange"
2645 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2649 newpath += dead_sound_dir_name;
2651 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2652 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2657 newpath += Glib::path_get_basename ((*x));
2659 if (access (newpath.c_str(), F_OK) == 0) {
2661 /* the new path already exists, try versioning */
2663 char buf[PATH_MAX+1];
2667 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2670 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2671 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2675 if (version == 999) {
2676 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2680 newpath = newpath_v;
2685 /* it doesn't exist, or we can't read it or something */
2689 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2690 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2691 (*x), newpath, strerror (errno))
2696 /* see if there an easy to find peakfile for this file, and remove it.
2699 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2700 peakpath += peakfile_suffix;
2702 if (access (peakpath.c_str(), W_OK) == 0) {
2703 if (::unlink (peakpath.c_str()) != 0) {
2704 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2705 peakpath, _path, strerror (errno))
2707 /* try to back out */
2708 rename (newpath.c_str(), _path.c_str());
2716 /* dump the history list */
2720 /* save state so we don't end up a session file
2721 referring to non-existent sources.
2727 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2733 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2735 // FIXME: needs adaptation for MIDI
2737 vector<space_and_path>::iterator i;
2738 string dead_sound_dir;
2739 struct dirent* dentry;
2740 struct stat statbuf;
2746 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2748 dead_sound_dir = (*i).path;
2749 dead_sound_dir += dead_sound_dir_name;
2751 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2755 while ((dentry = readdir (dead)) != 0) {
2757 /* avoid '.' and '..' */
2759 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2760 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2766 fullpath = dead_sound_dir;
2768 fullpath += dentry->d_name;
2770 if (stat (fullpath.c_str(), &statbuf)) {
2774 if (!S_ISREG (statbuf.st_mode)) {
2778 if (unlink (fullpath.c_str())) {
2779 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2780 fullpath, strerror (errno))
2784 rep.paths.push_back (dentry->d_name);
2785 rep.space += statbuf.st_size;
2796 Session::set_dirty ()
2798 bool was_dirty = dirty();
2800 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2804 DirtyChanged(); /* EMIT SIGNAL */
2810 Session::set_clean ()
2812 bool was_dirty = dirty();
2814 _state_of_the_state = Clean;
2818 DirtyChanged(); /* EMIT SIGNAL */
2823 Session::set_deletion_in_progress ()
2825 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2830 Session::add_controllable (boost::shared_ptr<Controllable> c)
2832 /* this adds a controllable to the list managed by the Session.
2833 this is a subset of those managed by the Controllable class
2834 itself, and represents the only ones whose state will be saved
2835 as part of the session.
2838 Glib::Mutex::Lock lm (controllables_lock);
2839 controllables.insert (c);
2842 struct null_deleter { void operator()(void const *) const {} };
2845 Session::remove_controllable (Controllable* c)
2847 if (_state_of_the_state | Deletion) {
2851 Glib::Mutex::Lock lm (controllables_lock);
2853 Controllables::iterator x = controllables.find(
2854 boost::shared_ptr<Controllable>(c, null_deleter()));
2856 if (x != controllables.end()) {
2857 controllables.erase (x);
2861 boost::shared_ptr<Controllable>
2862 Session::controllable_by_id (const PBD::ID& id)
2864 Glib::Mutex::Lock lm (controllables_lock);
2866 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2867 if ((*i)->id() == id) {
2872 return boost::shared_ptr<Controllable>();
2876 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2878 Stateful::add_instant_xml (node, _path);
2879 if (write_to_config) {
2880 Config->add_instant_xml (node);
2885 Session::instant_xml (const string& node_name)
2887 return Stateful::instant_xml (node_name, _path);
2891 Session::save_history (string snapshot_name)
2895 if (snapshot_name.empty()) {
2896 snapshot_name = _current_snapshot_name;
2899 const string history_filename = snapshot_name + history_suffix;
2900 const string backup_filename = history_filename + backup_suffix;
2901 const sys::path xml_path = _session_dir->root_path() / history_filename;
2902 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2904 if (sys::exists (xml_path)) {
2907 sys::rename (xml_path, backup_path);
2909 catch (const sys::filesystem_error& err)
2911 error << _("could not backup old history file, current history not saved") << endmsg;
2917 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2921 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2923 if (!tree.write (xml_path.to_string()))
2925 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2929 sys::remove (xml_path);
2930 sys::rename (backup_path, xml_path);
2932 catch (const sys::filesystem_error& err)
2934 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2935 backup_path.to_string(), err.what()) << endmsg;
2945 Session::restore_history (string snapshot_name)
2949 if (snapshot_name.empty()) {
2950 snapshot_name = _current_snapshot_name;
2953 const string xml_filename = snapshot_name + history_suffix;
2954 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2956 cerr << "Loading history from " << xml_path.to_string() << endmsg;
2958 if (!sys::exists (xml_path)) {
2959 info << string_compose (_("%1: no history file \"%2\" for this session."),
2960 _name, xml_path.to_string()) << endmsg;
2964 if (!tree.read (xml_path.to_string())) {
2965 error << string_compose (_("Could not understand session history file \"%1\""),
2966 xml_path.to_string()) << endmsg;
2973 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2976 UndoTransaction* ut = new UndoTransaction ();
2979 ut->set_name(t->property("name")->value());
2980 stringstream ss(t->property("tv-sec")->value());
2982 ss.str(t->property("tv-usec")->value());
2984 ut->set_timestamp(tv);
2986 for (XMLNodeConstIterator child_it = t->children().begin();
2987 child_it != t->children().end(); child_it++)
2989 XMLNode *n = *child_it;
2992 if (n->name() == "MementoCommand" ||
2993 n->name() == "MementoUndoCommand" ||
2994 n->name() == "MementoRedoCommand") {
2996 if ((c = memento_command_factory(n))) {
3000 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3002 if ((c = global_state_command_factory (*n))) {
3003 ut->add_command (c);
3006 } else if (n->name() == "DeltaCommand") {
3007 PBD::ID id(n->property("midi-source")->value());
3008 boost::shared_ptr<MidiSource> midi_source =
3009 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3011 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
3013 error << "FIXME: Failed to downcast MidiSource for DeltaCommand" << endmsg;
3016 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3027 Session::config_changed (const char* parameter_name)
3029 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3031 if (PARAM_IS ("seamless-loop")) {
3033 } else if (PARAM_IS ("rf-speed")) {
3035 } else if (PARAM_IS ("auto-loop")) {
3037 } else if (PARAM_IS ("auto-input")) {
3039 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3040 /* auto-input only makes a difference if we're rolling */
3042 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3044 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3045 if ((*i)->record_enabled ()) {
3046 (*i)->monitor_input (!Config->get_auto_input());
3051 } else if (PARAM_IS ("punch-in")) {
3055 if ((location = _locations.auto_punch_location()) != 0) {
3057 if (Config->get_punch_in ()) {
3058 replace_event (Event::PunchIn, location->start());
3060 remove_event (location->start(), Event::PunchIn);
3064 } else if (PARAM_IS ("punch-out")) {
3068 if ((location = _locations.auto_punch_location()) != 0) {
3070 if (Config->get_punch_out()) {
3071 replace_event (Event::PunchOut, location->end());
3073 clear_events (Event::PunchOut);
3077 } else if (PARAM_IS ("edit-mode")) {
3079 Glib::Mutex::Lock lm (playlist_lock);
3081 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3082 (*i)->set_edit_mode (Config->get_edit_mode ());
3085 } else if (PARAM_IS ("use-video-sync")) {
3087 waiting_for_sync_offset = Config->get_use_video_sync();
3089 } else if (PARAM_IS ("mmc-control")) {
3091 //poke_midi_thread ();
3093 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
3096 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3099 } else if (PARAM_IS ("mmc-send-id")) {
3102 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3105 } else if (PARAM_IS ("midi-control")) {
3107 //poke_midi_thread ();
3109 } else if (PARAM_IS ("raid-path")) {
3111 setup_raid_path (Config->get_raid_path());
3113 } else if (PARAM_IS ("smpte-format")) {
3117 } else if (PARAM_IS ("video-pullup")) {
3121 } else if (PARAM_IS ("seamless-loop")) {
3123 if (play_loop && transport_rolling()) {
3124 // to reset diskstreams etc
3125 request_play_loop (true);
3128 } else if (PARAM_IS ("rf-speed")) {
3130 cumulative_rf_motion = 0;
3133 } else if (PARAM_IS ("click-sound")) {
3135 setup_click_sounds (1);
3137 } else if (PARAM_IS ("click-emphasis-sound")) {
3139 setup_click_sounds (-1);
3141 } else if (PARAM_IS ("clicking")) {
3143 if (Config->get_clicking()) {
3144 if (_click_io && click_data) { // don't require emphasis data
3151 } else if (PARAM_IS ("send-mtc")) {
3153 /* only set the internal flag if we have
3157 if (_mtc_port != 0) {
3158 session_send_mtc = Config->get_send_mtc();
3159 if (session_send_mtc) {
3160 /* mark us ready to send */
3161 next_quarter_frame_to_send = 0;
3164 session_send_mtc = false;
3167 } else if (PARAM_IS ("send-mmc")) {
3169 /* only set the internal flag if we have
3173 if (_mmc_port != 0) {
3174 session_send_mmc = Config->get_send_mmc();
3177 session_send_mmc = false;
3180 } else if (PARAM_IS ("midi-feedback")) {
3182 /* only set the internal flag if we have
3186 if (_mtc_port != 0) {
3187 session_midi_feedback = Config->get_midi_feedback();
3190 } else if (PARAM_IS ("jack-time-master")) {
3192 engine().reset_timebase ();
3194 } else if (PARAM_IS ("native-file-header-format")) {
3196 if (!first_file_header_format_reset) {
3197 reset_native_file_format ();
3200 first_file_header_format_reset = false;
3202 } else if (PARAM_IS ("native-file-data-format")) {
3204 if (!first_file_data_format_reset) {
3205 reset_native_file_format ();
3208 first_file_data_format_reset = false;
3210 } else if (PARAM_IS ("slave-source")) {
3211 set_slave_source (Config->get_slave_source());
3212 } else if (PARAM_IS ("remote-model")) {
3213 set_remote_control_ids ();
3214 } else if (PARAM_IS ("denormal-model")) {
3216 } else if (PARAM_IS ("history-depth")) {
3217 set_history_depth (Config->get_history_depth());
3218 } else if (PARAM_IS ("sync-all-route-ordering")) {
3219 sync_order_keys ("session");
3220 } else if (PARAM_IS ("initial-program-change")) {
3222 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3225 buf[0] = MIDI::program; // channel zero by default
3226 buf[1] = (Config->get_initial_program_change() & 0x7f);
3228 _mmc_port->midimsg (buf, sizeof (buf), 0);
3230 } else if (PARAM_IS ("initial-program-change")) {
3232 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3233 MIDI::byte* buf = new MIDI::byte[2];
3235 buf[0] = MIDI::program; // channel zero by default
3236 buf[1] = (Config->get_initial_program_change() & 0x7f);
3237 // deliver_midi (_mmc_port, buf, 2);
3239 } else if (PARAM_IS ("solo-mute-override")) {
3240 catch_up_on_solo_mute_override ();
3250 Session::set_history_depth (uint32_t d)
3252 _history.set_depth (d);