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;
208 first_file_data_format_reset = true;
209 first_file_header_format_reset = true;
210 butler_thread = (pthread_t) 0;
211 //midi_thread = (pthread_t) 0;
213 AudioDiskstream::allocate_working_buffers();
215 /* default short fade = 15ms */
217 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
218 SndFileSource::setup_standard_crossfades (frame_rate());
220 last_mmc_step.tv_sec = 0;
221 last_mmc_step.tv_usec = 0;
224 /* click sounds are unset by default, which causes us to internal
225 waveforms for clicks.
229 click_emphasis_length = 0;
232 process_function = &Session::process_with_events;
234 if (Config->get_use_video_sync()) {
235 waiting_for_sync_offset = true;
237 waiting_for_sync_offset = false;
242 _smpte_offset_negative = true;
243 last_smpte_valid = false;
247 last_rr_session_dir = session_dirs.begin();
248 refresh_disk_space ();
250 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
254 average_slave_delta = 1800; // !!! why 1800 ????
255 have_first_delta_accumulator = false;
256 delta_accumulator_cnt = 0;
257 slave_state = Stopped;
259 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
261 /* These are all static "per-class" signals */
263 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
264 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
265 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
266 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
267 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
268 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
270 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
272 IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
274 /* stop IO objects from doing stuff until we're ready for them */
276 IO::disable_panners ();
277 IO::disable_ports ();
278 IO::disable_connecting ();
282 Session::second_stage_init (bool new_session)
284 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
287 if (load_state (_current_snapshot_name)) {
290 remove_empty_sounds ();
293 if (start_butler_thread()) {
297 if (start_midi_thread ()) {
301 // set_state() will call setup_raid_path(), but if it's a new session we need
302 // to call setup_raid_path() here.
305 if (set_state (*state_tree->root())) {
309 setup_raid_path(_path);
312 /* we can't save till after ::when_engine_running() is called,
313 because otherwise we save state with no connections made.
314 therefore, we reset _state_of_the_state because ::set_state()
315 will have cleared it.
317 we also have to include Loading so that any events that get
318 generated between here and the end of ::when_engine_running()
319 will be processed directly rather than queued.
322 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
325 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
326 _locations.added.connect (mem_fun (this, &Session::locations_added));
327 setup_click_sounds (0);
328 setup_midi_control ();
330 /* Pay attention ... */
332 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
333 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
336 when_engine_running();
339 /* handle this one in a different way than all others, so that its clear what happened */
341 catch (AudioEngine::PortRegistrationFailure& err) {
342 error << _("Unable to create all required ports")
351 BootMessage (_("Reset Remote Controls"));
353 send_full_time_code (0);
354 _engine.transport_locate (0);
355 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
356 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
358 MidiClockTicker::instance().set_session(*this);
359 MIDI::Name::MidiPatchManager::instance().set_session(*this);
361 /* initial program change will be delivered later; see ::config_changed() */
363 BootMessage (_("Reset Control Protocols"));
365 ControlProtocolManager::instance().set_session (*this);
368 _end_location_is_free = true;
370 _end_location_is_free = false;
373 _state_of_the_state = Clean;
375 DirtyChanged (); /* EMIT SIGNAL */
377 if (state_was_pending) {
378 save_state (_current_snapshot_name);
379 remove_pending_capture_state ();
380 state_was_pending = false;
383 BootMessage (_("Session loading complete"));
389 Session::raid_path () const
391 SearchPath raid_search_path;
393 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
394 raid_search_path += sys::path((*i).path);
397 return raid_search_path.to_string ();
401 Session::setup_raid_path (string path)
410 session_dirs.clear ();
412 SearchPath search_path(path);
413 SearchPath sound_search_path;
414 SearchPath midi_search_path;
416 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
417 sp.path = (*i).to_string ();
418 sp.blocks = 0; // not needed
419 session_dirs.push_back (sp);
421 SessionDirectory sdir(sp.path);
423 sound_search_path += sdir.sound_path ();
424 midi_search_path += sdir.midi_path ();
427 // set the search path for each data type
428 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
429 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
431 // reset the round-robin soundfile path thingie
432 last_rr_session_dir = session_dirs.begin();
436 Session::ensure_subdirs ()
440 dir = session_directory().peak_path().to_string();
442 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
443 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
447 dir = session_directory().sound_path().to_string();
449 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
450 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
454 dir = session_directory().midi_path().to_string();
456 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
457 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
461 dir = session_directory().dead_sound_path().to_string();
463 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
464 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
468 dir = session_directory().export_path().to_string();
470 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
471 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
475 dir = analysis_dir ();
477 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
478 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
486 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
489 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
490 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
494 if (ensure_subdirs ()) {
498 /* check new_session so we don't overwrite an existing one */
500 if (!mix_template.empty()) {
501 std::string in_path = mix_template;
503 ifstream in(in_path.c_str());
506 string out_path = _path;
508 out_path += statefile_suffix;
510 ofstream out(out_path.c_str());
515 // okay, session is set up. Treat like normal saved
516 // session from now on.
522 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
528 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
535 /* Instantiate metadata */
537 _metadata = new SessionMetadata ();
539 /* set initial start + end point */
541 start_location->set_end (0);
542 _locations.add (start_location);
544 end_location->set_end (initial_length);
545 _locations.add (end_location);
547 _state_of_the_state = Clean;
556 Session::load_diskstreams (const XMLNode& node)
559 XMLNodeConstIterator citer;
561 clist = node.children();
563 for (citer = clist.begin(); citer != clist.end(); ++citer) {
566 /* diskstreams added automatically by DiskstreamCreated handler */
567 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
568 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
569 add_diskstream (dstream);
570 } else if ((*citer)->name() == "MidiDiskstream") {
571 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
572 add_diskstream (dstream);
574 error << _("Session: unknown diskstream type in XML") << endmsg;
578 catch (failed_constructor& err) {
579 error << _("Session: could not load diskstream via XML state") << endmsg;
588 Session::maybe_write_autosave()
590 if (dirty() && record_status() != Recording) {
591 save_state("", true);
596 Session::remove_pending_capture_state ()
598 sys::path pending_state_file_path(_session_dir->root_path());
600 pending_state_file_path /= _current_snapshot_name + pending_suffix;
604 sys::remove (pending_state_file_path);
606 catch(sys::filesystem_error& ex)
608 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
609 pending_state_file_path.to_string(), ex.what()) << endmsg;
613 /** Rename a state file.
614 * @param snapshot_name Snapshot name.
617 Session::rename_state (string old_name, string new_name)
619 if (old_name == _current_snapshot_name || old_name == _name) {
620 /* refuse to rename the current snapshot or the "main" one */
624 const string old_xml_filename = old_name + statefile_suffix;
625 const string new_xml_filename = new_name + statefile_suffix;
627 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
628 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
632 sys::rename (old_xml_path, new_xml_path);
634 catch (const sys::filesystem_error& err)
636 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
637 old_name, new_name, err.what()) << endmsg;
641 /** Remove a state file.
642 * @param snapshot_name Snapshot name.
645 Session::remove_state (string snapshot_name)
647 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
648 // refuse to remove the current snapshot or the "main" one
652 sys::path xml_path(_session_dir->root_path());
654 xml_path /= snapshot_name + statefile_suffix;
656 if (!create_backup_file (xml_path)) {
657 // don't remove it if a backup can't be made
658 // create_backup_file will log the error.
663 sys::remove (xml_path);
667 Session::save_state (string snapshot_name, bool pending)
670 sys::path xml_path(_session_dir->root_path());
672 if (_state_of_the_state & CannotSave) {
676 if (!_engine.connected ()) {
677 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
682 /* tell sources we're saving first, in case they write out to a new file
683 * which should be saved with the state rather than the old one */
684 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
685 i->second->session_saved();
687 tree.set_root (&get_state());
689 if (snapshot_name.empty()) {
690 snapshot_name = _current_snapshot_name;
695 /* proper save: use statefile_suffix (.ardour in English) */
697 xml_path /= snapshot_name + statefile_suffix;
699 /* make a backup copy of the old file */
701 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
702 // create_backup_file will log the error
708 /* pending save: use pending_suffix (.pending in English) */
709 xml_path /= snapshot_name + pending_suffix;
712 sys::path tmp_path(_session_dir->root_path());
714 tmp_path /= snapshot_name + temp_suffix;
716 // cerr << "actually writing state to " << xml_path.to_string() << endl;
718 if (!tree.write (tmp_path.to_string())) {
719 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
720 sys::remove (tmp_path);
725 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
726 error << string_compose (_("could not rename temporary session file %1 to %2"),
727 tmp_path.to_string(), xml_path.to_string()) << endmsg;
728 sys::remove (tmp_path);
735 save_history (snapshot_name);
737 bool was_dirty = dirty();
739 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
742 DirtyChanged (); /* EMIT SIGNAL */
745 StateSaved (snapshot_name); /* EMIT SIGNAL */
752 Session::restore_state (string snapshot_name)
754 if (load_state (snapshot_name) == 0) {
755 set_state (*state_tree->root());
762 Session::load_state (string snapshot_name)
767 state_was_pending = false;
769 /* check for leftover pending state from a crashed capture attempt */
771 sys::path xmlpath(_session_dir->root_path());
772 xmlpath /= snapshot_name + pending_suffix;
774 if (sys::exists (xmlpath)) {
776 /* there is pending state from a crashed capture attempt */
778 if (AskAboutPendingState()) {
779 state_was_pending = true;
783 if (!state_was_pending) {
784 xmlpath = _session_dir->root_path();
785 xmlpath /= snapshot_name + statefile_suffix;
788 if (!sys::exists (xmlpath)) {
789 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
793 state_tree = new XMLTree;
797 if (!state_tree->read (xmlpath.to_string())) {
798 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
804 XMLNode& root (*state_tree->root());
806 if (root.name() != X_("Session")) {
807 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
813 const XMLProperty* prop;
814 bool is_old = false; // session is _very_ old (pre-2.0)
816 if ((prop = root.property ("version")) == 0) {
817 /* no version implies very old version of Ardour */
821 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
822 if (major_version < 2) {
829 sys::path backup_path(_session_dir->root_path());
831 backup_path /= snapshot_name + "-1" + statefile_suffix;
833 // only create a backup once
834 if (sys::exists (backup_path)) {
838 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
839 xmlpath.to_string(), backup_path.to_string())
844 sys::copy_file (xmlpath, backup_path);
846 catch(sys::filesystem_error& ex)
848 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
849 xmlpath.to_string(), ex.what())
859 Session::load_options (const XMLNode& node)
863 LocaleGuard lg (X_("POSIX"));
865 Config->set_variables (node, ConfigVariableBase::Session);
867 /* now reset MIDI ports because the session can have its own
873 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
874 if ((prop = child->property ("val")) != 0) {
875 _end_location_is_free = (prop->value() == "yes");
883 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
885 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
886 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
888 return owner & modified_by_session_or_user;
892 Session::get_options () const
895 LocaleGuard lg (X_("POSIX"));
897 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
899 child = option_root.add_child ("end-marker-is-free");
900 child->add_property ("val", _end_location_is_free ? "yes" : "no");
912 Session::get_template()
914 /* if we don't disable rec-enable, diskstreams
915 will believe they need to store their capture
916 sources in their state node.
919 disable_record (false);
925 Session::state(bool full_state)
927 XMLNode* node = new XMLNode("Session");
930 // store libardour version, just in case
932 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
933 node->add_property("version", string(buf));
935 /* store configuration settings */
939 node->add_property ("name", _name);
940 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
941 node->add_property ("sample-rate", buf);
943 if (session_dirs.size() > 1) {
947 vector<space_and_path>::iterator i = session_dirs.begin();
948 vector<space_and_path>::iterator next;
950 ++i; /* skip the first one */
954 while (i != session_dirs.end()) {
958 if (next != session_dirs.end()) {
968 child = node->add_child ("Path");
969 child->add_content (p);
973 /* save the ID counter */
975 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
976 node->add_property ("id-counter", buf);
978 /* various options */
980 node->add_child_nocopy (get_options());
982 node->add_child_nocopy (_metadata->get_state());
984 child = node->add_child ("Sources");
987 Glib::Mutex::Lock sl (source_lock);
989 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
991 /* Don't save information about non-destructive file sources that are empty */
992 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
994 boost::shared_ptr<AudioFileSource> fs;
995 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
996 if (!fs->destructive()) {
997 if (fs->length(fs->timeline_position()) == 0) {
1003 child->add_child_nocopy (siter->second->get_state());
1007 child = node->add_child ("Regions");
1010 Glib::Mutex::Lock rl (region_lock);
1012 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
1014 /* only store regions not attached to playlists */
1016 if (i->second->playlist() == 0) {
1017 child->add_child_nocopy (i->second->state (true));
1022 child = node->add_child ("DiskStreams");
1025 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1026 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1027 if (!(*i)->hidden()) {
1028 child->add_child_nocopy ((*i)->get_state());
1034 node->add_child_nocopy (_locations.get_state());
1036 // for a template, just create a new Locations, populate it
1037 // with the default start and end, and get the state for that.
1039 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1040 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1043 end->set_end(compute_initial_length());
1045 node->add_child_nocopy (loc.get_state());
1048 child = node->add_child ("Bundles");
1050 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1051 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1052 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1054 child->add_child_nocopy (b->get_state());
1059 child = node->add_child ("Routes");
1061 boost::shared_ptr<RouteList> r = routes.reader ();
1063 RoutePublicOrderSorter cmp;
1064 RouteList public_order (*r);
1065 public_order.sort (cmp);
1067 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1068 if (!(*i)->is_hidden()) {
1070 child->add_child_nocopy ((*i)->get_state());
1072 child->add_child_nocopy ((*i)->get_template());
1079 child = node->add_child ("EditGroups");
1080 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1081 child->add_child_nocopy ((*i)->get_state());
1084 child = node->add_child ("MixGroups");
1085 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1086 child->add_child_nocopy ((*i)->get_state());
1089 child = node->add_child ("Playlists");
1090 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1091 if (!(*i)->hidden()) {
1092 if (!(*i)->empty()) {
1094 child->add_child_nocopy ((*i)->get_state());
1096 child->add_child_nocopy ((*i)->get_template());
1102 child = node->add_child ("UnusedPlaylists");
1103 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1104 if (!(*i)->hidden()) {
1105 if (!(*i)->empty()) {
1107 child->add_child_nocopy ((*i)->get_state());
1109 child->add_child_nocopy ((*i)->get_template());
1117 child = node->add_child ("Click");
1118 child->add_child_nocopy (_click_io->state (full_state));
1122 child = node->add_child ("NamedSelections");
1123 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1125 child->add_child_nocopy ((*i)->get_state());
1130 node->add_child_nocopy (_tempo_map->get_state());
1132 node->add_child_nocopy (get_control_protocol_state());
1135 node->add_child_copy (*_extra_xml);
1142 Session::get_control_protocol_state ()
1144 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1145 return cpm.get_state();
1149 Session::set_state (const XMLNode& node)
1153 const XMLProperty* prop;
1156 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1158 if (node.name() != X_("Session")){
1159 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1163 if ((prop = node.property ("name")) != 0) {
1164 _name = prop->value ();
1167 if ((prop = node.property (X_("sample-rate"))) != 0) {
1169 _nominal_frame_rate = atoi (prop->value());
1171 if (_nominal_frame_rate != _current_frame_rate) {
1172 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1178 setup_raid_path(_session_dir->root_path().to_string());
1180 if ((prop = node.property (X_("id-counter"))) != 0) {
1182 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1183 ID::init_counter (x);
1185 /* old sessions used a timebased counter, so fake
1186 the startup ID counter based on a standard
1191 ID::init_counter (now);
1195 IO::disable_ports ();
1196 IO::disable_connecting ();
1198 /* Object loading order:
1203 MIDI Control // relies on data from Options/Config
1217 if ((child = find_named_node (node, "Extra")) != 0) {
1218 _extra_xml = new XMLNode (*child);
1221 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1222 load_options (*child);
1223 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1224 load_options (*child);
1226 error << _("Session: XML state has no options section") << endmsg;
1229 if (use_config_midi_ports ()) {
1232 if ((child = find_named_node (node, "Metadata")) == 0) {
1233 warning << _("Session: XML state has no metadata section (2.0 session?)") << endmsg;
1234 } else if (_metadata->set_state (*child)) {
1238 if ((child = find_named_node (node, "Locations")) == 0) {
1239 error << _("Session: XML state has no locations section") << endmsg;
1241 } else if (_locations.set_state (*child)) {
1247 if ((location = _locations.auto_loop_location()) != 0) {
1248 set_auto_loop_location (location);
1251 if ((location = _locations.auto_punch_location()) != 0) {
1252 set_auto_punch_location (location);
1255 if ((location = _locations.end_location()) == 0) {
1256 _locations.add (end_location);
1258 delete end_location;
1259 end_location = location;
1262 if ((location = _locations.start_location()) == 0) {
1263 _locations.add (start_location);
1265 delete start_location;
1266 start_location = location;
1269 AudioFileSource::set_header_position_offset (start_location->start());
1271 if ((child = find_named_node (node, "Sources")) == 0) {
1272 error << _("Session: XML state has no sources section") << endmsg;
1274 } else if (load_sources (*child)) {
1278 if ((child = find_named_node (node, "Regions")) == 0) {
1279 error << _("Session: XML state has no Regions section") << endmsg;
1281 } else if (load_regions (*child)) {
1285 if ((child = find_named_node (node, "Playlists")) == 0) {
1286 error << _("Session: XML state has no playlists section") << endmsg;
1288 } else if (load_playlists (*child)) {
1292 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1294 } else if (load_unused_playlists (*child)) {
1298 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1299 if (load_named_selections (*child)) {
1304 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1305 error << _("Session: XML state has no diskstreams section") << endmsg;
1307 } else if (load_diskstreams (*child)) {
1311 if ((child = find_named_node (node, "Bundles")) == 0) {
1312 warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg;
1315 /* We can't load Bundles yet as they need to be able
1316 to convert from port names to Port objects, which can't happen until
1318 _bundle_xml_node = new XMLNode (*child);
1321 if ((child = find_named_node (node, "EditGroups")) == 0) {
1322 error << _("Session: XML state has no edit groups section") << endmsg;
1324 } else if (load_edit_groups (*child)) {
1328 if ((child = find_named_node (node, "MixGroups")) == 0) {
1329 error << _("Session: XML state has no mix groups section") << endmsg;
1331 } else if (load_mix_groups (*child)) {
1335 if ((child = find_named_node (node, "TempoMap")) == 0) {
1336 error << _("Session: XML state has no Tempo Map section") << endmsg;
1338 } else if (_tempo_map->set_state (*child)) {
1342 if ((child = find_named_node (node, "Routes")) == 0) {
1343 error << _("Session: XML state has no routes section") << endmsg;
1345 } else if (load_routes (*child)) {
1349 if ((child = find_named_node (node, "Click")) == 0) {
1350 warning << _("Session: XML state has no click section") << endmsg;
1351 } else if (_click_io) {
1352 _click_io->set_state (*child);
1355 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1356 ControlProtocolManager::instance().set_protocol_states (*child);
1359 /* here beginneth the second phase ... */
1361 StateReady (); /* EMIT SIGNAL */
1370 Session::load_routes (const XMLNode& node)
1373 XMLNodeConstIterator niter;
1374 RouteList new_routes;
1376 nlist = node.children();
1380 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1382 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1385 error << _("Session: cannot create Route from XML description.") << endmsg;
1389 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1391 new_routes.push_back (route);
1394 add_routes (new_routes, false);
1399 boost::shared_ptr<Route>
1400 Session::XMLRouteFactory (const XMLNode& node)
1402 if (node.name() != "Route") {
1403 return boost::shared_ptr<Route> ((Route*) 0);
1406 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1408 DataType type = DataType::AUDIO;
1409 const XMLProperty* prop = node.property("default-type");
1412 type = DataType(prop->value());
1415 assert(type != DataType::NIL);
1417 if (has_diskstream) {
1418 if (type == DataType::AUDIO) {
1419 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1422 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1426 boost::shared_ptr<Route> ret (new Route (*this, node));
1432 Session::load_regions (const XMLNode& node)
1435 XMLNodeConstIterator niter;
1436 boost::shared_ptr<Region> region;
1438 nlist = node.children();
1442 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1443 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1444 error << _("Session: cannot create Region from XML description.");
1445 const XMLProperty *name = (**niter).property("name");
1448 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1458 boost::shared_ptr<Region>
1459 Session::XMLRegionFactory (const XMLNode& node, bool full)
1461 const XMLProperty* type = node.property("type");
1465 if ( !type || type->value() == "audio" ) {
1467 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1469 } else if (type->value() == "midi") {
1471 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1475 } catch (failed_constructor& err) {
1476 return boost::shared_ptr<Region> ();
1479 return boost::shared_ptr<Region> ();
1482 boost::shared_ptr<AudioRegion>
1483 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1485 const XMLProperty* prop;
1486 boost::shared_ptr<Source> source;
1487 boost::shared_ptr<AudioSource> as;
1489 SourceList master_sources;
1490 uint32_t nchans = 1;
1493 if (node.name() != X_("Region")) {
1494 return boost::shared_ptr<AudioRegion>();
1497 if ((prop = node.property (X_("channels"))) != 0) {
1498 nchans = atoi (prop->value().c_str());
1501 if ((prop = node.property ("name")) == 0) {
1502 cerr << "no name for this region\n";
1506 if ((prop = node.property (X_("source-0"))) == 0) {
1507 if ((prop = node.property ("source")) == 0) {
1508 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1509 return boost::shared_ptr<AudioRegion>();
1513 PBD::ID s_id (prop->value());
1515 if ((source = source_by_id (s_id)) == 0) {
1516 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1517 return boost::shared_ptr<AudioRegion>();
1520 as = boost::dynamic_pointer_cast<AudioSource>(source);
1522 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1523 return boost::shared_ptr<AudioRegion>();
1526 sources.push_back (as);
1528 /* pickup other channels */
1530 for (uint32_t n=1; n < nchans; ++n) {
1531 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1532 if ((prop = node.property (buf)) != 0) {
1534 PBD::ID id2 (prop->value());
1536 if ((source = source_by_id (id2)) == 0) {
1537 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1538 return boost::shared_ptr<AudioRegion>();
1541 as = boost::dynamic_pointer_cast<AudioSource>(source);
1543 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1544 return boost::shared_ptr<AudioRegion>();
1546 sources.push_back (as);
1550 for (uint32_t n=1; n < nchans; ++n) {
1551 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1552 if ((prop = node.property (buf)) != 0) {
1554 PBD::ID id2 (prop->value());
1556 if ((source = source_by_id (id2)) == 0) {
1557 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1558 return boost::shared_ptr<AudioRegion>();
1561 as = boost::dynamic_pointer_cast<AudioSource>(source);
1563 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1564 return boost::shared_ptr<AudioRegion>();
1566 master_sources.push_back (as);
1571 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1573 /* a final detail: this is the one and only place that we know how long missing files are */
1575 if (region->whole_file()) {
1576 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1577 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1579 sfp->set_length (region->length());
1584 if (!master_sources.empty()) {
1585 if (master_sources.size() == nchans) {
1586 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1588 region->set_master_sources (master_sources);
1596 catch (failed_constructor& err) {
1597 return boost::shared_ptr<AudioRegion>();
1601 boost::shared_ptr<MidiRegion>
1602 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1604 const XMLProperty* prop;
1605 boost::shared_ptr<Source> source;
1606 boost::shared_ptr<MidiSource> ms;
1608 uint32_t nchans = 1;
1610 if (node.name() != X_("Region")) {
1611 return boost::shared_ptr<MidiRegion>();
1614 if ((prop = node.property (X_("channels"))) != 0) {
1615 nchans = atoi (prop->value().c_str());
1618 if ((prop = node.property ("name")) == 0) {
1619 cerr << "no name for this region\n";
1623 // Multiple midi channels? that's just crazy talk
1624 assert(nchans == 1);
1626 if ((prop = node.property (X_("source-0"))) == 0) {
1627 if ((prop = node.property ("source")) == 0) {
1628 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1629 return boost::shared_ptr<MidiRegion>();
1633 PBD::ID s_id (prop->value());
1635 if ((source = source_by_id (s_id)) == 0) {
1636 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1637 return boost::shared_ptr<MidiRegion>();
1640 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1642 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1643 return boost::shared_ptr<MidiRegion>();
1646 sources.push_back (ms);
1649 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1650 /* a final detail: this is the one and only place that we know how long missing files are */
1652 if (region->whole_file()) {
1653 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1654 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1656 sfp->set_length (region->length());
1664 catch (failed_constructor& err) {
1665 return boost::shared_ptr<MidiRegion>();
1670 Session::get_sources_as_xml ()
1673 XMLNode* node = new XMLNode (X_("Sources"));
1674 Glib::Mutex::Lock lm (source_lock);
1676 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1677 node->add_child_nocopy (i->second->get_state());
1684 Session::path_from_region_name (DataType type, string name, string identifier)
1686 char buf[PATH_MAX+1];
1688 SessionDirectory sdir(get_best_session_directory_for_new_source());
1689 sys::path source_dir = ((type == DataType::AUDIO)
1690 ? sdir.sound_path() : sdir.midi_path());
1692 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1694 for (n = 0; n < 999999; ++n) {
1695 if (identifier.length()) {
1696 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1697 identifier.c_str(), n, ext.c_str());
1699 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1703 sys::path source_path = source_dir / buf;
1705 if (!sys::exists (source_path)) {
1706 return source_path.to_string();
1710 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1719 Session::load_sources (const XMLNode& node)
1722 XMLNodeConstIterator niter;
1723 boost::shared_ptr<Source> source;
1725 nlist = node.children();
1729 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1731 if ((source = XMLSourceFactory (**niter)) == 0) {
1732 error << _("Session: cannot create Source from XML description.") << endmsg;
1734 } catch (MissingSource& err) {
1735 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1736 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1743 boost::shared_ptr<Source>
1744 Session::XMLSourceFactory (const XMLNode& node)
1746 if (node.name() != "Source") {
1747 return boost::shared_ptr<Source>();
1751 /* note: do peak building in another thread when loading session state */
1752 return SourceFactory::create (*this, node, true);
1755 catch (failed_constructor& err) {
1756 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1757 return boost::shared_ptr<Source>();
1762 Session::save_template (string template_name)
1766 if (_state_of_the_state & CannotSave) {
1770 sys::path user_template_dir(user_template_directory());
1774 sys::create_directories (user_template_dir);
1776 catch(sys::filesystem_error& ex)
1778 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1779 user_template_dir.to_string(), ex.what()) << endmsg;
1783 tree.set_root (&get_template());
1785 sys::path template_file_path(user_template_dir);
1786 template_file_path /= template_name + template_suffix;
1788 if (sys::exists (template_file_path))
1790 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1791 template_file_path.to_string()) << endmsg;
1795 if (!tree.write (template_file_path.to_string())) {
1796 error << _("mix template not saved") << endmsg;
1804 Session::rename_template (string old_name, string new_name)
1806 sys::path old_path (user_template_directory());
1807 old_path /= old_name + template_suffix;
1809 sys::path new_path(user_template_directory());
1810 new_path /= new_name + template_suffix;
1812 if (sys::exists (new_path)) {
1813 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1814 new_path.to_string()) << endmsg;
1819 sys::rename (old_path, new_path);
1827 Session::delete_template (string name)
1829 sys::path path = user_template_directory();
1830 path /= name + template_suffix;
1841 Session::refresh_disk_space ()
1844 struct statfs statfsbuf;
1845 vector<space_and_path>::iterator i;
1846 Glib::Mutex::Lock lm (space_lock);
1849 /* get freespace on every FS that is part of the session path */
1851 _total_free_4k_blocks = 0;
1853 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1854 statfs ((*i).path.c_str(), &statfsbuf);
1856 scale = statfsbuf.f_bsize/4096.0;
1858 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1859 _total_free_4k_blocks += (*i).blocks;
1865 Session::get_best_session_directory_for_new_source ()
1867 vector<space_and_path>::iterator i;
1868 string result = _session_dir->root_path().to_string();
1870 /* handle common case without system calls */
1872 if (session_dirs.size() == 1) {
1876 /* OK, here's the algorithm we're following here:
1878 We want to select which directory to use for
1879 the next file source to be created. Ideally,
1880 we'd like to use a round-robin process so as to
1881 get maximum performance benefits from splitting
1882 the files across multiple disks.
1884 However, in situations without much diskspace, an
1885 RR approach may end up filling up a filesystem
1886 with new files while others still have space.
1887 Its therefore important to pay some attention to
1888 the freespace in the filesystem holding each
1889 directory as well. However, if we did that by
1890 itself, we'd keep creating new files in the file
1891 system with the most space until it was as full
1892 as all others, thus negating any performance
1893 benefits of this RAID-1 like approach.
1895 So, we use a user-configurable space threshold. If
1896 there are at least 2 filesystems with more than this
1897 much space available, we use RR selection between them.
1898 If not, then we pick the filesystem with the most space.
1900 This gets a good balance between the two
1904 refresh_disk_space ();
1906 int free_enough = 0;
1908 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1909 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1914 if (free_enough >= 2) {
1915 /* use RR selection process, ensuring that the one
1919 i = last_rr_session_dir;
1922 if (++i == session_dirs.end()) {
1923 i = session_dirs.begin();
1926 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1927 if (create_session_directory ((*i).path)) {
1929 last_rr_session_dir = i;
1934 } while (i != last_rr_session_dir);
1938 /* pick FS with the most freespace (and that
1939 seems to actually work ...)
1942 vector<space_and_path> sorted;
1943 space_and_path_ascending_cmp cmp;
1945 sorted = session_dirs;
1946 sort (sorted.begin(), sorted.end(), cmp);
1948 for (i = sorted.begin(); i != sorted.end(); ++i) {
1949 if (create_session_directory ((*i).path)) {
1951 last_rr_session_dir = i;
1961 Session::load_playlists (const XMLNode& node)
1964 XMLNodeConstIterator niter;
1965 boost::shared_ptr<Playlist> playlist;
1967 nlist = node.children();
1971 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1973 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1974 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1982 Session::load_unused_playlists (const XMLNode& node)
1985 XMLNodeConstIterator niter;
1986 boost::shared_ptr<Playlist> playlist;
1988 nlist = node.children();
1992 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1994 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1995 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1999 // now manually untrack it
2001 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
2007 boost::shared_ptr<Playlist>
2008 Session::XMLPlaylistFactory (const XMLNode& node)
2011 return PlaylistFactory::create (*this, node);
2014 catch (failed_constructor& err) {
2015 return boost::shared_ptr<Playlist>();
2020 Session::load_named_selections (const XMLNode& node)
2023 XMLNodeConstIterator niter;
2026 nlist = node.children();
2030 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2032 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2033 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2041 Session::XMLNamedSelectionFactory (const XMLNode& node)
2044 return new NamedSelection (*this, node);
2047 catch (failed_constructor& err) {
2053 Session::automation_dir () const
2055 return Glib::build_filename (_path, "automation");
2059 Session::analysis_dir () const
2061 return Glib::build_filename (_path, "analysis");
2065 Session::load_bundles (XMLNode const & node)
2067 XMLNodeList nlist = node.children();
2068 XMLNodeConstIterator niter;
2072 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2073 if ((*niter)->name() == "InputBundle") {
2074 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2075 } else if ((*niter)->name() == "OutputBundle") {
2076 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2078 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2087 Session::load_edit_groups (const XMLNode& node)
2089 return load_route_groups (node, true);
2093 Session::load_mix_groups (const XMLNode& node)
2095 return load_route_groups (node, false);
2099 Session::load_route_groups (const XMLNode& node, bool edit)
2101 XMLNodeList nlist = node.children();
2102 XMLNodeConstIterator niter;
2107 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2108 if ((*niter)->name() == "RouteGroup") {
2110 rg = add_edit_group ("");
2111 rg->set_state (**niter);
2113 rg = add_mix_group ("");
2114 rg->set_state (**niter);
2123 Session::auto_save()
2125 save_state (_current_snapshot_name);
2129 state_file_filter (const string &str, void *arg)
2131 return (str.length() > strlen(statefile_suffix) &&
2132 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2136 bool operator()(const string* a, const string* b) {
2142 remove_end(string* state)
2144 string statename(*state);
2146 string::size_type start,end;
2147 if ((start = statename.find_last_of ('/')) != string::npos) {
2148 statename = statename.substr (start+1);
2151 if ((end = statename.rfind(".ardour")) == string::npos) {
2152 end = statename.length();
2155 return new string(statename.substr (0, end));
2159 Session::possible_states (string path)
2161 PathScanner scanner;
2162 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2164 transform(states->begin(), states->end(), states->begin(), remove_end);
2167 sort (states->begin(), states->end(), cmp);
2173 Session::possible_states () const
2175 return possible_states(_path);
2179 Session::add_edit_group (string name)
2181 RouteGroup* rg = new RouteGroup (*this, name);
2182 edit_groups.push_back (rg);
2183 edit_group_added (rg); /* EMIT SIGNAL */
2189 Session::add_mix_group (string name)
2191 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2192 mix_groups.push_back (rg);
2193 mix_group_added (rg); /* EMIT SIGNAL */
2199 Session::remove_edit_group (RouteGroup& rg)
2201 list<RouteGroup*>::iterator i;
2203 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2204 (*i)->apply (&Route::drop_edit_group, this);
2205 edit_groups.erase (i);
2206 edit_group_removed (); /* EMIT SIGNAL */
2213 Session::remove_mix_group (RouteGroup& rg)
2215 list<RouteGroup*>::iterator i;
2217 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2218 (*i)->apply (&Route::drop_mix_group, this);
2219 mix_groups.erase (i);
2220 mix_group_removed (); /* EMIT SIGNAL */
2227 Session::mix_group_by_name (string name)
2229 list<RouteGroup *>::iterator i;
2231 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2232 if ((*i)->name() == name) {
2240 Session::edit_group_by_name (string name)
2242 list<RouteGroup *>::iterator i;
2244 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2245 if ((*i)->name() == name) {
2253 Session::begin_reversible_command(const string& name)
2255 UndoTransaction* trans = new UndoTransaction();
2256 trans->set_name(name);
2257 if (!_current_trans.empty()) {
2258 _current_trans.top()->add_command(trans);
2260 _current_trans.push(trans);
2264 Session::commit_reversible_command(Command *cmd)
2266 assert(!_current_trans.empty());
2270 _current_trans.top()->add_command(cmd);
2273 if (_current_trans.top()->empty()) {
2274 _current_trans.pop();
2278 gettimeofday(&now, 0);
2279 _current_trans.top()->set_timestamp(now);
2281 _history.add(_current_trans.top());
2282 _current_trans.pop();
2285 Session::GlobalRouteBooleanState
2286 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2288 GlobalRouteBooleanState s;
2289 boost::shared_ptr<RouteList> r = routes.reader ();
2291 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2292 if (!(*i)->is_hidden()) {
2293 RouteBooleanState v;
2296 Route* r = (*i).get();
2297 v.second = (r->*method)();
2306 Session::GlobalRouteMeterState
2307 Session::get_global_route_metering ()
2309 GlobalRouteMeterState s;
2310 boost::shared_ptr<RouteList> r = routes.reader ();
2312 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2313 if (!(*i)->is_hidden()) {
2317 v.second = (*i)->meter_point();
2327 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2329 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2331 boost::shared_ptr<Route> r = (i->first.lock());
2334 r->set_meter_point (i->second, arg);
2340 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2342 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2344 boost::shared_ptr<Route> r = (i->first.lock());
2347 Route* rp = r.get();
2348 (rp->*method) (i->second, arg);
2354 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2356 set_global_route_boolean (s, &Route::set_mute, src);
2360 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2362 set_global_route_boolean (s, &Route::set_solo, src);
2366 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2368 set_global_route_boolean (s, &Route::set_record_enable, src);
2372 accept_all_non_peak_files (const string& path, void *arg)
2374 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2378 accept_all_state_files (const string& path, void *arg)
2380 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2384 Session::find_all_sources (string path, set<string>& result)
2389 if (!tree.read (path)) {
2393 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2398 XMLNodeConstIterator niter;
2400 nlist = node->children();
2404 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2408 if ((prop = (*niter)->property (X_("name"))) == 0) {
2412 if (prop->value()[0] == '/') {
2413 /* external file, ignore */
2417 sys::path source_path = _session_dir->sound_path ();
2419 source_path /= prop->value ();
2421 result.insert (source_path.to_string ());
2428 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2430 PathScanner scanner;
2431 vector<string*>* state_files;
2433 string this_snapshot_path;
2439 if (ripped[ripped.length()-1] == '/') {
2440 ripped = ripped.substr (0, ripped.length() - 1);
2443 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2445 if (state_files == 0) {
2450 this_snapshot_path = _path;
2451 this_snapshot_path += _current_snapshot_name;
2452 this_snapshot_path += statefile_suffix;
2454 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2456 if (exclude_this_snapshot && **i == this_snapshot_path) {
2460 if (find_all_sources (**i, result) < 0) {
2468 struct RegionCounter {
2469 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2470 AudioSourceList::iterator iter;
2471 boost::shared_ptr<Region> region;
2474 RegionCounter() : count (0) {}
2478 Session::cleanup_sources (Session::cleanup_report& rep)
2480 // FIXME: needs adaptation to midi
2482 vector<boost::shared_ptr<Source> > dead_sources;
2483 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2484 PathScanner scanner;
2486 vector<space_and_path>::iterator i;
2487 vector<space_and_path>::iterator nexti;
2488 vector<string*>* soundfiles;
2489 vector<string> unused;
2490 set<string> all_sources;
2495 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2498 /* step 1: consider deleting all unused playlists */
2500 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2503 status = AskAboutPlaylistDeletion (*x);
2512 playlists_tbd.push_back (*x);
2516 /* leave it alone */
2521 /* now delete any that were marked for deletion */
2523 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2524 (*x)->drop_references ();
2527 playlists_tbd.clear ();
2529 /* step 2: find all un-used sources */
2534 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2536 SourceMap::iterator tmp;
2541 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2545 if (!i->second->used() && i->second->length(i->second->timeline_position()) > 0) {
2546 dead_sources.push_back (i->second);
2547 i->second->GoingAway();
2553 /* build a list of all the possible sound directories for the session */
2555 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2560 SessionDirectory sdir ((*i).path);
2561 sound_path += sdir.sound_path().to_string();
2563 if (nexti != session_dirs.end()) {
2570 /* now do the same thing for the files that ended up in the sounds dir(s)
2571 but are not referenced as sources in any snapshot.
2574 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2576 if (soundfiles == 0) {
2580 /* find all sources, but don't use this snapshot because the
2581 state file on disk still references sources we may have already
2585 find_all_sources_across_snapshots (all_sources, true);
2587 /* add our current source list
2590 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2591 boost::shared_ptr<FileSource> fs;
2593 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2594 all_sources.insert (fs->path());
2598 char tmppath1[PATH_MAX+1];
2599 char tmppath2[PATH_MAX+1];
2601 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2606 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2608 realpath(spath.c_str(), tmppath1);
2609 realpath((*i).c_str(), tmppath2);
2611 if (strcmp(tmppath1, tmppath2) == 0) {
2618 unused.push_back (spath);
2622 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2624 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2625 struct stat statbuf;
2627 rep.paths.push_back (*x);
2628 if (stat ((*x).c_str(), &statbuf) == 0) {
2629 rep.space += statbuf.st_size;
2634 /* don't move the file across filesystems, just
2635 stick it in the `dead_sound_dir_name' directory
2636 on whichever filesystem it was already on.
2639 if ((*x).find ("/sounds/") != string::npos) {
2641 /* old school, go up 1 level */
2643 newpath = Glib::path_get_dirname (*x); // "sounds"
2644 newpath = Glib::path_get_dirname (newpath); // "session-name"
2648 /* new school, go up 4 levels */
2650 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2651 newpath = Glib::path_get_dirname (newpath); // "session-name"
2652 newpath = Glib::path_get_dirname (newpath); // "interchange"
2653 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2657 newpath += dead_sound_dir_name;
2659 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2660 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2665 newpath += Glib::path_get_basename ((*x));
2667 if (access (newpath.c_str(), F_OK) == 0) {
2669 /* the new path already exists, try versioning */
2671 char buf[PATH_MAX+1];
2675 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2678 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2679 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2683 if (version == 999) {
2684 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2688 newpath = newpath_v;
2693 /* it doesn't exist, or we can't read it or something */
2697 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2698 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2699 (*x), newpath, strerror (errno))
2704 /* see if there an easy to find peakfile for this file, and remove it.
2707 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2708 peakpath += peakfile_suffix;
2710 if (access (peakpath.c_str(), W_OK) == 0) {
2711 if (::unlink (peakpath.c_str()) != 0) {
2712 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2713 peakpath, _path, strerror (errno))
2715 /* try to back out */
2716 rename (newpath.c_str(), _path.c_str());
2724 /* dump the history list */
2728 /* save state so we don't end up a session file
2729 referring to non-existent sources.
2735 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2741 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2743 // FIXME: needs adaptation for MIDI
2745 vector<space_and_path>::iterator i;
2746 string dead_sound_dir;
2747 struct dirent* dentry;
2748 struct stat statbuf;
2754 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2756 dead_sound_dir = (*i).path;
2757 dead_sound_dir += dead_sound_dir_name;
2759 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2763 while ((dentry = readdir (dead)) != 0) {
2765 /* avoid '.' and '..' */
2767 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2768 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2774 fullpath = dead_sound_dir;
2776 fullpath += dentry->d_name;
2778 if (stat (fullpath.c_str(), &statbuf)) {
2782 if (!S_ISREG (statbuf.st_mode)) {
2786 if (unlink (fullpath.c_str())) {
2787 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2788 fullpath, strerror (errno))
2792 rep.paths.push_back (dentry->d_name);
2793 rep.space += statbuf.st_size;
2804 Session::set_dirty ()
2806 bool was_dirty = dirty();
2808 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2812 DirtyChanged(); /* EMIT SIGNAL */
2818 Session::set_clean ()
2820 bool was_dirty = dirty();
2822 _state_of_the_state = Clean;
2826 DirtyChanged(); /* EMIT SIGNAL */
2831 Session::set_deletion_in_progress ()
2833 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2838 Session::add_controllable (boost::shared_ptr<Controllable> c)
2840 /* this adds a controllable to the list managed by the Session.
2841 this is a subset of those managed by the Controllable class
2842 itself, and represents the only ones whose state will be saved
2843 as part of the session.
2846 Glib::Mutex::Lock lm (controllables_lock);
2847 controllables.insert (c);
2850 struct null_deleter { void operator()(void const *) const {} };
2853 Session::remove_controllable (Controllable* c)
2855 if (_state_of_the_state | Deletion) {
2859 Glib::Mutex::Lock lm (controllables_lock);
2861 Controllables::iterator x = controllables.find(
2862 boost::shared_ptr<Controllable>(c, null_deleter()));
2864 if (x != controllables.end()) {
2865 controllables.erase (x);
2869 boost::shared_ptr<Controllable>
2870 Session::controllable_by_id (const PBD::ID& id)
2872 Glib::Mutex::Lock lm (controllables_lock);
2874 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2875 if ((*i)->id() == id) {
2880 return boost::shared_ptr<Controllable>();
2884 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2886 Stateful::add_instant_xml (node, _path);
2887 if (write_to_config) {
2888 Config->add_instant_xml (node);
2893 Session::instant_xml (const string& node_name)
2895 return Stateful::instant_xml (node_name, _path);
2899 Session::save_history (string snapshot_name)
2903 if (snapshot_name.empty()) {
2904 snapshot_name = _current_snapshot_name;
2907 const string history_filename = snapshot_name + history_suffix;
2908 const string backup_filename = history_filename + backup_suffix;
2909 const sys::path xml_path = _session_dir->root_path() / history_filename;
2910 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2912 if (sys::exists (xml_path)) {
2915 sys::rename (xml_path, backup_path);
2917 catch (const sys::filesystem_error& err)
2919 error << _("could not backup old history file, current history not saved") << endmsg;
2925 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2929 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2931 if (!tree.write (xml_path.to_string()))
2933 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2937 sys::remove (xml_path);
2938 sys::rename (backup_path, xml_path);
2940 catch (const sys::filesystem_error& err)
2942 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2943 backup_path.to_string(), err.what()) << endmsg;
2953 Session::restore_history (string snapshot_name)
2957 if (snapshot_name.empty()) {
2958 snapshot_name = _current_snapshot_name;
2961 const string xml_filename = snapshot_name + history_suffix;
2962 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2964 cerr << "Loading history from " << xml_path.to_string() << endmsg;
2966 if (!sys::exists (xml_path)) {
2967 info << string_compose (_("%1: no history file \"%2\" for this session."),
2968 _name, xml_path.to_string()) << endmsg;
2972 if (!tree.read (xml_path.to_string())) {
2973 error << string_compose (_("Could not understand session history file \"%1\""),
2974 xml_path.to_string()) << endmsg;
2981 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2984 UndoTransaction* ut = new UndoTransaction ();
2987 ut->set_name(t->property("name")->value());
2988 stringstream ss(t->property("tv-sec")->value());
2990 ss.str(t->property("tv-usec")->value());
2992 ut->set_timestamp(tv);
2994 for (XMLNodeConstIterator child_it = t->children().begin();
2995 child_it != t->children().end(); child_it++)
2997 XMLNode *n = *child_it;
3000 if (n->name() == "MementoCommand" ||
3001 n->name() == "MementoUndoCommand" ||
3002 n->name() == "MementoRedoCommand") {
3004 if ((c = memento_command_factory(n))) {
3008 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3010 if ((c = global_state_command_factory (*n))) {
3011 ut->add_command (c);
3014 } else if (n->name() == "DeltaCommand") {
3015 PBD::ID id(n->property("midi-source")->value());
3016 boost::shared_ptr<MidiSource> midi_source =
3017 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3019 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
3021 error << "FIXME: Failed to downcast MidiSource for DeltaCommand" << endmsg;
3024 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3035 Session::config_changed (const char* parameter_name)
3037 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3039 if (PARAM_IS ("seamless-loop")) {
3041 } else if (PARAM_IS ("rf-speed")) {
3043 } else if (PARAM_IS ("auto-loop")) {
3045 } else if (PARAM_IS ("auto-input")) {
3047 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3048 /* auto-input only makes a difference if we're rolling */
3050 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3052 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3053 if ((*i)->record_enabled ()) {
3054 (*i)->monitor_input (!Config->get_auto_input());
3059 } else if (PARAM_IS ("punch-in")) {
3063 if ((location = _locations.auto_punch_location()) != 0) {
3065 if (Config->get_punch_in ()) {
3066 replace_event (Event::PunchIn, location->start());
3068 remove_event (location->start(), Event::PunchIn);
3072 } else if (PARAM_IS ("punch-out")) {
3076 if ((location = _locations.auto_punch_location()) != 0) {
3078 if (Config->get_punch_out()) {
3079 replace_event (Event::PunchOut, location->end());
3081 clear_events (Event::PunchOut);
3085 } else if (PARAM_IS ("edit-mode")) {
3087 Glib::Mutex::Lock lm (playlist_lock);
3089 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3090 (*i)->set_edit_mode (Config->get_edit_mode ());
3093 } else if (PARAM_IS ("use-video-sync")) {
3095 waiting_for_sync_offset = Config->get_use_video_sync();
3097 } else if (PARAM_IS ("mmc-control")) {
3099 //poke_midi_thread ();
3101 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
3104 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3107 } else if (PARAM_IS ("mmc-send-id")) {
3110 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3113 } else if (PARAM_IS ("midi-control")) {
3115 //poke_midi_thread ();
3117 } else if (PARAM_IS ("raid-path")) {
3119 setup_raid_path (Config->get_raid_path());
3121 } else if (PARAM_IS ("smpte-format")) {
3125 } else if (PARAM_IS ("video-pullup")) {
3129 } else if (PARAM_IS ("seamless-loop")) {
3131 if (play_loop && transport_rolling()) {
3132 // to reset diskstreams etc
3133 request_play_loop (true);
3136 } else if (PARAM_IS ("rf-speed")) {
3138 cumulative_rf_motion = 0;
3141 } else if (PARAM_IS ("click-sound")) {
3143 setup_click_sounds (1);
3145 } else if (PARAM_IS ("click-emphasis-sound")) {
3147 setup_click_sounds (-1);
3149 } else if (PARAM_IS ("clicking")) {
3151 if (Config->get_clicking()) {
3152 if (_click_io && click_data) { // don't require emphasis data
3159 } else if (PARAM_IS ("send-mtc")) {
3161 /* only set the internal flag if we have
3165 if (_mtc_port != 0) {
3166 session_send_mtc = Config->get_send_mtc();
3167 if (session_send_mtc) {
3168 /* mark us ready to send */
3169 next_quarter_frame_to_send = 0;
3172 session_send_mtc = false;
3175 } else if (PARAM_IS ("send-mmc")) {
3177 /* only set the internal flag if we have
3181 if (_mmc_port != 0) {
3182 session_send_mmc = Config->get_send_mmc();
3185 session_send_mmc = false;
3188 } else if (PARAM_IS ("midi-feedback")) {
3190 /* only set the internal flag if we have
3194 if (_mtc_port != 0) {
3195 session_midi_feedback = Config->get_midi_feedback();
3198 } else if (PARAM_IS ("jack-time-master")) {
3200 engine().reset_timebase ();
3202 } else if (PARAM_IS ("native-file-header-format")) {
3204 if (!first_file_header_format_reset) {
3205 reset_native_file_format ();
3208 first_file_header_format_reset = false;
3210 } else if (PARAM_IS ("native-file-data-format")) {
3212 if (!first_file_data_format_reset) {
3213 reset_native_file_format ();
3216 first_file_data_format_reset = false;
3218 } else if (PARAM_IS ("slave-source")) {
3219 set_slave_source (Config->get_slave_source());
3220 } else if (PARAM_IS ("remote-model")) {
3221 set_remote_control_ids ();
3222 } else if (PARAM_IS ("denormal-model")) {
3224 } else if (PARAM_IS ("history-depth")) {
3225 set_history_depth (Config->get_history_depth());
3226 } else if (PARAM_IS ("sync-all-route-ordering")) {
3227 sync_order_keys ("session");
3228 } else if (PARAM_IS ("initial-program-change")) {
3230 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3233 buf[0] = MIDI::program; // channel zero by default
3234 buf[1] = (Config->get_initial_program_change() & 0x7f);
3236 _mmc_port->midimsg (buf, sizeof (buf), 0);
3238 } else if (PARAM_IS ("initial-program-change")) {
3240 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3241 MIDI::byte* buf = new MIDI::byte[2];
3243 buf[0] = MIDI::program; // channel zero by default
3244 buf[1] = (Config->get_initial_program_change() & 0x7f);
3245 // deliver_midi (_mmc_port, buf, 2);
3247 } else if (PARAM_IS ("solo-mute-override")) {
3248 catch_up_on_solo_mute_override ();
3258 Session::set_history_depth (uint32_t d)
3260 _history.set_depth (d);