2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #define __STDC_FORMAT_MACROS 1
28 #include <sigc++/bind.h>
30 #include <cstdio> /* snprintf(3) ... grrr */
45 #include <sys/param.h>
46 #include <sys/mount.h>
50 #include <glibmm/thread.h>
52 #include <midi++/mmc.h>
53 #include <midi++/port.h>
55 #include <pbd/error.h>
56 #include <pbd/pathscanner.h>
57 #include <pbd/pthread_utils.h>
58 #include <pbd/search_path.h>
59 #include <pbd/stacktrace.h>
61 #include <ardour/audioengine.h>
62 #include <ardour/configuration.h>
63 #include <ardour/session.h>
64 #include <ardour/session_directory.h>
65 #include <ardour/session_utils.h>
66 #include <ardour/session_state_utils.h>
67 #include <ardour/session_metadata.h>
68 #include <ardour/buffer.h>
69 #include <ardour/audio_diskstream.h>
70 #include <ardour/midi_diskstream.h>
71 #include <ardour/utils.h>
72 #include <ardour/audioplaylist.h>
73 #include <ardour/midi_playlist.h>
74 #include <ardour/smf_source.h>
75 #include <ardour/audiofilesource.h>
76 #include <ardour/silentfilesource.h>
77 #include <ardour/sndfilesource.h>
78 #include <ardour/midi_source.h>
79 #include <ardour/sndfile_helpers.h>
80 #include <ardour/auditioner.h>
81 #include <ardour/io_processor.h>
82 #include <ardour/send.h>
83 #include <ardour/processor.h>
84 #include <ardour/bundle.h>
85 #include <ardour/slave.h>
86 #include <ardour/tempo.h>
87 #include <ardour/audio_track.h>
88 #include <ardour/midi_track.h>
89 #include <ardour/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>
107 #include <control_protocol/control_protocol.h>
113 using namespace ARDOUR;
117 Session::first_stage_init (string fullpath, string snapshot_name)
119 if (fullpath.length() == 0) {
121 throw failed_constructor();
124 char buf[PATH_MAX+1];
125 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
126 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
128 throw failed_constructor();
133 if (_path[_path.length()-1] != '/') {
137 /* these two are just provisional settings. set_state()
138 will likely override them.
141 _name = _current_snapshot_name = snapshot_name;
143 set_history_depth (Config->get_history_depth());
145 _current_frame_rate = _engine.frame_rate ();
146 _nominal_frame_rate = _current_frame_rate;
147 _base_frame_rate = _current_frame_rate;
149 _tempo_map = new TempoMap (_current_frame_rate);
150 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
154 g_atomic_int_set (&processing_prohibited, 0);
156 _transport_speed = 0;
157 _last_transport_speed = 0;
158 auto_play_legal = false;
159 transport_sub_state = 0;
160 _transport_frame = 0;
162 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
163 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
164 _end_location_is_free = true;
165 g_atomic_int_set (&_record_status, Disabled);
166 loop_changing = false;
168 _last_roll_location = 0;
169 _last_record_location = 0;
170 pending_locate_frame = 0;
171 pending_locate_roll = false;
172 pending_locate_flush = false;
173 audio_dstream_buffer_size = 0;
174 midi_dstream_buffer_size = 0;
176 state_was_pending = false;
178 outbound_mtc_smpte_frame = 0;
179 next_quarter_frame_to_send = -1;
180 current_block_size = 0;
181 solo_update_disabled = false;
182 currently_soloing = false;
183 _have_captured = false;
184 _worst_output_latency = 0;
185 _worst_input_latency = 0;
186 _worst_track_latency = 0;
187 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
190 butler_mixdown_buffer = 0;
191 butler_gain_buffer = 0;
193 session_send_mmc = false;
194 session_send_mtc = false;
195 post_transport_work = PostTransportWork (0);
196 g_atomic_int_set (&butler_should_do_transport_work, 0);
197 g_atomic_int_set (&_playback_load, 100);
198 g_atomic_int_set (&_capture_load, 100);
199 g_atomic_int_set (&_playback_load_min, 100);
200 g_atomic_int_set (&_capture_load_min, 100);
203 _exporting_realtime = false;
204 _gain_automation_buffer = 0;
205 _pan_automation_buffer = 0;
207 pending_abort = false;
208 destructive_index = 0;
210 first_file_data_format_reset = true;
211 first_file_header_format_reset = true;
212 butler_thread = (pthread_t) 0;
213 //midi_thread = (pthread_t) 0;
215 AudioDiskstream::allocate_working_buffers();
217 /* default short fade = 15ms */
219 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
220 SndFileSource::setup_standard_crossfades (frame_rate());
222 last_mmc_step.tv_sec = 0;
223 last_mmc_step.tv_usec = 0;
226 /* click sounds are unset by default, which causes us to internal
227 waveforms for clicks.
231 click_emphasis_data = 0;
233 click_emphasis_length = 0;
236 process_function = &Session::process_with_events;
238 if (Config->get_use_video_sync()) {
239 waiting_for_sync_offset = true;
241 waiting_for_sync_offset = false;
246 _smpte_offset_negative = true;
247 last_smpte_valid = false;
251 last_rr_session_dir = session_dirs.begin();
252 refresh_disk_space ();
254 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
258 average_slave_delta = 1800; // !!! why 1800 ????
259 have_first_delta_accumulator = false;
260 delta_accumulator_cnt = 0;
261 slave_state = Stopped;
263 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
265 /* These are all static "per-class" signals */
267 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
268 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
269 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
270 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
271 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
272 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
274 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
276 IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
278 /* stop IO objects from doing stuff until we're ready for them */
280 IO::disable_panners ();
281 IO::disable_ports ();
282 IO::disable_connecting ();
286 Session::second_stage_init (bool new_session)
288 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
291 if (load_state (_current_snapshot_name)) {
294 remove_empty_sounds ();
297 if (start_butler_thread()) {
301 if (start_midi_thread ()) {
305 // set_state() will call setup_raid_path(), but if it's a new session we need
306 // to call setup_raid_path() here.
309 if (set_state (*state_tree->root())) {
313 setup_raid_path(_path);
316 /* we can't save till after ::when_engine_running() is called,
317 because otherwise we save state with no connections made.
318 therefore, we reset _state_of_the_state because ::set_state()
319 will have cleared it.
321 we also have to include Loading so that any events that get
322 generated between here and the end of ::when_engine_running()
323 will be processed directly rather than queued.
326 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
329 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
330 _locations.added.connect (mem_fun (this, &Session::locations_added));
331 setup_click_sounds (0);
332 setup_midi_control ();
334 /* Pay attention ... */
336 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
337 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
340 when_engine_running();
343 /* handle this one in a different way than all others, so that its clear what happened */
345 catch (AudioEngine::PortRegistrationFailure& err) {
346 error << _("Unable to create all required ports")
355 BootMessage (_("Reset Remote Controls"));
357 send_full_time_code (0);
358 _engine.transport_locate (0);
359 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
360 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
362 MidiClockTicker::instance().set_session(*this);
363 MIDI::Name::MidiPatchManager::instance().set_session(*this);
365 BootMessage (_("Reset Control Protocols"));
367 ControlProtocolManager::instance().set_session (*this);
370 _end_location_is_free = true;
372 _end_location_is_free = false;
375 _state_of_the_state = Clean;
377 DirtyChanged (); /* EMIT SIGNAL */
379 if (state_was_pending) {
380 save_state (_current_snapshot_name);
381 remove_pending_capture_state ();
382 state_was_pending = false;
385 BootMessage (_("Session loading complete"));
391 Session::raid_path () const
393 SearchPath raid_search_path;
395 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
396 raid_search_path += sys::path((*i).path);
399 return raid_search_path.to_string ();
403 Session::setup_raid_path (string path)
412 session_dirs.clear ();
414 SearchPath search_path(path);
415 SearchPath sound_search_path;
416 SearchPath midi_search_path;
419 SearchPath::const_iterator i = search_path.begin();
420 i != search_path.end();
424 sp.path = (*i).to_string ();
425 sp.blocks = 0; // not needed
426 session_dirs.push_back (sp);
428 SessionDirectory sdir(sp.path);
430 sound_search_path += sdir.sound_path ();
431 midi_search_path += sdir.midi_path ();
434 // set the AudioFileSource and SMFSource search path
436 AudioFileSource::set_search_path (sound_search_path.to_string ());
437 SMFSource::set_search_path (midi_search_path.to_string ());
440 // reset the round-robin soundfile path thingie
442 last_rr_session_dir = session_dirs.begin();
446 Session::ensure_subdirs ()
450 dir = session_directory().peak_path().to_string();
452 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
453 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
457 dir = session_directory().sound_path().to_string();
459 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
460 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
464 dir = session_directory().midi_path().to_string();
466 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
467 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
471 dir = session_directory().dead_sound_path().to_string();
473 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
474 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
478 dir = session_directory().export_path().to_string();
480 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
481 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
485 dir = analysis_dir ();
487 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
488 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
496 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
499 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
500 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
504 if (ensure_subdirs ()) {
508 /* check new_session so we don't overwrite an existing one */
510 if (!mix_template.empty()) {
511 std::string in_path = mix_template;
513 ifstream in(in_path.c_str());
516 string out_path = _path;
518 out_path += statefile_suffix;
520 ofstream out(out_path.c_str());
525 // okay, session is set up. Treat like normal saved
526 // session from now on.
532 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
538 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
545 /* Instantiate metadata */
547 _metadata = new SessionMetadata ();
549 /* set initial start + end point */
551 start_location->set_end (0);
552 _locations.add (start_location);
554 end_location->set_end (initial_length);
555 _locations.add (end_location);
557 _state_of_the_state = Clean;
566 Session::load_diskstreams (const XMLNode& node)
569 XMLNodeConstIterator citer;
571 clist = node.children();
573 for (citer = clist.begin(); citer != clist.end(); ++citer) {
576 /* diskstreams added automatically by DiskstreamCreated handler */
577 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
578 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
579 add_diskstream (dstream);
580 } else if ((*citer)->name() == "MidiDiskstream") {
581 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
582 add_diskstream (dstream);
584 error << _("Session: unknown diskstream type in XML") << endmsg;
588 catch (failed_constructor& err) {
589 error << _("Session: could not load diskstream via XML state") << endmsg;
598 Session::maybe_write_autosave()
600 if (dirty() && record_status() != Recording) {
601 save_state("", true);
606 Session::remove_pending_capture_state ()
608 sys::path pending_state_file_path(_session_dir->root_path());
610 pending_state_file_path /= _current_snapshot_name + pending_suffix;
614 sys::remove (pending_state_file_path);
616 catch(sys::filesystem_error& ex)
618 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
619 pending_state_file_path.to_string(), ex.what()) << endmsg;
623 /** Rename a state file.
624 * @param snapshot_name Snapshot name.
627 Session::rename_state (string old_name, string new_name)
629 if (old_name == _current_snapshot_name || old_name == _name) {
630 /* refuse to rename the current snapshot or the "main" one */
634 const string old_xml_filename = old_name + statefile_suffix;
635 const string new_xml_filename = new_name + statefile_suffix;
637 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
638 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
642 sys::rename (old_xml_path, new_xml_path);
644 catch (const sys::filesystem_error& err)
646 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
647 old_name, new_name, err.what()) << endmsg;
651 /** Remove a state file.
652 * @param snapshot_name Snapshot name.
655 Session::remove_state (string snapshot_name)
657 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
658 // refuse to remove the current snapshot or the "main" one
662 sys::path xml_path(_session_dir->root_path());
664 xml_path /= snapshot_name + statefile_suffix;
666 if (!create_backup_file (xml_path)) {
667 // don't remove it if a backup can't be made
668 // create_backup_file will log the error.
673 sys::remove (xml_path);
677 Session::save_state (string snapshot_name, bool pending)
680 sys::path xml_path(_session_dir->root_path());
682 if (_state_of_the_state & CannotSave) {
686 if (!_engine.connected ()) {
687 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
692 /* tell sources we're saving first, in case they write out to a new file
693 * which should be saved with the state rather than the old one */
694 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
695 i->second->session_saved();
697 tree.set_root (&get_state());
699 if (snapshot_name.empty()) {
700 snapshot_name = _current_snapshot_name;
705 /* proper save: use statefile_suffix (.ardour in English) */
707 xml_path /= snapshot_name + statefile_suffix;
709 /* make a backup copy of the old file */
711 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
712 // create_backup_file will log the error
718 /* pending save: use pending_suffix (.pending in English) */
719 xml_path /= snapshot_name + pending_suffix;
722 sys::path tmp_path(_session_dir->root_path());
724 tmp_path /= snapshot_name + temp_suffix;
726 // cerr << "actually writing state to " << xml_path.to_string() << endl;
728 if (!tree.write (tmp_path.to_string())) {
729 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
730 sys::remove (tmp_path);
735 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
736 error << string_compose (_("could not rename temporary session file %1 to %2"),
737 tmp_path.to_string(), xml_path.to_string()) << endmsg;
738 sys::remove (tmp_path);
745 save_history (snapshot_name);
747 bool was_dirty = dirty();
749 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
752 DirtyChanged (); /* EMIT SIGNAL */
755 StateSaved (snapshot_name); /* EMIT SIGNAL */
762 Session::restore_state (string snapshot_name)
764 if (load_state (snapshot_name) == 0) {
765 set_state (*state_tree->root());
772 Session::load_state (string snapshot_name)
779 state_was_pending = false;
781 /* check for leftover pending state from a crashed capture attempt */
783 sys::path xmlpath(_session_dir->root_path());
784 xmlpath /= snapshot_name + pending_suffix;
786 if (sys::exists (xmlpath)) {
788 /* there is pending state from a crashed capture attempt */
790 if (AskAboutPendingState()) {
791 state_was_pending = true;
795 if (!state_was_pending) {
796 xmlpath = _session_dir->root_path();
797 xmlpath /= snapshot_name + statefile_suffix;
800 if (!sys::exists (xmlpath)) {
801 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
805 state_tree = new XMLTree;
809 if (!state_tree->read (xmlpath.to_string())) {
810 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
816 XMLNode& root (*state_tree->root());
818 if (root.name() != X_("Session")) {
819 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
825 const XMLProperty* prop;
826 bool is_old = false; // session is _very_ old (pre-2.0)
828 if ((prop = root.property ("version")) == 0) {
829 /* no version implies very old version of Ardour */
833 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
834 if (major_version < 2) {
841 sys::path backup_path(_session_dir->root_path());
843 backup_path /= snapshot_name + "-1" + statefile_suffix;
845 // only create a backup once
846 if (sys::exists (backup_path)) {
850 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
851 xmlpath.to_string(), backup_path.to_string())
856 sys::copy_file (xmlpath, backup_path);
858 catch(sys::filesystem_error& ex)
860 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
861 xmlpath.to_string(), ex.what())
871 Session::load_options (const XMLNode& node)
875 LocaleGuard lg (X_("POSIX"));
877 Config->set_variables (node, ConfigVariableBase::Session);
879 /* now reset MIDI ports because the session can have its own
885 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
886 if ((prop = child->property ("val")) != 0) {
887 _end_location_is_free = (prop->value() == "yes");
895 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
897 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
898 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
900 return owner & modified_by_session_or_user;
904 Session::get_options () const
907 LocaleGuard lg (X_("POSIX"));
909 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
911 child = option_root.add_child ("end-marker-is-free");
912 child->add_property ("val", _end_location_is_free ? "yes" : "no");
924 Session::get_template()
926 /* if we don't disable rec-enable, diskstreams
927 will believe they need to store their capture
928 sources in their state node.
931 disable_record (false);
937 Session::state(bool full_state)
939 XMLNode* node = new XMLNode("Session");
942 // store libardour version, just in case
944 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
945 node->add_property("version", string(buf));
947 /* store configuration settings */
951 node->add_property ("name", _name);
952 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
953 node->add_property ("sample-rate", buf);
955 if (session_dirs.size() > 1) {
959 vector<space_and_path>::iterator i = session_dirs.begin();
960 vector<space_and_path>::iterator next;
962 ++i; /* skip the first one */
966 while (i != session_dirs.end()) {
970 if (next != session_dirs.end()) {
980 child = node->add_child ("Path");
981 child->add_content (p);
985 /* save the ID counter */
987 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
988 node->add_property ("id-counter", buf);
990 /* various options */
992 node->add_child_nocopy (get_options());
994 node->add_child_nocopy (_metadata->get_state());
996 child = node->add_child ("Sources");
999 Glib::Mutex::Lock sl (source_lock);
1001 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1003 /* Don't save information about AudioFileSources that are empty */
1005 boost::shared_ptr<AudioFileSource> fs;
1007 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
1009 /* Don't save sources that are empty, unless they're destructive (which are OK
1010 if they are empty, because we will re-use them every time.)
1013 if (!fs->destructive()) {
1014 if (fs->length() == 0) {
1020 child->add_child_nocopy (siter->second->get_state());
1024 child = node->add_child ("Regions");
1027 Glib::Mutex::Lock rl (region_lock);
1029 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
1031 /* only store regions not attached to playlists */
1033 if (i->second->playlist() == 0) {
1034 child->add_child_nocopy (i->second->state (true));
1039 child = node->add_child ("DiskStreams");
1042 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1043 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1044 if (!(*i)->hidden()) {
1045 child->add_child_nocopy ((*i)->get_state());
1051 node->add_child_nocopy (_locations.get_state());
1053 // for a template, just create a new Locations, populate it
1054 // with the default start and end, and get the state for that.
1056 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1057 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1060 end->set_end(compute_initial_length());
1062 node->add_child_nocopy (loc.get_state());
1065 child = node->add_child ("Bundles");
1067 Glib::Mutex::Lock lm (bundle_lock);
1068 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
1069 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1071 child->add_child_nocopy (b->get_state());
1076 child = node->add_child ("Routes");
1078 boost::shared_ptr<RouteList> r = routes.reader ();
1080 RoutePublicOrderSorter cmp;
1081 RouteList public_order (*r);
1082 public_order.sort (cmp);
1084 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1085 if (!(*i)->is_hidden()) {
1087 child->add_child_nocopy ((*i)->get_state());
1089 child->add_child_nocopy ((*i)->get_template());
1096 child = node->add_child ("EditGroups");
1097 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1098 child->add_child_nocopy ((*i)->get_state());
1101 child = node->add_child ("MixGroups");
1102 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1103 child->add_child_nocopy ((*i)->get_state());
1106 child = node->add_child ("Playlists");
1107 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1108 if (!(*i)->hidden()) {
1109 if (!(*i)->empty()) {
1111 child->add_child_nocopy ((*i)->get_state());
1113 child->add_child_nocopy ((*i)->get_template());
1119 child = node->add_child ("UnusedPlaylists");
1120 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1121 if (!(*i)->hidden()) {
1122 if (!(*i)->empty()) {
1124 child->add_child_nocopy ((*i)->get_state());
1126 child->add_child_nocopy ((*i)->get_template());
1134 child = node->add_child ("Click");
1135 child->add_child_nocopy (_click_io->state (full_state));
1139 child = node->add_child ("NamedSelections");
1140 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1142 child->add_child_nocopy ((*i)->get_state());
1147 node->add_child_nocopy (_tempo_map->get_state());
1149 node->add_child_nocopy (get_control_protocol_state());
1152 node->add_child_copy (*_extra_xml);
1159 Session::get_control_protocol_state ()
1161 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1162 return cpm.get_state();
1166 Session::set_state (const XMLNode& node)
1170 const XMLProperty* prop;
1173 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1175 if (node.name() != X_("Session")){
1176 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1180 if ((prop = node.property ("name")) != 0) {
1181 _name = prop->value ();
1184 if ((prop = node.property (X_("sample-rate"))) != 0) {
1186 _nominal_frame_rate = atoi (prop->value());
1188 if (_nominal_frame_rate != _current_frame_rate) {
1189 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1195 setup_raid_path(_session_dir->root_path().to_string());
1197 if ((prop = node.property (X_("id-counter"))) != 0) {
1199 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1200 ID::init_counter (x);
1202 /* old sessions used a timebased counter, so fake
1203 the startup ID counter based on a standard
1208 ID::init_counter (now);
1212 IO::disable_ports ();
1213 IO::disable_connecting ();
1215 /* Object loading order:
1220 MIDI Control // relies on data from Options/Config
1234 if ((child = find_named_node (node, "extra")) != 0) {
1235 _extra_xml = new XMLNode (*child);
1238 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1239 load_options (*child);
1240 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1241 load_options (*child);
1243 error << _("Session: XML state has no options section") << endmsg;
1246 if (use_config_midi_ports ()) {
1249 if ((child = find_named_node (node, "Metadata")) == 0) {
1250 warning << _("Session: XML state has no metadata section (2.0 session?)") << endmsg;
1251 } else if (_metadata->set_state (*child)) {
1255 if ((child = find_named_node (node, "Locations")) == 0) {
1256 error << _("Session: XML state has no locations section") << endmsg;
1258 } else if (_locations.set_state (*child)) {
1264 if ((location = _locations.auto_loop_location()) != 0) {
1265 set_auto_loop_location (location);
1268 if ((location = _locations.auto_punch_location()) != 0) {
1269 set_auto_punch_location (location);
1272 if ((location = _locations.end_location()) == 0) {
1273 _locations.add (end_location);
1275 delete end_location;
1276 end_location = location;
1279 if ((location = _locations.start_location()) == 0) {
1280 _locations.add (start_location);
1282 delete start_location;
1283 start_location = location;
1286 AudioFileSource::set_header_position_offset (start_location->start());
1288 if ((child = find_named_node (node, "Sources")) == 0) {
1289 error << _("Session: XML state has no sources section") << endmsg;
1291 } else if (load_sources (*child)) {
1295 if ((child = find_named_node (node, "Regions")) == 0) {
1296 error << _("Session: XML state has no Regions section") << endmsg;
1298 } else if (load_regions (*child)) {
1302 if ((child = find_named_node (node, "Playlists")) == 0) {
1303 error << _("Session: XML state has no playlists section") << endmsg;
1305 } else if (load_playlists (*child)) {
1309 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1311 } else if (load_unused_playlists (*child)) {
1315 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1316 if (load_named_selections (*child)) {
1321 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1322 error << _("Session: XML state has no diskstreams section") << endmsg;
1324 } else if (load_diskstreams (*child)) {
1328 if ((child = find_named_node (node, "Bundles")) == 0) {
1329 warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg;
1332 /* We can't load Bundles yet as they need to be able
1333 to convert from port names to Port objects, which can't happen until
1335 _bundle_xml_node = new XMLNode (*child);
1338 if ((child = find_named_node (node, "EditGroups")) == 0) {
1339 error << _("Session: XML state has no edit groups section") << endmsg;
1341 } else if (load_edit_groups (*child)) {
1345 if ((child = find_named_node (node, "MixGroups")) == 0) {
1346 error << _("Session: XML state has no mix groups section") << endmsg;
1348 } else if (load_mix_groups (*child)) {
1352 if ((child = find_named_node (node, "TempoMap")) == 0) {
1353 error << _("Session: XML state has no Tempo Map section") << endmsg;
1355 } else if (_tempo_map->set_state (*child)) {
1359 if ((child = find_named_node (node, "Routes")) == 0) {
1360 error << _("Session: XML state has no routes section") << endmsg;
1362 } else if (load_routes (*child)) {
1366 if ((child = find_named_node (node, "Click")) == 0) {
1367 warning << _("Session: XML state has no click section") << endmsg;
1368 } else if (_click_io) {
1369 _click_io->set_state (*child);
1372 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1373 ControlProtocolManager::instance().set_protocol_states (*child);
1376 /* here beginneth the second phase ... */
1378 StateReady (); /* EMIT SIGNAL */
1387 Session::load_routes (const XMLNode& node)
1390 XMLNodeConstIterator niter;
1391 RouteList new_routes;
1393 nlist = node.children();
1397 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1399 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1402 error << _("Session: cannot create Route from XML description.") << endmsg;
1406 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1408 new_routes.push_back (route);
1411 add_routes (new_routes, false);
1416 boost::shared_ptr<Route>
1417 Session::XMLRouteFactory (const XMLNode& node)
1419 if (node.name() != "Route") {
1420 return boost::shared_ptr<Route> ((Route*) 0);
1423 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1425 DataType type = DataType::AUDIO;
1426 const XMLProperty* prop = node.property("default-type");
1428 type = DataType(prop->value());
1430 assert(type != DataType::NIL);
1432 if (has_diskstream) {
1433 if (type == DataType::AUDIO) {
1434 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1437 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1441 boost::shared_ptr<Route> ret (new Route (*this, node));
1447 Session::load_regions (const XMLNode& node)
1450 XMLNodeConstIterator niter;
1451 boost::shared_ptr<Region> region;
1453 nlist = node.children();
1457 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1458 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1459 error << _("Session: cannot create Region from XML description.");
1460 const XMLProperty *name = (**niter).property("name");
1463 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1473 boost::shared_ptr<Region>
1474 Session::XMLRegionFactory (const XMLNode& node, bool full)
1476 const XMLProperty* type = node.property("type");
1480 if ( !type || type->value() == "audio" ) {
1482 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1484 } else if (type->value() == "midi") {
1486 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1490 } catch (failed_constructor& err) {
1491 return boost::shared_ptr<Region> ();
1494 return boost::shared_ptr<Region> ();
1497 boost::shared_ptr<AudioRegion>
1498 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1500 const XMLProperty* prop;
1501 boost::shared_ptr<Source> source;
1502 boost::shared_ptr<AudioSource> as;
1504 SourceList master_sources;
1505 uint32_t nchans = 1;
1508 if (node.name() != X_("Region")) {
1509 return boost::shared_ptr<AudioRegion>();
1512 if ((prop = node.property (X_("channels"))) != 0) {
1513 nchans = atoi (prop->value().c_str());
1516 if ((prop = node.property ("name")) == 0) {
1517 cerr << "no name for this region\n";
1521 if ((prop = node.property (X_("source-0"))) == 0) {
1522 if ((prop = node.property ("source")) == 0) {
1523 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1524 return boost::shared_ptr<AudioRegion>();
1528 PBD::ID s_id (prop->value());
1530 if ((source = source_by_id (s_id)) == 0) {
1531 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1532 return boost::shared_ptr<AudioRegion>();
1535 as = boost::dynamic_pointer_cast<AudioSource>(source);
1537 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1538 return boost::shared_ptr<AudioRegion>();
1541 sources.push_back (as);
1543 /* pickup other channels */
1545 for (uint32_t n=1; n < nchans; ++n) {
1546 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1547 if ((prop = node.property (buf)) != 0) {
1549 PBD::ID id2 (prop->value());
1551 if ((source = source_by_id (id2)) == 0) {
1552 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1553 return boost::shared_ptr<AudioRegion>();
1556 as = boost::dynamic_pointer_cast<AudioSource>(source);
1558 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1559 return boost::shared_ptr<AudioRegion>();
1561 sources.push_back (as);
1565 for (uint32_t n=1; n < nchans; ++n) {
1566 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1567 if ((prop = node.property (buf)) != 0) {
1569 PBD::ID id2 (prop->value());
1571 if ((source = source_by_id (id2)) == 0) {
1572 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1573 return boost::shared_ptr<AudioRegion>();
1576 as = boost::dynamic_pointer_cast<AudioSource>(source);
1578 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1579 return boost::shared_ptr<AudioRegion>();
1581 master_sources.push_back (as);
1586 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1588 /* a final detail: this is the one and only place that we know how long missing files are */
1590 if (region->whole_file()) {
1591 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1592 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1594 sfp->set_length (region->length());
1599 if (!master_sources.empty()) {
1600 if (master_sources.size() == nchans) {
1601 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1603 region->set_master_sources (master_sources);
1611 catch (failed_constructor& err) {
1612 return boost::shared_ptr<AudioRegion>();
1616 boost::shared_ptr<MidiRegion>
1617 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1619 const XMLProperty* prop;
1620 boost::shared_ptr<Source> source;
1621 boost::shared_ptr<MidiSource> ms;
1623 uint32_t nchans = 1;
1625 if (node.name() != X_("Region")) {
1626 return boost::shared_ptr<MidiRegion>();
1629 if ((prop = node.property (X_("channels"))) != 0) {
1630 nchans = atoi (prop->value().c_str());
1633 if ((prop = node.property ("name")) == 0) {
1634 cerr << "no name for this region\n";
1638 // Multiple midi channels? that's just crazy talk
1639 assert(nchans == 1);
1641 if ((prop = node.property (X_("source-0"))) == 0) {
1642 if ((prop = node.property ("source")) == 0) {
1643 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1644 return boost::shared_ptr<MidiRegion>();
1648 PBD::ID s_id (prop->value());
1650 if ((source = source_by_id (s_id)) == 0) {
1651 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1652 return boost::shared_ptr<MidiRegion>();
1655 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1657 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1658 return boost::shared_ptr<MidiRegion>();
1661 sources.push_back (ms);
1664 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1665 /* a final detail: this is the one and only place that we know how long missing files are */
1667 if (region->whole_file()) {
1668 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1669 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1671 sfp->set_length (region->length());
1679 catch (failed_constructor& err) {
1680 return boost::shared_ptr<MidiRegion>();
1685 Session::get_sources_as_xml ()
1688 XMLNode* node = new XMLNode (X_("Sources"));
1689 Glib::Mutex::Lock lm (source_lock);
1691 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1692 node->add_child_nocopy (i->second->get_state());
1699 Session::path_from_region_name (DataType type, string name, string identifier)
1701 char buf[PATH_MAX+1];
1703 SessionDirectory sdir(get_best_session_directory_for_new_source());
1704 sys::path source_dir = ((type == DataType::AUDIO)
1705 ? sdir.sound_path() : sdir.midi_path());
1707 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1709 for (n = 0; n < 999999; ++n) {
1710 if (identifier.length()) {
1711 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1712 identifier.c_str(), n, ext.c_str());
1714 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1718 sys::path source_path = source_dir / buf;
1720 if (!sys::exists (source_path)) {
1721 return source_path.to_string();
1725 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1734 Session::load_sources (const XMLNode& node)
1737 XMLNodeConstIterator niter;
1738 boost::shared_ptr<Source> source;
1740 nlist = node.children();
1744 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1747 if ((source = XMLSourceFactory (**niter)) == 0) {
1748 error << _("Session: cannot create Source from XML description.") << endmsg;
1752 catch (non_existent_source& err) {
1753 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1754 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1761 boost::shared_ptr<Source>
1762 Session::XMLSourceFactory (const XMLNode& node)
1764 if (node.name() != "Source") {
1765 return boost::shared_ptr<Source>();
1769 /* note: do peak building in another thread when loading session state */
1770 return SourceFactory::create (*this, node, true);
1773 catch (failed_constructor& err) {
1774 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1775 return boost::shared_ptr<Source>();
1780 Session::save_template (string template_name)
1784 if (_state_of_the_state & CannotSave) {
1788 sys::path user_template_dir(user_template_directory());
1792 sys::create_directories (user_template_dir);
1794 catch(sys::filesystem_error& ex)
1796 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1797 user_template_dir.to_string(), ex.what()) << endmsg;
1801 tree.set_root (&get_template());
1803 sys::path template_file_path(user_template_dir);
1804 template_file_path /= template_name + template_suffix;
1806 if (sys::exists (template_file_path))
1808 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1809 template_file_path.to_string()) << endmsg;
1813 if (!tree.write (template_file_path.to_string())) {
1814 error << _("mix template not saved") << endmsg;
1822 Session::rename_template (string old_name, string new_name)
1824 sys::path old_path (user_template_directory());
1825 old_path /= old_name + template_suffix;
1827 sys::path new_path(user_template_directory());
1828 new_path /= new_name + template_suffix;
1830 if (sys::exists (new_path)) {
1831 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1832 new_path.to_string()) << endmsg;
1837 sys::rename (old_path, new_path);
1845 Session::delete_template (string name)
1847 sys::path path = user_template_directory();
1848 path /= name + template_suffix;
1859 Session::refresh_disk_space ()
1862 struct statfs statfsbuf;
1863 vector<space_and_path>::iterator i;
1864 Glib::Mutex::Lock lm (space_lock);
1867 /* get freespace on every FS that is part of the session path */
1869 _total_free_4k_blocks = 0;
1871 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1872 statfs ((*i).path.c_str(), &statfsbuf);
1874 scale = statfsbuf.f_bsize/4096.0;
1876 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1877 _total_free_4k_blocks += (*i).blocks;
1883 Session::get_best_session_directory_for_new_source ()
1885 vector<space_and_path>::iterator i;
1886 string result = _session_dir->root_path().to_string();
1888 /* handle common case without system calls */
1890 if (session_dirs.size() == 1) {
1894 /* OK, here's the algorithm we're following here:
1896 We want to select which directory to use for
1897 the next file source to be created. Ideally,
1898 we'd like to use a round-robin process so as to
1899 get maximum performance benefits from splitting
1900 the files across multiple disks.
1902 However, in situations without much diskspace, an
1903 RR approach may end up filling up a filesystem
1904 with new files while others still have space.
1905 Its therefore important to pay some attention to
1906 the freespace in the filesystem holding each
1907 directory as well. However, if we did that by
1908 itself, we'd keep creating new files in the file
1909 system with the most space until it was as full
1910 as all others, thus negating any performance
1911 benefits of this RAID-1 like approach.
1913 So, we use a user-configurable space threshold. If
1914 there are at least 2 filesystems with more than this
1915 much space available, we use RR selection between them.
1916 If not, then we pick the filesystem with the most space.
1918 This gets a good balance between the two
1922 refresh_disk_space ();
1924 int free_enough = 0;
1926 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1927 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1932 if (free_enough >= 2) {
1933 /* use RR selection process, ensuring that the one
1937 i = last_rr_session_dir;
1940 if (++i == session_dirs.end()) {
1941 i = session_dirs.begin();
1944 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1945 if (create_session_directory ((*i).path)) {
1947 last_rr_session_dir = i;
1952 } while (i != last_rr_session_dir);
1956 /* pick FS with the most freespace (and that
1957 seems to actually work ...)
1960 vector<space_and_path> sorted;
1961 space_and_path_ascending_cmp cmp;
1963 sorted = session_dirs;
1964 sort (sorted.begin(), sorted.end(), cmp);
1966 for (i = sorted.begin(); i != sorted.end(); ++i) {
1967 if (create_session_directory ((*i).path)) {
1969 last_rr_session_dir = i;
1979 Session::load_playlists (const XMLNode& node)
1982 XMLNodeConstIterator niter;
1983 boost::shared_ptr<Playlist> playlist;
1985 nlist = node.children();
1989 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1991 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1992 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2000 Session::load_unused_playlists (const XMLNode& node)
2003 XMLNodeConstIterator niter;
2004 boost::shared_ptr<Playlist> playlist;
2006 nlist = node.children();
2010 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2012 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2013 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2017 // now manually untrack it
2019 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
2025 boost::shared_ptr<Playlist>
2026 Session::XMLPlaylistFactory (const XMLNode& node)
2029 return PlaylistFactory::create (*this, node);
2032 catch (failed_constructor& err) {
2033 return boost::shared_ptr<Playlist>();
2038 Session::load_named_selections (const XMLNode& node)
2041 XMLNodeConstIterator niter;
2044 nlist = node.children();
2048 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2050 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2051 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2059 Session::XMLNamedSelectionFactory (const XMLNode& node)
2062 return new NamedSelection (*this, node);
2065 catch (failed_constructor& err) {
2071 Session::automation_dir () const
2073 return Glib::build_filename (_path, "automation");
2077 Session::analysis_dir () const
2079 return Glib::build_filename (_path, "analysis");
2083 Session::load_bundles (XMLNode const & node)
2085 XMLNodeList nlist = node.children();
2086 XMLNodeConstIterator niter;
2090 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2091 if ((*niter)->name() == "InputBundle") {
2092 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2093 } else if ((*niter)->name() == "OutputBundle") {
2094 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2096 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2105 Session::load_edit_groups (const XMLNode& node)
2107 return load_route_groups (node, true);
2111 Session::load_mix_groups (const XMLNode& node)
2113 return load_route_groups (node, false);
2117 Session::load_route_groups (const XMLNode& node, bool edit)
2119 XMLNodeList nlist = node.children();
2120 XMLNodeConstIterator niter;
2125 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2126 if ((*niter)->name() == "RouteGroup") {
2128 rg = add_edit_group ("");
2129 rg->set_state (**niter);
2131 rg = add_mix_group ("");
2132 rg->set_state (**niter);
2141 Session::auto_save()
2143 save_state (_current_snapshot_name);
2147 state_file_filter (const string &str, void *arg)
2149 return (str.length() > strlen(statefile_suffix) &&
2150 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2154 bool operator()(const string* a, const string* b) {
2160 remove_end(string* state)
2162 string statename(*state);
2164 string::size_type start,end;
2165 if ((start = statename.find_last_of ('/')) != string::npos) {
2166 statename = statename.substr (start+1);
2169 if ((end = statename.rfind(".ardour")) == string::npos) {
2170 end = statename.length();
2173 return new string(statename.substr (0, end));
2177 Session::possible_states (string path)
2179 PathScanner scanner;
2180 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2182 transform(states->begin(), states->end(), states->begin(), remove_end);
2185 sort (states->begin(), states->end(), cmp);
2191 Session::possible_states () const
2193 return possible_states(_path);
2197 Session::add_edit_group (string name)
2199 RouteGroup* rg = new RouteGroup (*this, name);
2200 edit_groups.push_back (rg);
2201 edit_group_added (rg); /* EMIT SIGNAL */
2207 Session::add_mix_group (string name)
2209 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2210 mix_groups.push_back (rg);
2211 mix_group_added (rg); /* EMIT SIGNAL */
2217 Session::remove_edit_group (RouteGroup& rg)
2219 list<RouteGroup*>::iterator i;
2221 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2222 (*i)->apply (&Route::drop_edit_group, this);
2223 edit_groups.erase (i);
2224 edit_group_removed (); /* EMIT SIGNAL */
2231 Session::remove_mix_group (RouteGroup& rg)
2233 list<RouteGroup*>::iterator i;
2235 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2236 (*i)->apply (&Route::drop_mix_group, this);
2237 mix_groups.erase (i);
2238 mix_group_removed (); /* EMIT SIGNAL */
2245 Session::mix_group_by_name (string name)
2247 list<RouteGroup *>::iterator i;
2249 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2250 if ((*i)->name() == name) {
2258 Session::edit_group_by_name (string name)
2260 list<RouteGroup *>::iterator i;
2262 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2263 if ((*i)->name() == name) {
2271 Session::begin_reversible_command (const string& name)
2273 current_trans = new UndoTransaction;
2274 current_trans->set_name (name);
2278 Session::commit_reversible_command (Command *cmd)
2283 current_trans->add_command (cmd);
2286 if (current_trans->empty()) {
2290 gettimeofday (&now, 0);
2291 current_trans->set_timestamp (now);
2293 _history.add (current_trans);
2296 Session::GlobalRouteBooleanState
2297 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2299 GlobalRouteBooleanState s;
2300 boost::shared_ptr<RouteList> r = routes.reader ();
2302 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2303 if (!(*i)->is_hidden()) {
2304 RouteBooleanState v;
2307 Route* r = (*i).get();
2308 v.second = (r->*method)();
2317 Session::GlobalRouteMeterState
2318 Session::get_global_route_metering ()
2320 GlobalRouteMeterState s;
2321 boost::shared_ptr<RouteList> r = routes.reader ();
2323 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2324 if (!(*i)->is_hidden()) {
2328 v.second = (*i)->meter_point();
2338 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2340 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2342 boost::shared_ptr<Route> r = (i->first.lock());
2345 r->set_meter_point (i->second, arg);
2351 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2353 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2355 boost::shared_ptr<Route> r = (i->first.lock());
2358 Route* rp = r.get();
2359 (rp->*method) (i->second, arg);
2365 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2367 set_global_route_boolean (s, &Route::set_mute, src);
2371 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2373 set_global_route_boolean (s, &Route::set_solo, src);
2377 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2379 set_global_route_boolean (s, &Route::set_record_enable, src);
2384 Session::global_mute_memento (void* src)
2386 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2390 Session::global_metering_memento (void* src)
2392 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2396 Session::global_solo_memento (void* src)
2398 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2402 Session::global_record_enable_memento (void* src)
2404 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2409 accept_all_non_peak_files (const string& path, void *arg)
2411 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2415 accept_all_state_files (const string& path, void *arg)
2417 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2421 Session::find_all_sources (string path, set<string>& result)
2426 if (!tree.read (path)) {
2430 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2435 XMLNodeConstIterator niter;
2437 nlist = node->children();
2441 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2445 if ((prop = (*niter)->property (X_("name"))) == 0) {
2449 if (prop->value()[0] == '/') {
2450 /* external file, ignore */
2454 sys::path source_path = _session_dir->sound_path ();
2456 source_path /= prop->value ();
2458 result.insert (source_path.to_string ());
2465 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2467 PathScanner scanner;
2468 vector<string*>* state_files;
2470 string this_snapshot_path;
2476 if (ripped[ripped.length()-1] == '/') {
2477 ripped = ripped.substr (0, ripped.length() - 1);
2480 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2482 if (state_files == 0) {
2487 this_snapshot_path = _path;
2488 this_snapshot_path += _current_snapshot_name;
2489 this_snapshot_path += statefile_suffix;
2491 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2493 if (exclude_this_snapshot && **i == this_snapshot_path) {
2497 if (find_all_sources (**i, result) < 0) {
2505 struct RegionCounter {
2506 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2507 AudioSourceList::iterator iter;
2508 boost::shared_ptr<Region> region;
2511 RegionCounter() : count (0) {}
2515 Session::cleanup_sources (Session::cleanup_report& rep)
2517 // FIXME: needs adaptation to midi
2519 vector<boost::shared_ptr<Source> > dead_sources;
2520 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2521 PathScanner scanner;
2523 vector<space_and_path>::iterator i;
2524 vector<space_and_path>::iterator nexti;
2525 vector<string*>* soundfiles;
2526 vector<string> unused;
2527 set<string> all_sources;
2532 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2535 /* step 1: consider deleting all unused playlists */
2537 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2540 status = AskAboutPlaylistDeletion (*x);
2549 playlists_tbd.push_back (*x);
2553 /* leave it alone */
2558 /* now delete any that were marked for deletion */
2560 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2561 (*x)->drop_references ();
2564 playlists_tbd.clear ();
2566 /* step 2: find all un-used sources */
2571 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2573 SourceMap::iterator tmp;
2578 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2582 if (!i->second->used() && i->second->length() > 0) {
2583 dead_sources.push_back (i->second);
2584 i->second->GoingAway();
2590 /* build a list of all the possible sound directories for the session */
2592 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2597 SessionDirectory sdir ((*i).path);
2598 sound_path += sdir.sound_path().to_string();
2600 if (nexti != session_dirs.end()) {
2607 /* now do the same thing for the files that ended up in the sounds dir(s)
2608 but are not referenced as sources in any snapshot.
2611 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2613 if (soundfiles == 0) {
2617 /* find all sources, but don't use this snapshot because the
2618 state file on disk still references sources we may have already
2622 find_all_sources_across_snapshots (all_sources, true);
2624 /* add our current source list
2627 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2628 boost::shared_ptr<AudioFileSource> fs;
2630 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2631 all_sources.insert (fs->path());
2635 char tmppath1[PATH_MAX+1];
2636 char tmppath2[PATH_MAX+1];
2638 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2643 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2645 realpath(spath.c_str(), tmppath1);
2646 realpath((*i).c_str(), tmppath2);
2648 if (strcmp(tmppath1, tmppath2) == 0) {
2655 unused.push_back (spath);
2659 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2661 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2662 struct stat statbuf;
2664 rep.paths.push_back (*x);
2665 if (stat ((*x).c_str(), &statbuf) == 0) {
2666 rep.space += statbuf.st_size;
2671 /* don't move the file across filesystems, just
2672 stick it in the `dead_sound_dir_name' directory
2673 on whichever filesystem it was already on.
2676 if ((*x).find ("/sounds/") != string::npos) {
2678 /* old school, go up 1 level */
2680 newpath = Glib::path_get_dirname (*x); // "sounds"
2681 newpath = Glib::path_get_dirname (newpath); // "session-name"
2685 /* new school, go up 4 levels */
2687 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2688 newpath = Glib::path_get_dirname (newpath); // "session-name"
2689 newpath = Glib::path_get_dirname (newpath); // "interchange"
2690 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2694 newpath += dead_sound_dir_name;
2696 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2697 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2702 newpath += Glib::path_get_basename ((*x));
2704 if (access (newpath.c_str(), F_OK) == 0) {
2706 /* the new path already exists, try versioning */
2708 char buf[PATH_MAX+1];
2712 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2715 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2716 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2720 if (version == 999) {
2721 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2725 newpath = newpath_v;
2730 /* it doesn't exist, or we can't read it or something */
2734 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2735 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2736 (*x), newpath, strerror (errno))
2741 /* see if there an easy to find peakfile for this file, and remove it.
2744 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2745 peakpath += peakfile_suffix;
2747 if (access (peakpath.c_str(), W_OK) == 0) {
2748 if (::unlink (peakpath.c_str()) != 0) {
2749 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2750 peakpath, _path, strerror (errno))
2752 /* try to back out */
2753 rename (newpath.c_str(), _path.c_str());
2761 /* dump the history list */
2765 /* save state so we don't end up a session file
2766 referring to non-existent sources.
2772 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2778 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2780 // FIXME: needs adaptation for MIDI
2782 vector<space_and_path>::iterator i;
2783 string dead_sound_dir;
2784 struct dirent* dentry;
2785 struct stat statbuf;
2791 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2793 dead_sound_dir = (*i).path;
2794 dead_sound_dir += dead_sound_dir_name;
2796 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2800 while ((dentry = readdir (dead)) != 0) {
2802 /* avoid '.' and '..' */
2804 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2805 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2811 fullpath = dead_sound_dir;
2813 fullpath += dentry->d_name;
2815 if (stat (fullpath.c_str(), &statbuf)) {
2819 if (!S_ISREG (statbuf.st_mode)) {
2823 if (unlink (fullpath.c_str())) {
2824 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2825 fullpath, strerror (errno))
2829 rep.paths.push_back (dentry->d_name);
2830 rep.space += statbuf.st_size;
2841 Session::set_dirty ()
2843 bool was_dirty = dirty();
2845 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2849 DirtyChanged(); /* EMIT SIGNAL */
2855 Session::set_clean ()
2857 bool was_dirty = dirty();
2859 _state_of_the_state = Clean;
2863 DirtyChanged(); /* EMIT SIGNAL */
2868 Session::set_deletion_in_progress ()
2870 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2875 Session::add_controllable (boost::shared_ptr<Controllable> c)
2877 /* this adds a controllable to the list managed by the Session.
2878 this is a subset of those managed by the Controllable class
2879 itself, and represents the only ones whose state will be saved
2880 as part of the session.
2883 Glib::Mutex::Lock lm (controllables_lock);
2884 controllables.insert (c);
2887 struct null_deleter { void operator()(void const *) const {} };
2890 Session::remove_controllable (Controllable* c)
2892 if (_state_of_the_state | Deletion) {
2896 Glib::Mutex::Lock lm (controllables_lock);
2898 Controllables::iterator x = controllables.find(
2899 boost::shared_ptr<Controllable>(c, null_deleter()));
2901 if (x != controllables.end()) {
2902 controllables.erase (x);
2906 boost::shared_ptr<Controllable>
2907 Session::controllable_by_id (const PBD::ID& id)
2909 Glib::Mutex::Lock lm (controllables_lock);
2911 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2912 if ((*i)->id() == id) {
2917 return boost::shared_ptr<Controllable>();
2921 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2923 Stateful::add_instant_xml (node, _path);
2924 if (write_to_config) {
2925 Config->add_instant_xml (node);
2930 Session::instant_xml (const string& node_name)
2932 return Stateful::instant_xml (node_name, _path);
2936 Session::save_history (string snapshot_name)
2940 if (snapshot_name.empty()) {
2941 snapshot_name = _current_snapshot_name;
2944 const string history_filename = snapshot_name + history_suffix;
2945 const string backup_filename = history_filename + backup_suffix;
2946 const sys::path xml_path = _session_dir->root_path() / history_filename;
2947 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2949 if (sys::exists (xml_path)) {
2952 sys::rename (xml_path, backup_path);
2954 catch (const sys::filesystem_error& err)
2956 error << _("could not backup old history file, current history not saved") << endmsg;
2962 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2966 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2968 if (!tree.write (xml_path.to_string()))
2970 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2974 sys::remove (xml_path);
2975 sys::rename (backup_path, xml_path);
2977 catch (const sys::filesystem_error& err)
2979 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2980 backup_path.to_string(), err.what()) << endmsg;
2990 Session::restore_history (string snapshot_name)
2994 if (snapshot_name.empty()) {
2995 snapshot_name = _current_snapshot_name;
2998 const string xml_filename = snapshot_name + history_suffix;
2999 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3001 cerr << "Loading history from " << xml_path.to_string() << endmsg;
3003 if (!sys::exists (xml_path)) {
3004 info << string_compose (_("%1: no history file \"%2\" for this session."),
3005 _name, xml_path.to_string()) << endmsg;
3009 if (!tree.read (xml_path.to_string())) {
3010 error << string_compose (_("Could not understand session history file \"%1\""),
3011 xml_path.to_string()) << endmsg;
3018 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3021 UndoTransaction* ut = new UndoTransaction ();
3024 ut->set_name(t->property("name")->value());
3025 stringstream ss(t->property("tv-sec")->value());
3027 ss.str(t->property("tv-usec")->value());
3029 ut->set_timestamp(tv);
3031 for (XMLNodeConstIterator child_it = t->children().begin();
3032 child_it != t->children().end(); child_it++)
3034 XMLNode *n = *child_it;
3037 if (n->name() == "MementoCommand" ||
3038 n->name() == "MementoUndoCommand" ||
3039 n->name() == "MementoRedoCommand") {
3041 if ((c = memento_command_factory(n))) {
3045 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3047 if ((c = global_state_command_factory (*n))) {
3048 ut->add_command (c);
3051 } else if (n->name() == "DeltaCommand") {
3052 PBD::ID id(n->property("midi-source")->value());
3053 boost::shared_ptr<MidiSource> midi_source =
3054 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3056 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
3058 error << "FIXME: Failed to downcast MidiSource for DeltaCommand" << endmsg;
3061 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3072 Session::config_changed (const char* parameter_name)
3074 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3076 if (PARAM_IS ("seamless-loop")) {
3078 } else if (PARAM_IS ("rf-speed")) {
3080 } else if (PARAM_IS ("auto-loop")) {
3082 } else if (PARAM_IS ("auto-input")) {
3084 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3085 /* auto-input only makes a difference if we're rolling */
3087 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3089 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3090 if ((*i)->record_enabled ()) {
3091 (*i)->monitor_input (!Config->get_auto_input());
3096 } else if (PARAM_IS ("punch-in")) {
3100 if ((location = _locations.auto_punch_location()) != 0) {
3102 if (Config->get_punch_in ()) {
3103 replace_event (Event::PunchIn, location->start());
3105 remove_event (location->start(), Event::PunchIn);
3109 } else if (PARAM_IS ("punch-out")) {
3113 if ((location = _locations.auto_punch_location()) != 0) {
3115 if (Config->get_punch_out()) {
3116 replace_event (Event::PunchOut, location->end());
3118 clear_events (Event::PunchOut);
3122 } else if (PARAM_IS ("edit-mode")) {
3124 Glib::Mutex::Lock lm (playlist_lock);
3126 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3127 (*i)->set_edit_mode (Config->get_edit_mode ());
3130 } else if (PARAM_IS ("use-video-sync")) {
3132 waiting_for_sync_offset = Config->get_use_video_sync();
3134 } else if (PARAM_IS ("mmc-control")) {
3136 //poke_midi_thread ();
3138 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
3141 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3144 } else if (PARAM_IS ("mmc-send-id")) {
3147 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3150 } else if (PARAM_IS ("midi-control")) {
3152 //poke_midi_thread ();
3154 } else if (PARAM_IS ("raid-path")) {
3156 setup_raid_path (Config->get_raid_path());
3158 } else if (PARAM_IS ("smpte-format")) {
3162 } else if (PARAM_IS ("video-pullup")) {
3166 } else if (PARAM_IS ("seamless-loop")) {
3168 if (play_loop && transport_rolling()) {
3169 // to reset diskstreams etc
3170 request_play_loop (true);
3173 } else if (PARAM_IS ("rf-speed")) {
3175 cumulative_rf_motion = 0;
3178 } else if (PARAM_IS ("click-sound")) {
3180 setup_click_sounds (1);
3182 } else if (PARAM_IS ("click-emphasis-sound")) {
3184 setup_click_sounds (-1);
3186 } else if (PARAM_IS ("clicking")) {
3188 if (Config->get_clicking()) {
3189 if (_click_io && click_data) { // don't require emphasis data
3196 } else if (PARAM_IS ("send-mtc")) {
3198 /* only set the internal flag if we have
3202 if (_mtc_port != 0) {
3203 session_send_mtc = Config->get_send_mtc();
3204 if (session_send_mtc) {
3205 /* mark us ready to send */
3206 next_quarter_frame_to_send = 0;
3209 session_send_mtc = false;
3212 } else if (PARAM_IS ("send-mmc")) {
3214 /* only set the internal flag if we have
3218 if (_mmc_port != 0) {
3219 session_send_mmc = Config->get_send_mmc();
3222 session_send_mmc = false;
3225 } else if (PARAM_IS ("midi-feedback")) {
3227 /* only set the internal flag if we have
3231 if (_mtc_port != 0) {
3232 session_midi_feedback = Config->get_midi_feedback();
3235 } else if (PARAM_IS ("jack-time-master")) {
3237 engine().reset_timebase ();
3239 } else if (PARAM_IS ("native-file-header-format")) {
3241 if (!first_file_header_format_reset) {
3242 reset_native_file_format ();
3245 first_file_header_format_reset = false;
3247 } else if (PARAM_IS ("native-file-data-format")) {
3249 if (!first_file_data_format_reset) {
3250 reset_native_file_format ();
3253 first_file_data_format_reset = false;
3255 } else if (PARAM_IS ("slave-source")) {
3256 set_slave_source (Config->get_slave_source());
3257 } else if (PARAM_IS ("remote-model")) {
3258 set_remote_control_ids ();
3259 } else if (PARAM_IS ("denormal-model")) {
3261 } else if (PARAM_IS ("history-depth")) {
3262 set_history_depth (Config->get_history_depth());
3263 } else if (PARAM_IS ("sync-all-route-ordering")) {
3264 sync_order_keys ("session");
3265 } else if (PARAM_IS ("initial-program-change")) {
3267 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3270 buf[0] = MIDI::program; // channel zero by default
3271 buf[1] = (Config->get_initial_program_change() & 0x7f);
3273 _mmc_port->midimsg (buf, sizeof (buf), 0);
3284 Session::set_history_depth (uint32_t d)
3286 _history.set_depth (d);