2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #define __STDC_FORMAT_MACROS 1
28 #include <sigc++/bind.h>
30 #include <cstdio> /* snprintf(3) ... grrr */
45 #include <sys/param.h>
46 #include <sys/mount.h>
50 #include <glibmm/thread.h>
52 #include <midi++/mmc.h>
53 #include <midi++/port.h>
55 #include <pbd/error.h>
56 #include <pbd/pathscanner.h>
57 #include <pbd/pthread_utils.h>
58 #include <pbd/search_path.h>
59 #include <pbd/stacktrace.h>
61 #include <ardour/audioengine.h>
62 #include <ardour/configuration.h>
63 #include <ardour/session.h>
64 #include <ardour/session_directory.h>
65 #include <ardour/session_utils.h>
66 #include <ardour/session_state_utils.h>
67 #include <ardour/session_metadata.h>
68 #include <ardour/buffer.h>
69 #include <ardour/audio_diskstream.h>
70 #include <ardour/midi_diskstream.h>
71 #include <ardour/utils.h>
72 #include <ardour/audioplaylist.h>
73 #include <ardour/midi_playlist.h>
74 #include <ardour/smf_source.h>
75 #include <ardour/audiofilesource.h>
76 #include <ardour/silentfilesource.h>
77 #include <ardour/sndfilesource.h>
78 #include <ardour/midi_source.h>
79 #include <ardour/sndfile_helpers.h>
80 #include <ardour/auditioner.h>
81 #include <ardour/io_processor.h>
82 #include <ardour/send.h>
83 #include <ardour/processor.h>
84 #include <ardour/bundle.h>
85 #include <ardour/slave.h>
86 #include <ardour/tempo.h>
87 #include <ardour/audio_track.h>
88 #include <ardour/midi_track.h>
89 #include <ardour/cycle_timer.h>
90 #include <ardour/utils.h>
91 #include <ardour/named_selection.h>
92 #include <ardour/version.h>
93 #include <ardour/location.h>
94 #include <ardour/audioregion.h>
95 #include <ardour/midi_region.h>
96 #include <ardour/crossfade.h>
97 #include <ardour/control_protocol_manager.h>
98 #include <ardour/region_factory.h>
99 #include <ardour/source_factory.h>
100 #include <ardour/playlist_factory.h>
101 #include <ardour/filename_extensions.h>
102 #include <ardour/directory_names.h>
103 #include <ardour/template_utils.h>
105 #include <control_protocol/control_protocol.h>
111 using namespace ARDOUR;
115 Session::first_stage_init (string fullpath, string snapshot_name)
117 if (fullpath.length() == 0) {
119 throw failed_constructor();
122 char buf[PATH_MAX+1];
123 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
124 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
126 throw failed_constructor();
131 if (_path[_path.length()-1] != '/') {
135 /* these two are just provisional settings. set_state()
136 will likely override them.
139 _name = _current_snapshot_name = snapshot_name;
141 set_history_depth (Config->get_history_depth());
143 _current_frame_rate = _engine.frame_rate ();
144 _nominal_frame_rate = _current_frame_rate;
145 _base_frame_rate = _current_frame_rate;
147 _tempo_map = new TempoMap (_current_frame_rate);
148 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
152 g_atomic_int_set (&processing_prohibited, 0);
154 _transport_speed = 0;
155 _last_transport_speed = 0;
156 auto_play_legal = false;
157 transport_sub_state = 0;
158 _transport_frame = 0;
160 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
161 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
162 _end_location_is_free = true;
163 g_atomic_int_set (&_record_status, Disabled);
164 loop_changing = false;
166 _last_roll_location = 0;
167 _last_record_location = 0;
168 pending_locate_frame = 0;
169 pending_locate_roll = false;
170 pending_locate_flush = false;
171 audio_dstream_buffer_size = 0;
172 midi_dstream_buffer_size = 0;
174 state_was_pending = false;
176 outbound_mtc_smpte_frame = 0;
177 next_quarter_frame_to_send = -1;
178 current_block_size = 0;
179 solo_update_disabled = false;
180 currently_soloing = false;
181 _have_captured = false;
182 _worst_output_latency = 0;
183 _worst_input_latency = 0;
184 _worst_track_latency = 0;
185 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
188 butler_mixdown_buffer = 0;
189 butler_gain_buffer = 0;
191 session_send_mmc = false;
192 session_send_mtc = false;
193 post_transport_work = PostTransportWork (0);
194 g_atomic_int_set (&butler_should_do_transport_work, 0);
195 g_atomic_int_set (&butler_active, 0);
196 g_atomic_int_set (&_playback_load, 100);
197 g_atomic_int_set (&_capture_load, 100);
198 g_atomic_int_set (&_playback_load_min, 100);
199 g_atomic_int_set (&_capture_load_min, 100);
202 _exporting_realtime = false;
203 _gain_automation_buffer = 0;
204 _pan_automation_buffer = 0;
206 pending_abort = false;
207 destructive_index = 0;
209 first_file_data_format_reset = true;
210 first_file_header_format_reset = true;
211 butler_thread = (pthread_t) 0;
212 //midi_thread = (pthread_t) 0;
214 AudioDiskstream::allocate_working_buffers();
216 /* default short fade = 15ms */
218 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
219 SndFileSource::setup_standard_crossfades (frame_rate());
221 last_mmc_step.tv_sec = 0;
222 last_mmc_step.tv_usec = 0;
225 /* click sounds are unset by default, which causes us to internal
226 waveforms for clicks.
230 click_emphasis_data = 0;
232 click_emphasis_length = 0;
235 process_function = &Session::process_with_events;
237 if (Config->get_use_video_sync()) {
238 waiting_for_sync_offset = true;
240 waiting_for_sync_offset = false;
245 _smpte_offset_negative = true;
246 last_smpte_valid = false;
250 last_rr_session_dir = session_dirs.begin();
251 refresh_disk_space ();
253 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
257 average_slave_delta = 1800;
258 have_first_delta_accumulator = false;
259 delta_accumulator_cnt = 0;
260 slave_state = Stopped;
262 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
264 /* These are all static "per-class" signals */
266 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
267 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
268 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
269 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
270 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
271 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
273 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
275 IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
277 /* stop IO objects from doing stuff until we're ready for them */
279 IO::disable_panners ();
280 IO::disable_ports ();
281 IO::disable_connecting ();
285 Session::second_stage_init (bool new_session)
287 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
290 if (load_state (_current_snapshot_name)) {
293 remove_empty_sounds ();
296 if (start_butler_thread()) {
300 if (start_midi_thread ()) {
304 // set_state() will call setup_raid_path(), but if it's a new session we need
305 // to call setup_raid_path() here.
308 if (set_state (*state_tree->root())) {
312 setup_raid_path(_path);
315 /* we can't save till after ::when_engine_running() is called,
316 because otherwise we save state with no connections made.
317 therefore, we reset _state_of_the_state because ::set_state()
318 will have cleared it.
320 we also have to include Loading so that any events that get
321 generated between here and the end of ::when_engine_running()
322 will be processed directly rather than queued.
325 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
328 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
329 _locations.added.connect (mem_fun (this, &Session::locations_added));
330 setup_click_sounds (0);
331 setup_midi_control ();
333 /* Pay attention ... */
335 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
336 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
339 when_engine_running();
342 /* handle this one in a different way than all others, so that its clear what happened */
344 catch (AudioEngine::PortRegistrationFailure& err) {
345 error << _("Unable to create all required ports")
354 BootMessage (_("Reset Remote Controls"));
356 send_full_time_code (0);
357 _engine.transport_locate (0);
358 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
359 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
361 BootMessage (_("Reset Control Protocols"));
363 ControlProtocolManager::instance().set_session (*this);
366 _end_location_is_free = true;
368 _end_location_is_free = false;
371 _state_of_the_state = Clean;
373 DirtyChanged (); /* EMIT SIGNAL */
375 if (state_was_pending) {
376 save_state (_current_snapshot_name);
377 remove_pending_capture_state ();
378 state_was_pending = false;
381 BootMessage (_("Session loading complete"));
387 Session::raid_path () const
389 SearchPath raid_search_path;
391 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
392 raid_search_path += sys::path((*i).path);
395 return raid_search_path.to_string ();
399 Session::setup_raid_path (string path)
408 session_dirs.clear ();
410 SearchPath search_path(path);
411 SearchPath sound_search_path;
412 SearchPath midi_search_path;
415 SearchPath::const_iterator i = search_path.begin();
416 i != search_path.end();
420 sp.path = (*i).to_string ();
421 sp.blocks = 0; // not needed
422 session_dirs.push_back (sp);
424 SessionDirectory sdir(sp.path);
426 sound_search_path += sdir.sound_path ();
427 midi_search_path += sdir.midi_path ();
430 // set the AudioFileSource and SMFSource search path
432 AudioFileSource::set_search_path (sound_search_path.to_string ());
433 SMFSource::set_search_path (midi_search_path.to_string ());
436 // reset the round-robin soundfile path thingie
438 last_rr_session_dir = session_dirs.begin();
442 Session::ensure_subdirs ()
446 dir = session_directory().peak_path().to_string();
448 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
449 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
453 dir = session_directory().sound_path().to_string();
455 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
456 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
460 dir = session_directory().midi_path().to_string();
462 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
463 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
467 dir = session_directory().dead_sound_path().to_string();
469 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
470 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
474 dir = session_directory().export_path().to_string();
476 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
477 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
481 dir = analysis_dir ();
483 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
484 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
492 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
495 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
496 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
500 if (ensure_subdirs ()) {
504 /* check new_session so we don't overwrite an existing one */
506 if (!mix_template.empty()) {
507 std::string in_path = mix_template;
509 ifstream in(in_path.c_str());
512 string out_path = _path;
514 out_path += statefile_suffix;
516 ofstream out(out_path.c_str());
521 // okay, session is set up. Treat like normal saved
522 // session from now on.
528 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
534 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
541 /* Instantiate metadata */
543 _metadata = new SessionMetadata ();
545 /* set initial start + end point */
547 start_location->set_end (0);
548 _locations.add (start_location);
550 end_location->set_end (initial_length);
551 _locations.add (end_location);
553 _state_of_the_state = Clean;
562 Session::load_diskstreams (const XMLNode& node)
565 XMLNodeConstIterator citer;
567 clist = node.children();
569 for (citer = clist.begin(); citer != clist.end(); ++citer) {
572 /* diskstreams added automatically by DiskstreamCreated handler */
573 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
574 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
575 add_diskstream (dstream);
576 } else if ((*citer)->name() == "MidiDiskstream") {
577 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
578 add_diskstream (dstream);
580 error << _("Session: unknown diskstream type in XML") << endmsg;
584 catch (failed_constructor& err) {
585 error << _("Session: could not load diskstream via XML state") << endmsg;
594 Session::maybe_write_autosave()
596 if (dirty() && record_status() != Recording) {
597 save_state("", true);
602 Session::remove_pending_capture_state ()
604 sys::path pending_state_file_path(_session_dir->root_path());
606 pending_state_file_path /= _current_snapshot_name + pending_suffix;
610 sys::remove (pending_state_file_path);
612 catch(sys::filesystem_error& ex)
614 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
615 pending_state_file_path.to_string(), ex.what()) << endmsg;
619 /** Rename a state file.
620 * @param snapshot_name Snapshot name.
623 Session::rename_state (string old_name, string new_name)
625 if (old_name == _current_snapshot_name || old_name == _name) {
626 /* refuse to rename the current snapshot or the "main" one */
630 const string old_xml_filename = old_name + statefile_suffix;
631 const string new_xml_filename = new_name + statefile_suffix;
633 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
634 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
638 sys::rename (old_xml_path, new_xml_path);
640 catch (const sys::filesystem_error& err)
642 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
643 old_name, new_name, err.what()) << endmsg;
647 /** Remove a state file.
648 * @param snapshot_name Snapshot name.
651 Session::remove_state (string snapshot_name)
653 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
654 // refuse to remove the current snapshot or the "main" one
658 sys::path xml_path(_session_dir->root_path());
660 xml_path /= snapshot_name + statefile_suffix;
662 if (!create_backup_file (xml_path)) {
663 // don't remove it if a backup can't be made
664 // create_backup_file will log the error.
669 sys::remove (xml_path);
673 Session::save_state (string snapshot_name, bool pending)
676 sys::path xml_path(_session_dir->root_path());
678 if (_state_of_the_state & CannotSave) {
682 if (!_engine.connected ()) {
683 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
688 /* tell sources we're saving first, in case they write out to a new file
689 * which should be saved with the state rather than the old one */
690 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
691 i->second->session_saved();
693 tree.set_root (&get_state());
695 if (snapshot_name.empty()) {
696 snapshot_name = _current_snapshot_name;
701 /* proper save: use statefile_suffix (.ardour in English) */
703 xml_path /= snapshot_name + statefile_suffix;
705 /* make a backup copy of the old file */
707 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
708 // create_backup_file will log the error
714 /* pending save: use pending_suffix (.pending in English) */
715 xml_path /= snapshot_name + pending_suffix;
718 sys::path tmp_path(_session_dir->root_path());
720 tmp_path /= snapshot_name + temp_suffix;
722 // cerr << "actually writing state to " << xml_path.to_string() << endl;
724 if (!tree.write (tmp_path.to_string())) {
725 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
726 sys::remove (tmp_path);
731 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
732 error << string_compose (_("could not rename temporary session file %1 to %2"),
733 tmp_path.to_string(), xml_path.to_string()) << endmsg;
734 sys::remove (tmp_path);
741 save_history (snapshot_name);
743 bool was_dirty = dirty();
745 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
748 DirtyChanged (); /* EMIT SIGNAL */
751 StateSaved (snapshot_name); /* EMIT SIGNAL */
758 Session::restore_state (string snapshot_name)
760 if (load_state (snapshot_name) == 0) {
761 set_state (*state_tree->root());
768 Session::load_state (string snapshot_name)
775 state_was_pending = false;
777 /* check for leftover pending state from a crashed capture attempt */
779 sys::path xmlpath(_session_dir->root_path());
780 xmlpath /= snapshot_name + pending_suffix;
782 if (sys::exists (xmlpath)) {
784 /* there is pending state from a crashed capture attempt */
786 if (AskAboutPendingState()) {
787 state_was_pending = true;
791 if (!state_was_pending) {
792 xmlpath = _session_dir->root_path();
793 xmlpath /= snapshot_name + statefile_suffix;
796 if (!sys::exists (xmlpath)) {
797 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
801 state_tree = new XMLTree;
805 if (!state_tree->read (xmlpath.to_string())) {
806 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
812 XMLNode& root (*state_tree->root());
814 if (root.name() != X_("Session")) {
815 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
821 const XMLProperty* prop;
822 bool is_old = false; // session is _very_ old (pre-2.0)
824 if ((prop = root.property ("version")) == 0) {
825 /* no version implies very old version of Ardour */
829 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
830 if (major_version < 2) {
837 sys::path backup_path(_session_dir->root_path());
839 backup_path /= snapshot_name + "-1" + statefile_suffix;
841 // only create a backup once
842 if (sys::exists (backup_path)) {
846 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
847 xmlpath.to_string(), backup_path.to_string())
852 sys::copy_file (xmlpath, backup_path);
854 catch(sys::filesystem_error& ex)
856 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
857 xmlpath.to_string(), ex.what())
867 Session::load_options (const XMLNode& node)
871 LocaleGuard lg (X_("POSIX"));
873 Config->set_variables (node, ConfigVariableBase::Session);
875 /* now reset MIDI ports because the session can have its own
881 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
882 if ((prop = child->property ("val")) != 0) {
883 _end_location_is_free = (prop->value() == "yes");
891 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
893 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
894 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
896 return owner & modified_by_session_or_user;
900 Session::get_options () const
903 LocaleGuard lg (X_("POSIX"));
905 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
907 child = option_root.add_child ("end-marker-is-free");
908 child->add_property ("val", _end_location_is_free ? "yes" : "no");
920 Session::get_template()
922 /* if we don't disable rec-enable, diskstreams
923 will believe they need to store their capture
924 sources in their state node.
927 disable_record (false);
933 Session::state(bool full_state)
935 XMLNode* node = new XMLNode("Session");
938 // store libardour version, just in case
940 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
941 node->add_property("version", string(buf));
943 /* store configuration settings */
947 node->add_property ("name", _name);
948 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
949 node->add_property ("sample-rate", buf);
951 if (session_dirs.size() > 1) {
955 vector<space_and_path>::iterator i = session_dirs.begin();
956 vector<space_and_path>::iterator next;
958 ++i; /* skip the first one */
962 while (i != session_dirs.end()) {
966 if (next != session_dirs.end()) {
976 child = node->add_child ("Path");
977 child->add_content (p);
981 /* save the ID counter */
983 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
984 node->add_property ("id-counter", buf);
986 /* various options */
988 node->add_child_nocopy (get_options());
990 node->add_child_nocopy (_metadata->get_state());
992 child = node->add_child ("Sources");
995 Glib::Mutex::Lock sl (source_lock);
997 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
999 /* Don't save information about AudioFileSources that are empty */
1001 boost::shared_ptr<AudioFileSource> fs;
1003 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
1005 /* Don't save sources that are empty, unless they're destructive (which are OK
1006 if they are empty, because we will re-use them every time.)
1009 if (!fs->destructive()) {
1010 if (fs->length() == 0) {
1016 child->add_child_nocopy (siter->second->get_state());
1020 child = node->add_child ("Regions");
1023 Glib::Mutex::Lock rl (region_lock);
1025 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
1027 /* only store regions not attached to playlists */
1029 if (i->second->playlist() == 0) {
1030 child->add_child_nocopy (i->second->state (true));
1035 child = node->add_child ("DiskStreams");
1038 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1039 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1040 if (!(*i)->hidden()) {
1041 child->add_child_nocopy ((*i)->get_state());
1047 node->add_child_nocopy (_locations.get_state());
1049 // for a template, just create a new Locations, populate it
1050 // with the default start and end, and get the state for that.
1052 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1053 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1056 end->set_end(compute_initial_length());
1058 node->add_child_nocopy (loc.get_state());
1061 child = node->add_child ("Bundles");
1063 Glib::Mutex::Lock lm (bundle_lock);
1064 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
1065 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1067 child->add_child_nocopy (b->get_state());
1072 child = node->add_child ("Routes");
1074 boost::shared_ptr<RouteList> r = routes.reader ();
1076 RoutePublicOrderSorter cmp;
1077 RouteList public_order (*r);
1078 public_order.sort (cmp);
1080 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1081 if (!(*i)->is_hidden()) {
1083 child->add_child_nocopy ((*i)->get_state());
1085 child->add_child_nocopy ((*i)->get_template());
1092 child = node->add_child ("EditGroups");
1093 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1094 child->add_child_nocopy ((*i)->get_state());
1097 child = node->add_child ("MixGroups");
1098 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1099 child->add_child_nocopy ((*i)->get_state());
1102 child = node->add_child ("Playlists");
1103 for (PlaylistList::iterator i = playlists.begin(); i != 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());
1115 child = node->add_child ("UnusedPlaylists");
1116 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1117 if (!(*i)->hidden()) {
1118 if (!(*i)->empty()) {
1120 child->add_child_nocopy ((*i)->get_state());
1122 child->add_child_nocopy ((*i)->get_template());
1130 child = node->add_child ("Click");
1131 child->add_child_nocopy (_click_io->state (full_state));
1135 child = node->add_child ("NamedSelections");
1136 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1138 child->add_child_nocopy ((*i)->get_state());
1143 node->add_child_nocopy (_tempo_map->get_state());
1145 node->add_child_nocopy (get_control_protocol_state());
1148 node->add_child_copy (*_extra_xml);
1155 Session::get_control_protocol_state ()
1157 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1158 return cpm.get_state();
1162 Session::set_state (const XMLNode& node)
1166 const XMLProperty* prop;
1169 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1171 if (node.name() != X_("Session")){
1172 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1176 if ((prop = node.property ("name")) != 0) {
1177 _name = prop->value ();
1180 if ((prop = node.property (X_("sample-rate"))) != 0) {
1182 _nominal_frame_rate = atoi (prop->value());
1184 if (_nominal_frame_rate != _current_frame_rate) {
1185 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1191 setup_raid_path(_session_dir->root_path().to_string());
1193 if ((prop = node.property (X_("id-counter"))) != 0) {
1195 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1196 ID::init_counter (x);
1198 /* old sessions used a timebased counter, so fake
1199 the startup ID counter based on a standard
1204 ID::init_counter (now);
1208 IO::disable_ports ();
1209 IO::disable_connecting ();
1211 /* Object loading order:
1216 MIDI Control // relies on data from Options/Config
1230 if ((child = find_named_node (node, "extra")) != 0) {
1231 _extra_xml = new XMLNode (*child);
1234 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1235 load_options (*child);
1236 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1237 load_options (*child);
1239 error << _("Session: XML state has no options section") << endmsg;
1242 if (use_config_midi_ports ()) {
1245 if ((child = find_named_node (node, "Metadata")) == 0) {
1246 warning << _("Session: XML state has no metadata section (2.0 session?)") << endmsg;
1247 } else if (_metadata->set_state (*child)) {
1251 if ((child = find_named_node (node, "Locations")) == 0) {
1252 error << _("Session: XML state has no locations section") << endmsg;
1254 } else if (_locations.set_state (*child)) {
1260 if ((location = _locations.auto_loop_location()) != 0) {
1261 set_auto_loop_location (location);
1264 if ((location = _locations.auto_punch_location()) != 0) {
1265 set_auto_punch_location (location);
1268 if ((location = _locations.end_location()) == 0) {
1269 _locations.add (end_location);
1271 delete end_location;
1272 end_location = location;
1275 if ((location = _locations.start_location()) == 0) {
1276 _locations.add (start_location);
1278 delete start_location;
1279 start_location = location;
1282 AudioFileSource::set_header_position_offset (start_location->start());
1284 if ((child = find_named_node (node, "Sources")) == 0) {
1285 error << _("Session: XML state has no sources section") << endmsg;
1287 } else if (load_sources (*child)) {
1291 if ((child = find_named_node (node, "Regions")) == 0) {
1292 error << _("Session: XML state has no Regions section") << endmsg;
1294 } else if (load_regions (*child)) {
1298 if ((child = find_named_node (node, "Playlists")) == 0) {
1299 error << _("Session: XML state has no playlists section") << endmsg;
1301 } else if (load_playlists (*child)) {
1305 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1307 } else if (load_unused_playlists (*child)) {
1311 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1312 if (load_named_selections (*child)) {
1317 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1318 error << _("Session: XML state has no diskstreams section") << endmsg;
1320 } else if (load_diskstreams (*child)) {
1324 if ((child = find_named_node (node, "Bundles")) == 0) {
1325 warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg;
1328 /* We can't load Bundles yet as they need to be able
1329 to convert from port names to Port objects, which can't happen until
1331 _bundle_xml_node = new XMLNode (*child);
1334 if ((child = find_named_node (node, "EditGroups")) == 0) {
1335 error << _("Session: XML state has no edit groups section") << endmsg;
1337 } else if (load_edit_groups (*child)) {
1341 if ((child = find_named_node (node, "MixGroups")) == 0) {
1342 error << _("Session: XML state has no mix groups section") << endmsg;
1344 } else if (load_mix_groups (*child)) {
1348 if ((child = find_named_node (node, "TempoMap")) == 0) {
1349 error << _("Session: XML state has no Tempo Map section") << endmsg;
1351 } else if (_tempo_map->set_state (*child)) {
1355 if ((child = find_named_node (node, "Routes")) == 0) {
1356 error << _("Session: XML state has no routes section") << endmsg;
1358 } else if (load_routes (*child)) {
1362 if ((child = find_named_node (node, "Click")) == 0) {
1363 warning << _("Session: XML state has no click section") << endmsg;
1364 } else if (_click_io) {
1365 _click_io->set_state (*child);
1368 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1369 ControlProtocolManager::instance().set_protocol_states (*child);
1372 /* here beginneth the second phase ... */
1374 StateReady (); /* EMIT SIGNAL */
1383 Session::load_routes (const XMLNode& node)
1386 XMLNodeConstIterator niter;
1387 RouteList new_routes;
1389 nlist = node.children();
1393 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1395 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1398 error << _("Session: cannot create Route from XML description.") << endmsg;
1402 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1404 new_routes.push_back (route);
1407 add_routes (new_routes, false);
1412 boost::shared_ptr<Route>
1413 Session::XMLRouteFactory (const XMLNode& node)
1415 if (node.name() != "Route") {
1416 return boost::shared_ptr<Route> ((Route*) 0);
1419 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1421 DataType type = DataType::AUDIO;
1422 const XMLProperty* prop = node.property("default-type");
1424 type = DataType(prop->value());
1426 assert(type != DataType::NIL);
1428 if (has_diskstream) {
1429 if (type == DataType::AUDIO) {
1430 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1433 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1437 boost::shared_ptr<Route> ret (new Route (*this, node));
1443 Session::load_regions (const XMLNode& node)
1446 XMLNodeConstIterator niter;
1447 boost::shared_ptr<Region> region;
1449 nlist = node.children();
1453 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1454 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1455 error << _("Session: cannot create Region from XML description.");
1456 const XMLProperty *name = (**niter).property("name");
1459 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1469 boost::shared_ptr<Region>
1470 Session::XMLRegionFactory (const XMLNode& node, bool full)
1472 const XMLProperty* type = node.property("type");
1476 if ( !type || type->value() == "audio" ) {
1478 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1480 } else if (type->value() == "midi") {
1482 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1486 } catch (failed_constructor& err) {
1487 return boost::shared_ptr<Region> ();
1490 return boost::shared_ptr<Region> ();
1493 boost::shared_ptr<AudioRegion>
1494 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1496 const XMLProperty* prop;
1497 boost::shared_ptr<Source> source;
1498 boost::shared_ptr<AudioSource> as;
1500 SourceList master_sources;
1501 uint32_t nchans = 1;
1504 if (node.name() != X_("Region")) {
1505 return boost::shared_ptr<AudioRegion>();
1508 if ((prop = node.property (X_("channels"))) != 0) {
1509 nchans = atoi (prop->value().c_str());
1512 if ((prop = node.property ("name")) == 0) {
1513 cerr << "no name for this region\n";
1517 if ((prop = node.property (X_("source-0"))) == 0) {
1518 if ((prop = node.property ("source")) == 0) {
1519 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1520 return boost::shared_ptr<AudioRegion>();
1524 PBD::ID s_id (prop->value());
1526 if ((source = source_by_id (s_id)) == 0) {
1527 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1528 return boost::shared_ptr<AudioRegion>();
1531 as = boost::dynamic_pointer_cast<AudioSource>(source);
1533 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1534 return boost::shared_ptr<AudioRegion>();
1537 sources.push_back (as);
1539 /* pickup other channels */
1541 for (uint32_t n=1; n < nchans; ++n) {
1542 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1543 if ((prop = node.property (buf)) != 0) {
1545 PBD::ID id2 (prop->value());
1547 if ((source = source_by_id (id2)) == 0) {
1548 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1549 return boost::shared_ptr<AudioRegion>();
1552 as = boost::dynamic_pointer_cast<AudioSource>(source);
1554 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1555 return boost::shared_ptr<AudioRegion>();
1557 sources.push_back (as);
1561 for (uint32_t n=1; n < nchans; ++n) {
1562 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1563 if ((prop = node.property (buf)) != 0) {
1565 PBD::ID id2 (prop->value());
1567 if ((source = source_by_id (id2)) == 0) {
1568 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1569 return boost::shared_ptr<AudioRegion>();
1572 as = boost::dynamic_pointer_cast<AudioSource>(source);
1574 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1575 return boost::shared_ptr<AudioRegion>();
1577 master_sources.push_back (as);
1582 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1584 /* a final detail: this is the one and only place that we know how long missing files are */
1586 if (region->whole_file()) {
1587 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1588 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1590 sfp->set_length (region->length());
1595 if (!master_sources.empty()) {
1596 if (master_sources.size() == nchans) {
1597 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1599 region->set_master_sources (master_sources);
1607 catch (failed_constructor& err) {
1608 return boost::shared_ptr<AudioRegion>();
1612 boost::shared_ptr<MidiRegion>
1613 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1615 const XMLProperty* prop;
1616 boost::shared_ptr<Source> source;
1617 boost::shared_ptr<MidiSource> ms;
1619 uint32_t nchans = 1;
1621 if (node.name() != X_("Region")) {
1622 return boost::shared_ptr<MidiRegion>();
1625 if ((prop = node.property (X_("channels"))) != 0) {
1626 nchans = atoi (prop->value().c_str());
1629 if ((prop = node.property ("name")) == 0) {
1630 cerr << "no name for this region\n";
1634 // Multiple midi channels? that's just crazy talk
1635 assert(nchans == 1);
1637 if ((prop = node.property (X_("source-0"))) == 0) {
1638 if ((prop = node.property ("source")) == 0) {
1639 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1640 return boost::shared_ptr<MidiRegion>();
1644 PBD::ID s_id (prop->value());
1646 if ((source = source_by_id (s_id)) == 0) {
1647 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1648 return boost::shared_ptr<MidiRegion>();
1651 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1653 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1654 return boost::shared_ptr<MidiRegion>();
1657 sources.push_back (ms);
1660 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1661 /* a final detail: this is the one and only place that we know how long missing files are */
1663 if (region->whole_file()) {
1664 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1665 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1667 sfp->set_length (region->length());
1675 catch (failed_constructor& err) {
1676 return boost::shared_ptr<MidiRegion>();
1681 Session::get_sources_as_xml ()
1684 XMLNode* node = new XMLNode (X_("Sources"));
1685 Glib::Mutex::Lock lm (source_lock);
1687 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1688 node->add_child_nocopy (i->second->get_state());
1695 Session::path_from_region_name (DataType type, string name, string identifier)
1697 char buf[PATH_MAX+1];
1699 SessionDirectory sdir(get_best_session_directory_for_new_source());
1700 sys::path source_dir = ((type == DataType::AUDIO)
1701 ? sdir.sound_path() : sdir.midi_path());
1703 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1705 for (n = 0; n < 999999; ++n) {
1706 if (identifier.length()) {
1707 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1708 identifier.c_str(), n, ext.c_str());
1710 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1714 sys::path source_path = source_dir / buf;
1716 if (!sys::exists (source_path)) {
1717 return source_path.to_string();
1721 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1730 Session::load_sources (const XMLNode& node)
1733 XMLNodeConstIterator niter;
1734 boost::shared_ptr<Source> source;
1736 nlist = node.children();
1740 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1743 if ((source = XMLSourceFactory (**niter)) == 0) {
1744 error << _("Session: cannot create Source from XML description.") << endmsg;
1748 catch (non_existent_source& err) {
1749 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1750 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1757 boost::shared_ptr<Source>
1758 Session::XMLSourceFactory (const XMLNode& node)
1760 if (node.name() != "Source") {
1761 return boost::shared_ptr<Source>();
1765 /* note: do peak building in another thread when loading session state */
1766 return SourceFactory::create (*this, node, true);
1769 catch (failed_constructor& err) {
1770 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1771 return boost::shared_ptr<Source>();
1776 Session::save_template (string template_name)
1780 if (_state_of_the_state & CannotSave) {
1784 sys::path user_template_dir(user_template_directory());
1788 sys::create_directories (user_template_dir);
1790 catch(sys::filesystem_error& ex)
1792 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1793 user_template_dir.to_string(), ex.what()) << endmsg;
1797 tree.set_root (&get_template());
1799 sys::path template_file_path(user_template_dir);
1800 template_file_path /= template_name + template_suffix;
1802 if (sys::exists (template_file_path))
1804 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1805 template_file_path.to_string()) << endmsg;
1809 if (!tree.write (template_file_path.to_string())) {
1810 error << _("mix template not saved") << endmsg;
1818 Session::rename_template (string old_name, string new_name)
1820 sys::path old_path (user_template_directory());
1821 old_path /= old_name + template_suffix;
1823 sys::path new_path(user_template_directory());
1824 new_path /= new_name + template_suffix;
1826 if (sys::exists (new_path)) {
1827 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1828 new_path.to_string()) << endmsg;
1833 sys::rename (old_path, new_path);
1841 Session::delete_template (string name)
1843 sys::path path = user_template_directory();
1844 path /= name + template_suffix;
1855 Session::refresh_disk_space ()
1858 struct statfs statfsbuf;
1859 vector<space_and_path>::iterator i;
1860 Glib::Mutex::Lock lm (space_lock);
1863 /* get freespace on every FS that is part of the session path */
1865 _total_free_4k_blocks = 0;
1867 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1868 statfs ((*i).path.c_str(), &statfsbuf);
1870 scale = statfsbuf.f_bsize/4096.0;
1872 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1873 _total_free_4k_blocks += (*i).blocks;
1879 Session::get_best_session_directory_for_new_source ()
1881 vector<space_and_path>::iterator i;
1882 string result = _session_dir->root_path().to_string();
1884 /* handle common case without system calls */
1886 if (session_dirs.size() == 1) {
1890 /* OK, here's the algorithm we're following here:
1892 We want to select which directory to use for
1893 the next file source to be created. Ideally,
1894 we'd like to use a round-robin process so as to
1895 get maximum performance benefits from splitting
1896 the files across multiple disks.
1898 However, in situations without much diskspace, an
1899 RR approach may end up filling up a filesystem
1900 with new files while others still have space.
1901 Its therefore important to pay some attention to
1902 the freespace in the filesystem holding each
1903 directory as well. However, if we did that by
1904 itself, we'd keep creating new files in the file
1905 system with the most space until it was as full
1906 as all others, thus negating any performance
1907 benefits of this RAID-1 like approach.
1909 So, we use a user-configurable space threshold. If
1910 there are at least 2 filesystems with more than this
1911 much space available, we use RR selection between them.
1912 If not, then we pick the filesystem with the most space.
1914 This gets a good balance between the two
1918 refresh_disk_space ();
1920 int free_enough = 0;
1922 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1923 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1928 if (free_enough >= 2) {
1929 /* use RR selection process, ensuring that the one
1933 i = last_rr_session_dir;
1936 if (++i == session_dirs.end()) {
1937 i = session_dirs.begin();
1940 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1941 if (create_session_directory ((*i).path)) {
1943 last_rr_session_dir = i;
1948 } while (i != last_rr_session_dir);
1952 /* pick FS with the most freespace (and that
1953 seems to actually work ...)
1956 vector<space_and_path> sorted;
1957 space_and_path_ascending_cmp cmp;
1959 sorted = session_dirs;
1960 sort (sorted.begin(), sorted.end(), cmp);
1962 for (i = sorted.begin(); i != sorted.end(); ++i) {
1963 if (create_session_directory ((*i).path)) {
1965 last_rr_session_dir = i;
1975 Session::load_playlists (const XMLNode& node)
1978 XMLNodeConstIterator niter;
1979 boost::shared_ptr<Playlist> playlist;
1981 nlist = node.children();
1985 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1987 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1988 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1996 Session::load_unused_playlists (const XMLNode& node)
1999 XMLNodeConstIterator niter;
2000 boost::shared_ptr<Playlist> playlist;
2002 nlist = node.children();
2006 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2008 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2009 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2013 // now manually untrack it
2015 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
2021 boost::shared_ptr<Playlist>
2022 Session::XMLPlaylistFactory (const XMLNode& node)
2025 return PlaylistFactory::create (*this, node);
2028 catch (failed_constructor& err) {
2029 return boost::shared_ptr<Playlist>();
2034 Session::load_named_selections (const XMLNode& node)
2037 XMLNodeConstIterator niter;
2040 nlist = node.children();
2044 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2046 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2047 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2055 Session::XMLNamedSelectionFactory (const XMLNode& node)
2058 return new NamedSelection (*this, node);
2061 catch (failed_constructor& err) {
2067 Session::automation_dir () const
2069 return Glib::build_filename (_path, "automation");
2073 Session::analysis_dir () const
2075 return Glib::build_filename (_path, "analysis");
2079 Session::load_bundles (XMLNode const & node)
2081 XMLNodeList nlist = node.children();
2082 XMLNodeConstIterator niter;
2086 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2087 if ((*niter)->name() == "InputBundle") {
2088 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2089 } else if ((*niter)->name() == "OutputBundle") {
2090 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2092 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2101 Session::load_edit_groups (const XMLNode& node)
2103 return load_route_groups (node, true);
2107 Session::load_mix_groups (const XMLNode& node)
2109 return load_route_groups (node, false);
2113 Session::load_route_groups (const XMLNode& node, bool edit)
2115 XMLNodeList nlist = node.children();
2116 XMLNodeConstIterator niter;
2121 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2122 if ((*niter)->name() == "RouteGroup") {
2124 rg = add_edit_group ("");
2125 rg->set_state (**niter);
2127 rg = add_mix_group ("");
2128 rg->set_state (**niter);
2137 Session::auto_save()
2139 save_state (_current_snapshot_name);
2143 state_file_filter (const string &str, void *arg)
2145 return (str.length() > strlen(statefile_suffix) &&
2146 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2150 bool operator()(const string* a, const string* b) {
2156 remove_end(string* state)
2158 string statename(*state);
2160 string::size_type start,end;
2161 if ((start = statename.find_last_of ('/')) != string::npos) {
2162 statename = statename.substr (start+1);
2165 if ((end = statename.rfind(".ardour")) == string::npos) {
2166 end = statename.length();
2169 return new string(statename.substr (0, end));
2173 Session::possible_states (string path)
2175 PathScanner scanner;
2176 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2178 transform(states->begin(), states->end(), states->begin(), remove_end);
2181 sort (states->begin(), states->end(), cmp);
2187 Session::possible_states () const
2189 return possible_states(_path);
2193 Session::add_edit_group (string name)
2195 RouteGroup* rg = new RouteGroup (*this, name);
2196 edit_groups.push_back (rg);
2197 edit_group_added (rg); /* EMIT SIGNAL */
2203 Session::add_mix_group (string name)
2205 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2206 mix_groups.push_back (rg);
2207 mix_group_added (rg); /* EMIT SIGNAL */
2213 Session::remove_edit_group (RouteGroup& rg)
2215 list<RouteGroup*>::iterator i;
2217 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2218 (*i)->apply (&Route::drop_edit_group, this);
2219 edit_groups.erase (i);
2220 edit_group_removed (); /* EMIT SIGNAL */
2227 Session::remove_mix_group (RouteGroup& rg)
2229 list<RouteGroup*>::iterator i;
2231 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2232 (*i)->apply (&Route::drop_mix_group, this);
2233 mix_groups.erase (i);
2234 mix_group_removed (); /* EMIT SIGNAL */
2241 Session::mix_group_by_name (string name)
2243 list<RouteGroup *>::iterator i;
2245 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2246 if ((*i)->name() == name) {
2254 Session::edit_group_by_name (string name)
2256 list<RouteGroup *>::iterator i;
2258 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2259 if ((*i)->name() == name) {
2267 Session::begin_reversible_command (const string& name)
2269 current_trans = new UndoTransaction;
2270 current_trans->set_name (name);
2274 Session::commit_reversible_command (Command *cmd)
2279 current_trans->add_command (cmd);
2282 if (current_trans->empty()) {
2286 gettimeofday (&now, 0);
2287 current_trans->set_timestamp (now);
2289 _history.add (current_trans);
2292 Session::GlobalRouteBooleanState
2293 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2295 GlobalRouteBooleanState s;
2296 boost::shared_ptr<RouteList> r = routes.reader ();
2298 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2299 if (!(*i)->is_hidden()) {
2300 RouteBooleanState v;
2303 Route* r = (*i).get();
2304 v.second = (r->*method)();
2313 Session::GlobalRouteMeterState
2314 Session::get_global_route_metering ()
2316 GlobalRouteMeterState s;
2317 boost::shared_ptr<RouteList> r = routes.reader ();
2319 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2320 if (!(*i)->is_hidden()) {
2324 v.second = (*i)->meter_point();
2334 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2336 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2338 boost::shared_ptr<Route> r = (i->first.lock());
2341 r->set_meter_point (i->second, arg);
2347 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2349 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2351 boost::shared_ptr<Route> r = (i->first.lock());
2354 Route* rp = r.get();
2355 (rp->*method) (i->second, arg);
2361 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2363 set_global_route_boolean (s, &Route::set_mute, src);
2367 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2369 set_global_route_boolean (s, &Route::set_solo, src);
2373 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2375 set_global_route_boolean (s, &Route::set_record_enable, src);
2380 Session::global_mute_memento (void* src)
2382 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2386 Session::global_metering_memento (void* src)
2388 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2392 Session::global_solo_memento (void* src)
2394 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2398 Session::global_record_enable_memento (void* src)
2400 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2405 accept_all_non_peak_files (const string& path, void *arg)
2407 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2411 accept_all_state_files (const string& path, void *arg)
2413 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2417 Session::find_all_sources (string path, set<string>& result)
2422 if (!tree.read (path)) {
2426 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2431 XMLNodeConstIterator niter;
2433 nlist = node->children();
2437 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2441 if ((prop = (*niter)->property (X_("name"))) == 0) {
2445 if (prop->value()[0] == '/') {
2446 /* external file, ignore */
2450 sys::path source_path = _session_dir->sound_path ();
2452 source_path /= prop->value ();
2454 result.insert (source_path.to_string ());
2461 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2463 PathScanner scanner;
2464 vector<string*>* state_files;
2466 string this_snapshot_path;
2472 if (ripped[ripped.length()-1] == '/') {
2473 ripped = ripped.substr (0, ripped.length() - 1);
2476 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2478 if (state_files == 0) {
2483 this_snapshot_path = _path;
2484 this_snapshot_path += _current_snapshot_name;
2485 this_snapshot_path += statefile_suffix;
2487 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2489 if (exclude_this_snapshot && **i == this_snapshot_path) {
2493 if (find_all_sources (**i, result) < 0) {
2501 struct RegionCounter {
2502 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2503 AudioSourceList::iterator iter;
2504 boost::shared_ptr<Region> region;
2507 RegionCounter() : count (0) {}
2511 Session::cleanup_sources (Session::cleanup_report& rep)
2513 // FIXME: needs adaptation to midi
2515 vector<boost::shared_ptr<Source> > dead_sources;
2516 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2517 PathScanner scanner;
2519 vector<space_and_path>::iterator i;
2520 vector<space_and_path>::iterator nexti;
2521 vector<string*>* soundfiles;
2522 vector<string> unused;
2523 set<string> all_sources;
2528 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2531 /* step 1: consider deleting all unused playlists */
2533 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2536 status = AskAboutPlaylistDeletion (*x);
2545 playlists_tbd.push_back (*x);
2549 /* leave it alone */
2554 /* now delete any that were marked for deletion */
2556 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2557 (*x)->drop_references ();
2560 playlists_tbd.clear ();
2562 /* step 2: find all un-used sources */
2567 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2569 SourceMap::iterator tmp;
2574 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2578 if (!i->second->used() && i->second->length() > 0) {
2579 dead_sources.push_back (i->second);
2580 i->second->GoingAway();
2586 /* build a list of all the possible sound directories for the session */
2588 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2593 SessionDirectory sdir ((*i).path);
2594 sound_path += sdir.sound_path().to_string();
2596 if (nexti != session_dirs.end()) {
2603 /* now do the same thing for the files that ended up in the sounds dir(s)
2604 but are not referenced as sources in any snapshot.
2607 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2609 if (soundfiles == 0) {
2613 /* find all sources, but don't use this snapshot because the
2614 state file on disk still references sources we may have already
2618 find_all_sources_across_snapshots (all_sources, true);
2620 /* add our current source list
2623 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2624 boost::shared_ptr<AudioFileSource> fs;
2626 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2627 all_sources.insert (fs->path());
2631 char tmppath1[PATH_MAX+1];
2632 char tmppath2[PATH_MAX+1];
2634 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2639 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2641 realpath(spath.c_str(), tmppath1);
2642 realpath((*i).c_str(), tmppath2);
2644 if (strcmp(tmppath1, tmppath2) == 0) {
2651 unused.push_back (spath);
2655 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2657 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2658 struct stat statbuf;
2660 rep.paths.push_back (*x);
2661 if (stat ((*x).c_str(), &statbuf) == 0) {
2662 rep.space += statbuf.st_size;
2667 /* don't move the file across filesystems, just
2668 stick it in the `dead_sound_dir_name' directory
2669 on whichever filesystem it was already on.
2672 if ((*x).find ("/sounds/") != string::npos) {
2674 /* old school, go up 1 level */
2676 newpath = Glib::path_get_dirname (*x); // "sounds"
2677 newpath = Glib::path_get_dirname (newpath); // "session-name"
2681 /* new school, go up 4 levels */
2683 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2684 newpath = Glib::path_get_dirname (newpath); // "session-name"
2685 newpath = Glib::path_get_dirname (newpath); // "interchange"
2686 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2690 newpath += dead_sound_dir_name;
2692 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2693 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2698 newpath += Glib::path_get_basename ((*x));
2700 if (access (newpath.c_str(), F_OK) == 0) {
2702 /* the new path already exists, try versioning */
2704 char buf[PATH_MAX+1];
2708 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2711 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2712 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2716 if (version == 999) {
2717 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2721 newpath = newpath_v;
2726 /* it doesn't exist, or we can't read it or something */
2730 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2731 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2732 (*x), newpath, strerror (errno))
2737 /* see if there an easy to find peakfile for this file, and remove it.
2740 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2741 peakpath += peakfile_suffix;
2743 if (access (peakpath.c_str(), W_OK) == 0) {
2744 if (::unlink (peakpath.c_str()) != 0) {
2745 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2746 peakpath, _path, strerror (errno))
2748 /* try to back out */
2749 rename (newpath.c_str(), _path.c_str());
2757 /* dump the history list */
2761 /* save state so we don't end up a session file
2762 referring to non-existent sources.
2768 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2774 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2776 // FIXME: needs adaptation for MIDI
2778 vector<space_and_path>::iterator i;
2779 string dead_sound_dir;
2780 struct dirent* dentry;
2781 struct stat statbuf;
2787 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2789 dead_sound_dir = (*i).path;
2790 dead_sound_dir += dead_sound_dir_name;
2792 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2796 while ((dentry = readdir (dead)) != 0) {
2798 /* avoid '.' and '..' */
2800 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2801 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2807 fullpath = dead_sound_dir;
2809 fullpath += dentry->d_name;
2811 if (stat (fullpath.c_str(), &statbuf)) {
2815 if (!S_ISREG (statbuf.st_mode)) {
2819 if (unlink (fullpath.c_str())) {
2820 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2821 fullpath, strerror (errno))
2825 rep.paths.push_back (dentry->d_name);
2826 rep.space += statbuf.st_size;
2837 Session::set_dirty ()
2839 bool was_dirty = dirty();
2841 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2845 DirtyChanged(); /* EMIT SIGNAL */
2851 Session::set_clean ()
2853 bool was_dirty = dirty();
2855 _state_of_the_state = Clean;
2859 DirtyChanged(); /* EMIT SIGNAL */
2864 Session::set_deletion_in_progress ()
2866 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2871 Session::add_controllable (boost::shared_ptr<Controllable> c)
2873 /* this adds a controllable to the list managed by the Session.
2874 this is a subset of those managed by the Controllable class
2875 itself, and represents the only ones whose state will be saved
2876 as part of the session.
2879 Glib::Mutex::Lock lm (controllables_lock);
2880 controllables.insert (c);
2883 struct null_deleter { void operator()(void const *) const {} };
2886 Session::remove_controllable (Controllable* c)
2888 if (_state_of_the_state | Deletion) {
2892 Glib::Mutex::Lock lm (controllables_lock);
2894 Controllables::iterator x = controllables.find(
2895 boost::shared_ptr<Controllable>(c, null_deleter()));
2897 if (x != controllables.end()) {
2898 controllables.erase (x);
2902 boost::shared_ptr<Controllable>
2903 Session::controllable_by_id (const PBD::ID& id)
2905 Glib::Mutex::Lock lm (controllables_lock);
2907 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2908 if ((*i)->id() == id) {
2913 return boost::shared_ptr<Controllable>();
2917 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2919 Stateful::add_instant_xml (node, _path);
2920 if (write_to_config) {
2921 Config->add_instant_xml (node);
2926 Session::instant_xml (const string& node_name)
2928 return Stateful::instant_xml (node_name, _path);
2932 Session::save_history (string snapshot_name)
2936 if (snapshot_name.empty()) {
2937 snapshot_name = _current_snapshot_name;
2940 const string history_filename = snapshot_name + history_suffix;
2941 const string backup_filename = history_filename + backup_suffix;
2942 const sys::path xml_path = _session_dir->root_path() / history_filename;
2943 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2945 if (sys::exists (xml_path)) {
2948 sys::rename (xml_path, backup_path);
2950 catch (const sys::filesystem_error& err)
2952 error << _("could not backup old history file, current history not saved") << endmsg;
2958 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2962 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2964 if (!tree.write (xml_path.to_string()))
2966 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2970 sys::remove (xml_path);
2971 sys::rename (backup_path, xml_path);
2973 catch (const sys::filesystem_error& err)
2975 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2976 backup_path.to_string(), err.what()) << endmsg;
2986 Session::restore_history (string snapshot_name)
2990 if (snapshot_name.empty()) {
2991 snapshot_name = _current_snapshot_name;
2994 const string xml_filename = snapshot_name + history_suffix;
2995 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2997 cerr << "Loading history from " << xml_path.to_string() << endmsg;
2999 if (!sys::exists (xml_path)) {
3000 info << string_compose (_("%1: no history file \"%2\" for this session."),
3001 _name, xml_path.to_string()) << endmsg;
3005 if (!tree.read (xml_path.to_string())) {
3006 error << string_compose (_("Could not understand session history file \"%1\""),
3007 xml_path.to_string()) << endmsg;
3014 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3017 UndoTransaction* ut = new UndoTransaction ();
3020 ut->set_name(t->property("name")->value());
3021 stringstream ss(t->property("tv-sec")->value());
3023 ss.str(t->property("tv-usec")->value());
3025 ut->set_timestamp(tv);
3027 for (XMLNodeConstIterator child_it = t->children().begin();
3028 child_it != t->children().end(); child_it++)
3030 XMLNode *n = *child_it;
3033 if (n->name() == "MementoCommand" ||
3034 n->name() == "MementoUndoCommand" ||
3035 n->name() == "MementoRedoCommand") {
3037 if ((c = memento_command_factory(n))) {
3041 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3043 if ((c = global_state_command_factory (*n))) {
3044 ut->add_command (c);
3047 } else if (n->name() == "DeltaCommand") {
3048 PBD::ID id(n->property("midi-source")->value());
3049 boost::shared_ptr<MidiSource> midi_source =
3050 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3052 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
3054 error << "FIXME: Failed to downcast MidiSource for DeltaCommand" << endmsg;
3057 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3068 Session::config_changed (const char* parameter_name)
3070 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3072 if (PARAM_IS ("seamless-loop")) {
3074 } else if (PARAM_IS ("rf-speed")) {
3076 } else if (PARAM_IS ("auto-loop")) {
3078 } else if (PARAM_IS ("auto-input")) {
3080 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3081 /* auto-input only makes a difference if we're rolling */
3083 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3085 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3086 if ((*i)->record_enabled ()) {
3087 (*i)->monitor_input (!Config->get_auto_input());
3092 } else if (PARAM_IS ("punch-in")) {
3096 if ((location = _locations.auto_punch_location()) != 0) {
3098 if (Config->get_punch_in ()) {
3099 replace_event (Event::PunchIn, location->start());
3101 remove_event (location->start(), Event::PunchIn);
3105 } else if (PARAM_IS ("punch-out")) {
3109 if ((location = _locations.auto_punch_location()) != 0) {
3111 if (Config->get_punch_out()) {
3112 replace_event (Event::PunchOut, location->end());
3114 clear_events (Event::PunchOut);
3118 } else if (PARAM_IS ("edit-mode")) {
3120 Glib::Mutex::Lock lm (playlist_lock);
3122 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3123 (*i)->set_edit_mode (Config->get_edit_mode ());
3126 } else if (PARAM_IS ("use-video-sync")) {
3128 waiting_for_sync_offset = Config->get_use_video_sync();
3130 } else if (PARAM_IS ("mmc-control")) {
3132 //poke_midi_thread ();
3134 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
3137 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3140 } else if (PARAM_IS ("mmc-send-id")) {
3143 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3146 } else if (PARAM_IS ("midi-control")) {
3148 //poke_midi_thread ();
3150 } else if (PARAM_IS ("raid-path")) {
3152 setup_raid_path (Config->get_raid_path());
3154 } else if (PARAM_IS ("smpte-format")) {
3158 } else if (PARAM_IS ("video-pullup")) {
3162 } else if (PARAM_IS ("seamless-loop")) {
3164 if (play_loop && transport_rolling()) {
3165 // to reset diskstreams etc
3166 request_play_loop (true);
3169 } else if (PARAM_IS ("rf-speed")) {
3171 cumulative_rf_motion = 0;
3174 } else if (PARAM_IS ("click-sound")) {
3176 setup_click_sounds (1);
3178 } else if (PARAM_IS ("click-emphasis-sound")) {
3180 setup_click_sounds (-1);
3182 } else if (PARAM_IS ("clicking")) {
3184 if (Config->get_clicking()) {
3185 if (_click_io && click_data) { // don't require emphasis data
3192 } else if (PARAM_IS ("send-mtc")) {
3194 /* only set the internal flag if we have
3198 if (_mtc_port != 0) {
3199 session_send_mtc = Config->get_send_mtc();
3200 if (session_send_mtc) {
3201 /* mark us ready to send */
3202 next_quarter_frame_to_send = 0;
3205 session_send_mtc = false;
3208 } else if (PARAM_IS ("send-mmc")) {
3210 /* only set the internal flag if we have
3214 if (_mmc_port != 0) {
3215 session_send_mmc = Config->get_send_mmc();
3218 session_send_mmc = false;
3221 } else if (PARAM_IS ("midi-feedback")) {
3223 /* only set the internal flag if we have
3227 if (_mtc_port != 0) {
3228 session_midi_feedback = Config->get_midi_feedback();
3231 } else if (PARAM_IS ("jack-time-master")) {
3233 engine().reset_timebase ();
3235 } else if (PARAM_IS ("native-file-header-format")) {
3237 if (!first_file_header_format_reset) {
3238 reset_native_file_format ();
3241 first_file_header_format_reset = false;
3243 } else if (PARAM_IS ("native-file-data-format")) {
3245 if (!first_file_data_format_reset) {
3246 reset_native_file_format ();
3249 first_file_data_format_reset = false;
3251 } else if (PARAM_IS ("slave-source")) {
3252 set_slave_source (Config->get_slave_source());
3253 } else if (PARAM_IS ("remote-model")) {
3254 set_remote_control_ids ();
3255 } else if (PARAM_IS ("denormal-model")) {
3257 } else if (PARAM_IS ("history-depth")) {
3258 set_history_depth (Config->get_history_depth());
3259 } else if (PARAM_IS ("sync-all-route-ordering")) {
3261 } else if (PARAM_IS ("initial-program-change")) {
3263 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3266 buf[0] = MIDI::program; // channel zero by default
3267 buf[1] = (Config->get_initial_program_change() & 0x7f);
3269 _mmc_port->midimsg (buf, sizeof (buf), 0);
3280 Session::set_history_depth (uint32_t d)
3282 _history.set_depth (d);