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>
104 #include <ardour/ticker.h>
106 #include <control_protocol/control_protocol.h>
112 using namespace ARDOUR;
116 Session::first_stage_init (string fullpath, string snapshot_name)
118 if (fullpath.length() == 0) {
120 throw failed_constructor();
123 char buf[PATH_MAX+1];
124 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
125 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
127 throw failed_constructor();
132 if (_path[_path.length()-1] != '/') {
136 /* these two are just provisional settings. set_state()
137 will likely override them.
140 _name = _current_snapshot_name = snapshot_name;
142 set_history_depth (Config->get_history_depth());
144 _current_frame_rate = _engine.frame_rate ();
145 _nominal_frame_rate = _current_frame_rate;
146 _base_frame_rate = _current_frame_rate;
148 _tempo_map = new TempoMap (_current_frame_rate);
149 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
153 g_atomic_int_set (&processing_prohibited, 0);
155 _transport_speed = 0;
156 _last_transport_speed = 0;
157 auto_play_legal = false;
158 transport_sub_state = 0;
159 _transport_frame = 0;
161 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
162 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
163 _end_location_is_free = true;
164 g_atomic_int_set (&_record_status, Disabled);
165 loop_changing = false;
167 _last_roll_location = 0;
168 _last_record_location = 0;
169 pending_locate_frame = 0;
170 pending_locate_roll = false;
171 pending_locate_flush = false;
172 audio_dstream_buffer_size = 0;
173 midi_dstream_buffer_size = 0;
175 state_was_pending = false;
177 outbound_mtc_smpte_frame = 0;
178 next_quarter_frame_to_send = -1;
179 current_block_size = 0;
180 solo_update_disabled = false;
181 currently_soloing = false;
182 _have_captured = false;
183 _worst_output_latency = 0;
184 _worst_input_latency = 0;
185 _worst_track_latency = 0;
186 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
189 butler_mixdown_buffer = 0;
190 butler_gain_buffer = 0;
192 session_send_mmc = false;
193 session_send_mtc = false;
194 post_transport_work = PostTransportWork (0);
195 g_atomic_int_set (&butler_should_do_transport_work, 0);
196 g_atomic_int_set (&butler_active, 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;
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);
364 BootMessage (_("Reset Control Protocols"));
366 ControlProtocolManager::instance().set_session (*this);
369 _end_location_is_free = true;
371 _end_location_is_free = false;
374 _state_of_the_state = Clean;
376 DirtyChanged (); /* EMIT SIGNAL */
378 if (state_was_pending) {
379 save_state (_current_snapshot_name);
380 remove_pending_capture_state ();
381 state_was_pending = false;
384 BootMessage (_("Session loading complete"));
390 Session::raid_path () const
392 SearchPath raid_search_path;
394 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
395 raid_search_path += sys::path((*i).path);
398 return raid_search_path.to_string ();
402 Session::setup_raid_path (string path)
411 session_dirs.clear ();
413 SearchPath search_path(path);
414 SearchPath sound_search_path;
415 SearchPath midi_search_path;
418 SearchPath::const_iterator i = search_path.begin();
419 i != search_path.end();
423 sp.path = (*i).to_string ();
424 sp.blocks = 0; // not needed
425 session_dirs.push_back (sp);
427 SessionDirectory sdir(sp.path);
429 sound_search_path += sdir.sound_path ();
430 midi_search_path += sdir.midi_path ();
433 // set the AudioFileSource and SMFSource search path
435 AudioFileSource::set_search_path (sound_search_path.to_string ());
436 SMFSource::set_search_path (midi_search_path.to_string ());
439 // reset the round-robin soundfile path thingie
441 last_rr_session_dir = session_dirs.begin();
445 Session::ensure_subdirs ()
449 dir = session_directory().peak_path().to_string();
451 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
452 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
456 dir = session_directory().sound_path().to_string();
458 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
459 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
463 dir = session_directory().midi_path().to_string();
465 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
466 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
470 dir = session_directory().dead_sound_path().to_string();
472 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
473 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
477 dir = session_directory().export_path().to_string();
479 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
480 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
484 dir = analysis_dir ();
486 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
487 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
495 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
498 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
499 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
503 if (ensure_subdirs ()) {
507 /* check new_session so we don't overwrite an existing one */
509 if (!mix_template.empty()) {
510 std::string in_path = mix_template;
512 ifstream in(in_path.c_str());
515 string out_path = _path;
517 out_path += statefile_suffix;
519 ofstream out(out_path.c_str());
524 // okay, session is set up. Treat like normal saved
525 // session from now on.
531 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
537 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
544 /* Instantiate metadata */
546 _metadata = new SessionMetadata ();
548 /* set initial start + end point */
550 start_location->set_end (0);
551 _locations.add (start_location);
553 end_location->set_end (initial_length);
554 _locations.add (end_location);
556 _state_of_the_state = Clean;
565 Session::load_diskstreams (const XMLNode& node)
568 XMLNodeConstIterator citer;
570 clist = node.children();
572 for (citer = clist.begin(); citer != clist.end(); ++citer) {
575 /* diskstreams added automatically by DiskstreamCreated handler */
576 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
577 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
578 add_diskstream (dstream);
579 } else if ((*citer)->name() == "MidiDiskstream") {
580 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
581 add_diskstream (dstream);
583 error << _("Session: unknown diskstream type in XML") << endmsg;
587 catch (failed_constructor& err) {
588 error << _("Session: could not load diskstream via XML state") << endmsg;
597 Session::maybe_write_autosave()
599 if (dirty() && record_status() != Recording) {
600 save_state("", true);
605 Session::remove_pending_capture_state ()
607 sys::path pending_state_file_path(_session_dir->root_path());
609 pending_state_file_path /= _current_snapshot_name + pending_suffix;
613 sys::remove (pending_state_file_path);
615 catch(sys::filesystem_error& ex)
617 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
618 pending_state_file_path.to_string(), ex.what()) << endmsg;
622 /** Rename a state file.
623 * @param snapshot_name Snapshot name.
626 Session::rename_state (string old_name, string new_name)
628 if (old_name == _current_snapshot_name || old_name == _name) {
629 /* refuse to rename the current snapshot or the "main" one */
633 const string old_xml_filename = old_name + statefile_suffix;
634 const string new_xml_filename = new_name + statefile_suffix;
636 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
637 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
641 sys::rename (old_xml_path, new_xml_path);
643 catch (const sys::filesystem_error& err)
645 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
646 old_name, new_name, err.what()) << endmsg;
650 /** Remove a state file.
651 * @param snapshot_name Snapshot name.
654 Session::remove_state (string snapshot_name)
656 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
657 // refuse to remove the current snapshot or the "main" one
661 sys::path xml_path(_session_dir->root_path());
663 xml_path /= snapshot_name + statefile_suffix;
665 if (!create_backup_file (xml_path)) {
666 // don't remove it if a backup can't be made
667 // create_backup_file will log the error.
672 sys::remove (xml_path);
676 Session::save_state (string snapshot_name, bool pending)
679 sys::path xml_path(_session_dir->root_path());
681 if (_state_of_the_state & CannotSave) {
685 if (!_engine.connected ()) {
686 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
691 /* tell sources we're saving first, in case they write out to a new file
692 * which should be saved with the state rather than the old one */
693 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
694 i->second->session_saved();
696 tree.set_root (&get_state());
698 if (snapshot_name.empty()) {
699 snapshot_name = _current_snapshot_name;
704 /* proper save: use statefile_suffix (.ardour in English) */
706 xml_path /= snapshot_name + statefile_suffix;
708 /* make a backup copy of the old file */
710 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
711 // create_backup_file will log the error
717 /* pending save: use pending_suffix (.pending in English) */
718 xml_path /= snapshot_name + pending_suffix;
721 sys::path tmp_path(_session_dir->root_path());
723 tmp_path /= snapshot_name + temp_suffix;
725 // cerr << "actually writing state to " << xml_path.to_string() << endl;
727 if (!tree.write (tmp_path.to_string())) {
728 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
729 sys::remove (tmp_path);
734 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
735 error << string_compose (_("could not rename temporary session file %1 to %2"),
736 tmp_path.to_string(), xml_path.to_string()) << endmsg;
737 sys::remove (tmp_path);
744 save_history (snapshot_name);
746 bool was_dirty = dirty();
748 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
751 DirtyChanged (); /* EMIT SIGNAL */
754 StateSaved (snapshot_name); /* EMIT SIGNAL */
761 Session::restore_state (string snapshot_name)
763 if (load_state (snapshot_name) == 0) {
764 set_state (*state_tree->root());
771 Session::load_state (string snapshot_name)
778 state_was_pending = false;
780 /* check for leftover pending state from a crashed capture attempt */
782 sys::path xmlpath(_session_dir->root_path());
783 xmlpath /= snapshot_name + pending_suffix;
785 if (sys::exists (xmlpath)) {
787 /* there is pending state from a crashed capture attempt */
789 if (AskAboutPendingState()) {
790 state_was_pending = true;
794 if (!state_was_pending) {
795 xmlpath = _session_dir->root_path();
796 xmlpath /= snapshot_name + statefile_suffix;
799 if (!sys::exists (xmlpath)) {
800 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
804 state_tree = new XMLTree;
808 if (!state_tree->read (xmlpath.to_string())) {
809 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
815 XMLNode& root (*state_tree->root());
817 if (root.name() != X_("Session")) {
818 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
824 const XMLProperty* prop;
825 bool is_old = false; // session is _very_ old (pre-2.0)
827 if ((prop = root.property ("version")) == 0) {
828 /* no version implies very old version of Ardour */
832 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
833 if (major_version < 2) {
840 sys::path backup_path(_session_dir->root_path());
842 backup_path /= snapshot_name + "-1" + statefile_suffix;
844 // only create a backup once
845 if (sys::exists (backup_path)) {
849 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
850 xmlpath.to_string(), backup_path.to_string())
855 sys::copy_file (xmlpath, backup_path);
857 catch(sys::filesystem_error& ex)
859 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
860 xmlpath.to_string(), ex.what())
870 Session::load_options (const XMLNode& node)
874 LocaleGuard lg (X_("POSIX"));
876 Config->set_variables (node, ConfigVariableBase::Session);
878 /* now reset MIDI ports because the session can have its own
884 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
885 if ((prop = child->property ("val")) != 0) {
886 _end_location_is_free = (prop->value() == "yes");
894 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
896 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
897 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
899 return owner & modified_by_session_or_user;
903 Session::get_options () const
906 LocaleGuard lg (X_("POSIX"));
908 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
910 child = option_root.add_child ("end-marker-is-free");
911 child->add_property ("val", _end_location_is_free ? "yes" : "no");
923 Session::get_template()
925 /* if we don't disable rec-enable, diskstreams
926 will believe they need to store their capture
927 sources in their state node.
930 disable_record (false);
936 Session::state(bool full_state)
938 XMLNode* node = new XMLNode("Session");
941 // store libardour version, just in case
943 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
944 node->add_property("version", string(buf));
946 /* store configuration settings */
950 node->add_property ("name", _name);
951 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
952 node->add_property ("sample-rate", buf);
954 if (session_dirs.size() > 1) {
958 vector<space_and_path>::iterator i = session_dirs.begin();
959 vector<space_and_path>::iterator next;
961 ++i; /* skip the first one */
965 while (i != session_dirs.end()) {
969 if (next != session_dirs.end()) {
979 child = node->add_child ("Path");
980 child->add_content (p);
984 /* save the ID counter */
986 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
987 node->add_property ("id-counter", buf);
989 /* various options */
991 node->add_child_nocopy (get_options());
993 node->add_child_nocopy (_metadata->get_state());
995 child = node->add_child ("Sources");
998 Glib::Mutex::Lock sl (source_lock);
1000 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1002 /* Don't save information about AudioFileSources that are empty */
1004 boost::shared_ptr<AudioFileSource> fs;
1006 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
1008 /* Don't save sources that are empty, unless they're destructive (which are OK
1009 if they are empty, because we will re-use them every time.)
1012 if (!fs->destructive()) {
1013 if (fs->length() == 0) {
1019 child->add_child_nocopy (siter->second->get_state());
1023 child = node->add_child ("Regions");
1026 Glib::Mutex::Lock rl (region_lock);
1028 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
1030 /* only store regions not attached to playlists */
1032 if (i->second->playlist() == 0) {
1033 child->add_child_nocopy (i->second->state (true));
1038 child = node->add_child ("DiskStreams");
1041 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1042 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1043 if (!(*i)->hidden()) {
1044 child->add_child_nocopy ((*i)->get_state());
1050 node->add_child_nocopy (_locations.get_state());
1052 // for a template, just create a new Locations, populate it
1053 // with the default start and end, and get the state for that.
1055 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1056 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1059 end->set_end(compute_initial_length());
1061 node->add_child_nocopy (loc.get_state());
1064 child = node->add_child ("Bundles");
1066 Glib::Mutex::Lock lm (bundle_lock);
1067 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
1068 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1070 child->add_child_nocopy (b->get_state());
1075 child = node->add_child ("Routes");
1077 boost::shared_ptr<RouteList> r = routes.reader ();
1079 RoutePublicOrderSorter cmp;
1080 RouteList public_order (*r);
1081 public_order.sort (cmp);
1083 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1084 if (!(*i)->is_hidden()) {
1086 child->add_child_nocopy ((*i)->get_state());
1088 child->add_child_nocopy ((*i)->get_template());
1095 child = node->add_child ("EditGroups");
1096 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1097 child->add_child_nocopy ((*i)->get_state());
1100 child = node->add_child ("MixGroups");
1101 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1102 child->add_child_nocopy ((*i)->get_state());
1105 child = node->add_child ("Playlists");
1106 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1107 if (!(*i)->hidden()) {
1108 if (!(*i)->empty()) {
1110 child->add_child_nocopy ((*i)->get_state());
1112 child->add_child_nocopy ((*i)->get_template());
1118 child = node->add_child ("UnusedPlaylists");
1119 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1120 if (!(*i)->hidden()) {
1121 if (!(*i)->empty()) {
1123 child->add_child_nocopy ((*i)->get_state());
1125 child->add_child_nocopy ((*i)->get_template());
1133 child = node->add_child ("Click");
1134 child->add_child_nocopy (_click_io->state (full_state));
1138 child = node->add_child ("NamedSelections");
1139 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1141 child->add_child_nocopy ((*i)->get_state());
1146 node->add_child_nocopy (_tempo_map->get_state());
1148 node->add_child_nocopy (get_control_protocol_state());
1151 node->add_child_copy (*_extra_xml);
1158 Session::get_control_protocol_state ()
1160 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1161 return cpm.get_state();
1165 Session::set_state (const XMLNode& node)
1169 const XMLProperty* prop;
1172 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1174 if (node.name() != X_("Session")){
1175 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1179 if ((prop = node.property ("name")) != 0) {
1180 _name = prop->value ();
1183 if ((prop = node.property (X_("sample-rate"))) != 0) {
1185 _nominal_frame_rate = atoi (prop->value());
1187 if (_nominal_frame_rate != _current_frame_rate) {
1188 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1194 setup_raid_path(_session_dir->root_path().to_string());
1196 if ((prop = node.property (X_("id-counter"))) != 0) {
1198 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1199 ID::init_counter (x);
1201 /* old sessions used a timebased counter, so fake
1202 the startup ID counter based on a standard
1207 ID::init_counter (now);
1211 IO::disable_ports ();
1212 IO::disable_connecting ();
1214 /* Object loading order:
1219 MIDI Control // relies on data from Options/Config
1233 if ((child = find_named_node (node, "extra")) != 0) {
1234 _extra_xml = new XMLNode (*child);
1237 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1238 load_options (*child);
1239 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1240 load_options (*child);
1242 error << _("Session: XML state has no options section") << endmsg;
1245 if (use_config_midi_ports ()) {
1248 if ((child = find_named_node (node, "Metadata")) == 0) {
1249 warning << _("Session: XML state has no metadata section (2.0 session?)") << endmsg;
1250 } else if (_metadata->set_state (*child)) {
1254 if ((child = find_named_node (node, "Locations")) == 0) {
1255 error << _("Session: XML state has no locations section") << endmsg;
1257 } else if (_locations.set_state (*child)) {
1263 if ((location = _locations.auto_loop_location()) != 0) {
1264 set_auto_loop_location (location);
1267 if ((location = _locations.auto_punch_location()) != 0) {
1268 set_auto_punch_location (location);
1271 if ((location = _locations.end_location()) == 0) {
1272 _locations.add (end_location);
1274 delete end_location;
1275 end_location = location;
1278 if ((location = _locations.start_location()) == 0) {
1279 _locations.add (start_location);
1281 delete start_location;
1282 start_location = location;
1285 AudioFileSource::set_header_position_offset (start_location->start());
1287 if ((child = find_named_node (node, "Sources")) == 0) {
1288 error << _("Session: XML state has no sources section") << endmsg;
1290 } else if (load_sources (*child)) {
1294 if ((child = find_named_node (node, "Regions")) == 0) {
1295 error << _("Session: XML state has no Regions section") << endmsg;
1297 } else if (load_regions (*child)) {
1301 if ((child = find_named_node (node, "Playlists")) == 0) {
1302 error << _("Session: XML state has no playlists section") << endmsg;
1304 } else if (load_playlists (*child)) {
1308 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1310 } else if (load_unused_playlists (*child)) {
1314 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1315 if (load_named_selections (*child)) {
1320 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1321 error << _("Session: XML state has no diskstreams section") << endmsg;
1323 } else if (load_diskstreams (*child)) {
1327 if ((child = find_named_node (node, "Bundles")) == 0) {
1328 warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg;
1331 /* We can't load Bundles yet as they need to be able
1332 to convert from port names to Port objects, which can't happen until
1334 _bundle_xml_node = new XMLNode (*child);
1337 if ((child = find_named_node (node, "EditGroups")) == 0) {
1338 error << _("Session: XML state has no edit groups section") << endmsg;
1340 } else if (load_edit_groups (*child)) {
1344 if ((child = find_named_node (node, "MixGroups")) == 0) {
1345 error << _("Session: XML state has no mix groups section") << endmsg;
1347 } else if (load_mix_groups (*child)) {
1351 if ((child = find_named_node (node, "TempoMap")) == 0) {
1352 error << _("Session: XML state has no Tempo Map section") << endmsg;
1354 } else if (_tempo_map->set_state (*child)) {
1358 if ((child = find_named_node (node, "Routes")) == 0) {
1359 error << _("Session: XML state has no routes section") << endmsg;
1361 } else if (load_routes (*child)) {
1365 if ((child = find_named_node (node, "Click")) == 0) {
1366 warning << _("Session: XML state has no click section") << endmsg;
1367 } else if (_click_io) {
1368 _click_io->set_state (*child);
1371 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1372 ControlProtocolManager::instance().set_protocol_states (*child);
1375 /* here beginneth the second phase ... */
1377 StateReady (); /* EMIT SIGNAL */
1386 Session::load_routes (const XMLNode& node)
1389 XMLNodeConstIterator niter;
1390 RouteList new_routes;
1392 nlist = node.children();
1396 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1398 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1401 error << _("Session: cannot create Route from XML description.") << endmsg;
1405 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1407 new_routes.push_back (route);
1410 add_routes (new_routes, false);
1415 boost::shared_ptr<Route>
1416 Session::XMLRouteFactory (const XMLNode& node)
1418 if (node.name() != "Route") {
1419 return boost::shared_ptr<Route> ((Route*) 0);
1422 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1424 DataType type = DataType::AUDIO;
1425 const XMLProperty* prop = node.property("default-type");
1427 type = DataType(prop->value());
1429 assert(type != DataType::NIL);
1431 if (has_diskstream) {
1432 if (type == DataType::AUDIO) {
1433 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1436 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1440 boost::shared_ptr<Route> ret (new Route (*this, node));
1446 Session::load_regions (const XMLNode& node)
1449 XMLNodeConstIterator niter;
1450 boost::shared_ptr<Region> region;
1452 nlist = node.children();
1456 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1457 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1458 error << _("Session: cannot create Region from XML description.");
1459 const XMLProperty *name = (**niter).property("name");
1462 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1472 boost::shared_ptr<Region>
1473 Session::XMLRegionFactory (const XMLNode& node, bool full)
1475 const XMLProperty* type = node.property("type");
1479 if ( !type || type->value() == "audio" ) {
1481 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1483 } else if (type->value() == "midi") {
1485 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1489 } catch (failed_constructor& err) {
1490 return boost::shared_ptr<Region> ();
1493 return boost::shared_ptr<Region> ();
1496 boost::shared_ptr<AudioRegion>
1497 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1499 const XMLProperty* prop;
1500 boost::shared_ptr<Source> source;
1501 boost::shared_ptr<AudioSource> as;
1503 SourceList master_sources;
1504 uint32_t nchans = 1;
1507 if (node.name() != X_("Region")) {
1508 return boost::shared_ptr<AudioRegion>();
1511 if ((prop = node.property (X_("channels"))) != 0) {
1512 nchans = atoi (prop->value().c_str());
1515 if ((prop = node.property ("name")) == 0) {
1516 cerr << "no name for this region\n";
1520 if ((prop = node.property (X_("source-0"))) == 0) {
1521 if ((prop = node.property ("source")) == 0) {
1522 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1523 return boost::shared_ptr<AudioRegion>();
1527 PBD::ID s_id (prop->value());
1529 if ((source = source_by_id (s_id)) == 0) {
1530 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1531 return boost::shared_ptr<AudioRegion>();
1534 as = boost::dynamic_pointer_cast<AudioSource>(source);
1536 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1537 return boost::shared_ptr<AudioRegion>();
1540 sources.push_back (as);
1542 /* pickup other channels */
1544 for (uint32_t n=1; n < nchans; ++n) {
1545 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1546 if ((prop = node.property (buf)) != 0) {
1548 PBD::ID id2 (prop->value());
1550 if ((source = source_by_id (id2)) == 0) {
1551 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1552 return boost::shared_ptr<AudioRegion>();
1555 as = boost::dynamic_pointer_cast<AudioSource>(source);
1557 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1558 return boost::shared_ptr<AudioRegion>();
1560 sources.push_back (as);
1564 for (uint32_t n=1; n < nchans; ++n) {
1565 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1566 if ((prop = node.property (buf)) != 0) {
1568 PBD::ID id2 (prop->value());
1570 if ((source = source_by_id (id2)) == 0) {
1571 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1572 return boost::shared_ptr<AudioRegion>();
1575 as = boost::dynamic_pointer_cast<AudioSource>(source);
1577 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1578 return boost::shared_ptr<AudioRegion>();
1580 master_sources.push_back (as);
1585 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1587 /* a final detail: this is the one and only place that we know how long missing files are */
1589 if (region->whole_file()) {
1590 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1591 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1593 sfp->set_length (region->length());
1598 if (!master_sources.empty()) {
1599 if (master_sources.size() == nchans) {
1600 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1602 region->set_master_sources (master_sources);
1610 catch (failed_constructor& err) {
1611 return boost::shared_ptr<AudioRegion>();
1615 boost::shared_ptr<MidiRegion>
1616 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1618 const XMLProperty* prop;
1619 boost::shared_ptr<Source> source;
1620 boost::shared_ptr<MidiSource> ms;
1622 uint32_t nchans = 1;
1624 if (node.name() != X_("Region")) {
1625 return boost::shared_ptr<MidiRegion>();
1628 if ((prop = node.property (X_("channels"))) != 0) {
1629 nchans = atoi (prop->value().c_str());
1632 if ((prop = node.property ("name")) == 0) {
1633 cerr << "no name for this region\n";
1637 // Multiple midi channels? that's just crazy talk
1638 assert(nchans == 1);
1640 if ((prop = node.property (X_("source-0"))) == 0) {
1641 if ((prop = node.property ("source")) == 0) {
1642 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1643 return boost::shared_ptr<MidiRegion>();
1647 PBD::ID s_id (prop->value());
1649 if ((source = source_by_id (s_id)) == 0) {
1650 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1651 return boost::shared_ptr<MidiRegion>();
1654 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1656 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1657 return boost::shared_ptr<MidiRegion>();
1660 sources.push_back (ms);
1663 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1664 /* a final detail: this is the one and only place that we know how long missing files are */
1666 if (region->whole_file()) {
1667 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1668 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1670 sfp->set_length (region->length());
1678 catch (failed_constructor& err) {
1679 return boost::shared_ptr<MidiRegion>();
1684 Session::get_sources_as_xml ()
1687 XMLNode* node = new XMLNode (X_("Sources"));
1688 Glib::Mutex::Lock lm (source_lock);
1690 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1691 node->add_child_nocopy (i->second->get_state());
1698 Session::path_from_region_name (DataType type, string name, string identifier)
1700 char buf[PATH_MAX+1];
1702 SessionDirectory sdir(get_best_session_directory_for_new_source());
1703 sys::path source_dir = ((type == DataType::AUDIO)
1704 ? sdir.sound_path() : sdir.midi_path());
1706 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1708 for (n = 0; n < 999999; ++n) {
1709 if (identifier.length()) {
1710 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1711 identifier.c_str(), n, ext.c_str());
1713 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1717 sys::path source_path = source_dir / buf;
1719 if (!sys::exists (source_path)) {
1720 return source_path.to_string();
1724 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1733 Session::load_sources (const XMLNode& node)
1736 XMLNodeConstIterator niter;
1737 boost::shared_ptr<Source> source;
1739 nlist = node.children();
1743 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1746 if ((source = XMLSourceFactory (**niter)) == 0) {
1747 error << _("Session: cannot create Source from XML description.") << endmsg;
1751 catch (non_existent_source& err) {
1752 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1753 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1760 boost::shared_ptr<Source>
1761 Session::XMLSourceFactory (const XMLNode& node)
1763 if (node.name() != "Source") {
1764 return boost::shared_ptr<Source>();
1768 /* note: do peak building in another thread when loading session state */
1769 return SourceFactory::create (*this, node, true);
1772 catch (failed_constructor& err) {
1773 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1774 return boost::shared_ptr<Source>();
1779 Session::save_template (string template_name)
1783 if (_state_of_the_state & CannotSave) {
1787 sys::path user_template_dir(user_template_directory());
1791 sys::create_directories (user_template_dir);
1793 catch(sys::filesystem_error& ex)
1795 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1796 user_template_dir.to_string(), ex.what()) << endmsg;
1800 tree.set_root (&get_template());
1802 sys::path template_file_path(user_template_dir);
1803 template_file_path /= template_name + template_suffix;
1805 if (sys::exists (template_file_path))
1807 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1808 template_file_path.to_string()) << endmsg;
1812 if (!tree.write (template_file_path.to_string())) {
1813 error << _("mix template not saved") << endmsg;
1821 Session::rename_template (string old_name, string new_name)
1823 sys::path old_path (user_template_directory());
1824 old_path /= old_name + template_suffix;
1826 sys::path new_path(user_template_directory());
1827 new_path /= new_name + template_suffix;
1829 if (sys::exists (new_path)) {
1830 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1831 new_path.to_string()) << endmsg;
1836 sys::rename (old_path, new_path);
1844 Session::delete_template (string name)
1846 sys::path path = user_template_directory();
1847 path /= name + template_suffix;
1858 Session::refresh_disk_space ()
1861 struct statfs statfsbuf;
1862 vector<space_and_path>::iterator i;
1863 Glib::Mutex::Lock lm (space_lock);
1866 /* get freespace on every FS that is part of the session path */
1868 _total_free_4k_blocks = 0;
1870 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1871 statfs ((*i).path.c_str(), &statfsbuf);
1873 scale = statfsbuf.f_bsize/4096.0;
1875 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1876 _total_free_4k_blocks += (*i).blocks;
1882 Session::get_best_session_directory_for_new_source ()
1884 vector<space_and_path>::iterator i;
1885 string result = _session_dir->root_path().to_string();
1887 /* handle common case without system calls */
1889 if (session_dirs.size() == 1) {
1893 /* OK, here's the algorithm we're following here:
1895 We want to select which directory to use for
1896 the next file source to be created. Ideally,
1897 we'd like to use a round-robin process so as to
1898 get maximum performance benefits from splitting
1899 the files across multiple disks.
1901 However, in situations without much diskspace, an
1902 RR approach may end up filling up a filesystem
1903 with new files while others still have space.
1904 Its therefore important to pay some attention to
1905 the freespace in the filesystem holding each
1906 directory as well. However, if we did that by
1907 itself, we'd keep creating new files in the file
1908 system with the most space until it was as full
1909 as all others, thus negating any performance
1910 benefits of this RAID-1 like approach.
1912 So, we use a user-configurable space threshold. If
1913 there are at least 2 filesystems with more than this
1914 much space available, we use RR selection between them.
1915 If not, then we pick the filesystem with the most space.
1917 This gets a good balance between the two
1921 refresh_disk_space ();
1923 int free_enough = 0;
1925 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1926 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1931 if (free_enough >= 2) {
1932 /* use RR selection process, ensuring that the one
1936 i = last_rr_session_dir;
1939 if (++i == session_dirs.end()) {
1940 i = session_dirs.begin();
1943 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1944 if (create_session_directory ((*i).path)) {
1946 last_rr_session_dir = i;
1951 } while (i != last_rr_session_dir);
1955 /* pick FS with the most freespace (and that
1956 seems to actually work ...)
1959 vector<space_and_path> sorted;
1960 space_and_path_ascending_cmp cmp;
1962 sorted = session_dirs;
1963 sort (sorted.begin(), sorted.end(), cmp);
1965 for (i = sorted.begin(); i != sorted.end(); ++i) {
1966 if (create_session_directory ((*i).path)) {
1968 last_rr_session_dir = i;
1978 Session::load_playlists (const XMLNode& node)
1981 XMLNodeConstIterator niter;
1982 boost::shared_ptr<Playlist> playlist;
1984 nlist = node.children();
1988 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1990 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1991 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1999 Session::load_unused_playlists (const XMLNode& node)
2002 XMLNodeConstIterator niter;
2003 boost::shared_ptr<Playlist> playlist;
2005 nlist = node.children();
2009 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2011 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2012 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2016 // now manually untrack it
2018 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
2024 boost::shared_ptr<Playlist>
2025 Session::XMLPlaylistFactory (const XMLNode& node)
2028 return PlaylistFactory::create (*this, node);
2031 catch (failed_constructor& err) {
2032 return boost::shared_ptr<Playlist>();
2037 Session::load_named_selections (const XMLNode& node)
2040 XMLNodeConstIterator niter;
2043 nlist = node.children();
2047 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2049 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2050 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2058 Session::XMLNamedSelectionFactory (const XMLNode& node)
2061 return new NamedSelection (*this, node);
2064 catch (failed_constructor& err) {
2070 Session::automation_dir () const
2072 return Glib::build_filename (_path, "automation");
2076 Session::analysis_dir () const
2078 return Glib::build_filename (_path, "analysis");
2082 Session::load_bundles (XMLNode const & node)
2084 XMLNodeList nlist = node.children();
2085 XMLNodeConstIterator niter;
2089 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2090 if ((*niter)->name() == "InputBundle") {
2091 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2092 } else if ((*niter)->name() == "OutputBundle") {
2093 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2095 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2104 Session::load_edit_groups (const XMLNode& node)
2106 return load_route_groups (node, true);
2110 Session::load_mix_groups (const XMLNode& node)
2112 return load_route_groups (node, false);
2116 Session::load_route_groups (const XMLNode& node, bool edit)
2118 XMLNodeList nlist = node.children();
2119 XMLNodeConstIterator niter;
2124 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2125 if ((*niter)->name() == "RouteGroup") {
2127 rg = add_edit_group ("");
2128 rg->set_state (**niter);
2130 rg = add_mix_group ("");
2131 rg->set_state (**niter);
2140 Session::auto_save()
2142 save_state (_current_snapshot_name);
2146 state_file_filter (const string &str, void *arg)
2148 return (str.length() > strlen(statefile_suffix) &&
2149 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2153 bool operator()(const string* a, const string* b) {
2159 remove_end(string* state)
2161 string statename(*state);
2163 string::size_type start,end;
2164 if ((start = statename.find_last_of ('/')) != string::npos) {
2165 statename = statename.substr (start+1);
2168 if ((end = statename.rfind(".ardour")) == string::npos) {
2169 end = statename.length();
2172 return new string(statename.substr (0, end));
2176 Session::possible_states (string path)
2178 PathScanner scanner;
2179 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2181 transform(states->begin(), states->end(), states->begin(), remove_end);
2184 sort (states->begin(), states->end(), cmp);
2190 Session::possible_states () const
2192 return possible_states(_path);
2196 Session::add_edit_group (string name)
2198 RouteGroup* rg = new RouteGroup (*this, name);
2199 edit_groups.push_back (rg);
2200 edit_group_added (rg); /* EMIT SIGNAL */
2206 Session::add_mix_group (string name)
2208 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2209 mix_groups.push_back (rg);
2210 mix_group_added (rg); /* EMIT SIGNAL */
2216 Session::remove_edit_group (RouteGroup& rg)
2218 list<RouteGroup*>::iterator i;
2220 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2221 (*i)->apply (&Route::drop_edit_group, this);
2222 edit_groups.erase (i);
2223 edit_group_removed (); /* EMIT SIGNAL */
2230 Session::remove_mix_group (RouteGroup& rg)
2232 list<RouteGroup*>::iterator i;
2234 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2235 (*i)->apply (&Route::drop_mix_group, this);
2236 mix_groups.erase (i);
2237 mix_group_removed (); /* EMIT SIGNAL */
2244 Session::mix_group_by_name (string name)
2246 list<RouteGroup *>::iterator i;
2248 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2249 if ((*i)->name() == name) {
2257 Session::edit_group_by_name (string name)
2259 list<RouteGroup *>::iterator i;
2261 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2262 if ((*i)->name() == name) {
2270 Session::begin_reversible_command (const string& name)
2272 current_trans = new UndoTransaction;
2273 current_trans->set_name (name);
2277 Session::commit_reversible_command (Command *cmd)
2282 current_trans->add_command (cmd);
2285 if (current_trans->empty()) {
2289 gettimeofday (&now, 0);
2290 current_trans->set_timestamp (now);
2292 _history.add (current_trans);
2295 Session::GlobalRouteBooleanState
2296 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2298 GlobalRouteBooleanState s;
2299 boost::shared_ptr<RouteList> r = routes.reader ();
2301 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2302 if (!(*i)->is_hidden()) {
2303 RouteBooleanState v;
2306 Route* r = (*i).get();
2307 v.second = (r->*method)();
2316 Session::GlobalRouteMeterState
2317 Session::get_global_route_metering ()
2319 GlobalRouteMeterState s;
2320 boost::shared_ptr<RouteList> r = routes.reader ();
2322 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2323 if (!(*i)->is_hidden()) {
2327 v.second = (*i)->meter_point();
2337 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2339 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2341 boost::shared_ptr<Route> r = (i->first.lock());
2344 r->set_meter_point (i->second, arg);
2350 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2352 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2354 boost::shared_ptr<Route> r = (i->first.lock());
2357 Route* rp = r.get();
2358 (rp->*method) (i->second, arg);
2364 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2366 set_global_route_boolean (s, &Route::set_mute, src);
2370 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2372 set_global_route_boolean (s, &Route::set_solo, src);
2376 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2378 set_global_route_boolean (s, &Route::set_record_enable, src);
2383 Session::global_mute_memento (void* src)
2385 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2389 Session::global_metering_memento (void* src)
2391 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2395 Session::global_solo_memento (void* src)
2397 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2401 Session::global_record_enable_memento (void* src)
2403 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2408 accept_all_non_peak_files (const string& path, void *arg)
2410 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2414 accept_all_state_files (const string& path, void *arg)
2416 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2420 Session::find_all_sources (string path, set<string>& result)
2425 if (!tree.read (path)) {
2429 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2434 XMLNodeConstIterator niter;
2436 nlist = node->children();
2440 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2444 if ((prop = (*niter)->property (X_("name"))) == 0) {
2448 if (prop->value()[0] == '/') {
2449 /* external file, ignore */
2453 sys::path source_path = _session_dir->sound_path ();
2455 source_path /= prop->value ();
2457 result.insert (source_path.to_string ());
2464 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2466 PathScanner scanner;
2467 vector<string*>* state_files;
2469 string this_snapshot_path;
2475 if (ripped[ripped.length()-1] == '/') {
2476 ripped = ripped.substr (0, ripped.length() - 1);
2479 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2481 if (state_files == 0) {
2486 this_snapshot_path = _path;
2487 this_snapshot_path += _current_snapshot_name;
2488 this_snapshot_path += statefile_suffix;
2490 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2492 if (exclude_this_snapshot && **i == this_snapshot_path) {
2496 if (find_all_sources (**i, result) < 0) {
2504 struct RegionCounter {
2505 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2506 AudioSourceList::iterator iter;
2507 boost::shared_ptr<Region> region;
2510 RegionCounter() : count (0) {}
2514 Session::cleanup_sources (Session::cleanup_report& rep)
2516 // FIXME: needs adaptation to midi
2518 vector<boost::shared_ptr<Source> > dead_sources;
2519 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2520 PathScanner scanner;
2522 vector<space_and_path>::iterator i;
2523 vector<space_and_path>::iterator nexti;
2524 vector<string*>* soundfiles;
2525 vector<string> unused;
2526 set<string> all_sources;
2531 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2534 /* step 1: consider deleting all unused playlists */
2536 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2539 status = AskAboutPlaylistDeletion (*x);
2548 playlists_tbd.push_back (*x);
2552 /* leave it alone */
2557 /* now delete any that were marked for deletion */
2559 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2560 (*x)->drop_references ();
2563 playlists_tbd.clear ();
2565 /* step 2: find all un-used sources */
2570 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2572 SourceMap::iterator tmp;
2577 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2581 if (!i->second->used() && i->second->length() > 0) {
2582 dead_sources.push_back (i->second);
2583 i->second->GoingAway();
2589 /* build a list of all the possible sound directories for the session */
2591 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2596 SessionDirectory sdir ((*i).path);
2597 sound_path += sdir.sound_path().to_string();
2599 if (nexti != session_dirs.end()) {
2606 /* now do the same thing for the files that ended up in the sounds dir(s)
2607 but are not referenced as sources in any snapshot.
2610 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2612 if (soundfiles == 0) {
2616 /* find all sources, but don't use this snapshot because the
2617 state file on disk still references sources we may have already
2621 find_all_sources_across_snapshots (all_sources, true);
2623 /* add our current source list
2626 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2627 boost::shared_ptr<AudioFileSource> fs;
2629 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2630 all_sources.insert (fs->path());
2634 char tmppath1[PATH_MAX+1];
2635 char tmppath2[PATH_MAX+1];
2637 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2642 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2644 realpath(spath.c_str(), tmppath1);
2645 realpath((*i).c_str(), tmppath2);
2647 if (strcmp(tmppath1, tmppath2) == 0) {
2654 unused.push_back (spath);
2658 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2660 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2661 struct stat statbuf;
2663 rep.paths.push_back (*x);
2664 if (stat ((*x).c_str(), &statbuf) == 0) {
2665 rep.space += statbuf.st_size;
2670 /* don't move the file across filesystems, just
2671 stick it in the `dead_sound_dir_name' directory
2672 on whichever filesystem it was already on.
2675 if ((*x).find ("/sounds/") != string::npos) {
2677 /* old school, go up 1 level */
2679 newpath = Glib::path_get_dirname (*x); // "sounds"
2680 newpath = Glib::path_get_dirname (newpath); // "session-name"
2684 /* new school, go up 4 levels */
2686 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2687 newpath = Glib::path_get_dirname (newpath); // "session-name"
2688 newpath = Glib::path_get_dirname (newpath); // "interchange"
2689 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2693 newpath += dead_sound_dir_name;
2695 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2696 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2701 newpath += Glib::path_get_basename ((*x));
2703 if (access (newpath.c_str(), F_OK) == 0) {
2705 /* the new path already exists, try versioning */
2707 char buf[PATH_MAX+1];
2711 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2714 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2715 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2719 if (version == 999) {
2720 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2724 newpath = newpath_v;
2729 /* it doesn't exist, or we can't read it or something */
2733 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2734 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2735 (*x), newpath, strerror (errno))
2740 /* see if there an easy to find peakfile for this file, and remove it.
2743 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2744 peakpath += peakfile_suffix;
2746 if (access (peakpath.c_str(), W_OK) == 0) {
2747 if (::unlink (peakpath.c_str()) != 0) {
2748 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2749 peakpath, _path, strerror (errno))
2751 /* try to back out */
2752 rename (newpath.c_str(), _path.c_str());
2760 /* dump the history list */
2764 /* save state so we don't end up a session file
2765 referring to non-existent sources.
2771 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2777 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2779 // FIXME: needs adaptation for MIDI
2781 vector<space_and_path>::iterator i;
2782 string dead_sound_dir;
2783 struct dirent* dentry;
2784 struct stat statbuf;
2790 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2792 dead_sound_dir = (*i).path;
2793 dead_sound_dir += dead_sound_dir_name;
2795 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2799 while ((dentry = readdir (dead)) != 0) {
2801 /* avoid '.' and '..' */
2803 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2804 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2810 fullpath = dead_sound_dir;
2812 fullpath += dentry->d_name;
2814 if (stat (fullpath.c_str(), &statbuf)) {
2818 if (!S_ISREG (statbuf.st_mode)) {
2822 if (unlink (fullpath.c_str())) {
2823 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2824 fullpath, strerror (errno))
2828 rep.paths.push_back (dentry->d_name);
2829 rep.space += statbuf.st_size;
2840 Session::set_dirty ()
2842 bool was_dirty = dirty();
2844 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2848 DirtyChanged(); /* EMIT SIGNAL */
2854 Session::set_clean ()
2856 bool was_dirty = dirty();
2858 _state_of_the_state = Clean;
2862 DirtyChanged(); /* EMIT SIGNAL */
2867 Session::set_deletion_in_progress ()
2869 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2874 Session::add_controllable (boost::shared_ptr<Controllable> c)
2876 /* this adds a controllable to the list managed by the Session.
2877 this is a subset of those managed by the Controllable class
2878 itself, and represents the only ones whose state will be saved
2879 as part of the session.
2882 Glib::Mutex::Lock lm (controllables_lock);
2883 controllables.insert (c);
2886 struct null_deleter { void operator()(void const *) const {} };
2889 Session::remove_controllable (Controllable* c)
2891 if (_state_of_the_state | Deletion) {
2895 Glib::Mutex::Lock lm (controllables_lock);
2897 Controllables::iterator x = controllables.find(
2898 boost::shared_ptr<Controllable>(c, null_deleter()));
2900 if (x != controllables.end()) {
2901 controllables.erase (x);
2905 boost::shared_ptr<Controllable>
2906 Session::controllable_by_id (const PBD::ID& id)
2908 Glib::Mutex::Lock lm (controllables_lock);
2910 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2911 if ((*i)->id() == id) {
2916 return boost::shared_ptr<Controllable>();
2920 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2922 Stateful::add_instant_xml (node, _path);
2923 if (write_to_config) {
2924 Config->add_instant_xml (node);
2929 Session::instant_xml (const string& node_name)
2931 return Stateful::instant_xml (node_name, _path);
2935 Session::save_history (string snapshot_name)
2939 if (snapshot_name.empty()) {
2940 snapshot_name = _current_snapshot_name;
2943 const string history_filename = snapshot_name + history_suffix;
2944 const string backup_filename = history_filename + backup_suffix;
2945 const sys::path xml_path = _session_dir->root_path() / history_filename;
2946 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2948 if (sys::exists (xml_path)) {
2951 sys::rename (xml_path, backup_path);
2953 catch (const sys::filesystem_error& err)
2955 error << _("could not backup old history file, current history not saved") << endmsg;
2961 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2965 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2967 if (!tree.write (xml_path.to_string()))
2969 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2973 sys::remove (xml_path);
2974 sys::rename (backup_path, xml_path);
2976 catch (const sys::filesystem_error& err)
2978 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2979 backup_path.to_string(), err.what()) << endmsg;
2989 Session::restore_history (string snapshot_name)
2993 if (snapshot_name.empty()) {
2994 snapshot_name = _current_snapshot_name;
2997 const string xml_filename = snapshot_name + history_suffix;
2998 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3000 cerr << "Loading history from " << xml_path.to_string() << endmsg;
3002 if (!sys::exists (xml_path)) {
3003 info << string_compose (_("%1: no history file \"%2\" for this session."),
3004 _name, xml_path.to_string()) << endmsg;
3008 if (!tree.read (xml_path.to_string())) {
3009 error << string_compose (_("Could not understand session history file \"%1\""),
3010 xml_path.to_string()) << endmsg;
3017 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3020 UndoTransaction* ut = new UndoTransaction ();
3023 ut->set_name(t->property("name")->value());
3024 stringstream ss(t->property("tv-sec")->value());
3026 ss.str(t->property("tv-usec")->value());
3028 ut->set_timestamp(tv);
3030 for (XMLNodeConstIterator child_it = t->children().begin();
3031 child_it != t->children().end(); child_it++)
3033 XMLNode *n = *child_it;
3036 if (n->name() == "MementoCommand" ||
3037 n->name() == "MementoUndoCommand" ||
3038 n->name() == "MementoRedoCommand") {
3040 if ((c = memento_command_factory(n))) {
3044 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3046 if ((c = global_state_command_factory (*n))) {
3047 ut->add_command (c);
3050 } else if (n->name() == "DeltaCommand") {
3051 PBD::ID id(n->property("midi-source")->value());
3052 boost::shared_ptr<MidiSource> midi_source =
3053 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3055 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
3057 error << "FIXME: Failed to downcast MidiSource for DeltaCommand" << endmsg;
3060 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3071 Session::config_changed (const char* parameter_name)
3073 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3075 if (PARAM_IS ("seamless-loop")) {
3077 } else if (PARAM_IS ("rf-speed")) {
3079 } else if (PARAM_IS ("auto-loop")) {
3081 } else if (PARAM_IS ("auto-input")) {
3083 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3084 /* auto-input only makes a difference if we're rolling */
3086 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3088 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3089 if ((*i)->record_enabled ()) {
3090 (*i)->monitor_input (!Config->get_auto_input());
3095 } else if (PARAM_IS ("punch-in")) {
3099 if ((location = _locations.auto_punch_location()) != 0) {
3101 if (Config->get_punch_in ()) {
3102 replace_event (Event::PunchIn, location->start());
3104 remove_event (location->start(), Event::PunchIn);
3108 } else if (PARAM_IS ("punch-out")) {
3112 if ((location = _locations.auto_punch_location()) != 0) {
3114 if (Config->get_punch_out()) {
3115 replace_event (Event::PunchOut, location->end());
3117 clear_events (Event::PunchOut);
3121 } else if (PARAM_IS ("edit-mode")) {
3123 Glib::Mutex::Lock lm (playlist_lock);
3125 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3126 (*i)->set_edit_mode (Config->get_edit_mode ());
3129 } else if (PARAM_IS ("use-video-sync")) {
3131 waiting_for_sync_offset = Config->get_use_video_sync();
3133 } else if (PARAM_IS ("mmc-control")) {
3135 //poke_midi_thread ();
3137 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
3140 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3143 } else if (PARAM_IS ("mmc-send-id")) {
3146 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3149 } else if (PARAM_IS ("midi-control")) {
3151 //poke_midi_thread ();
3153 } else if (PARAM_IS ("raid-path")) {
3155 setup_raid_path (Config->get_raid_path());
3157 } else if (PARAM_IS ("smpte-format")) {
3161 } else if (PARAM_IS ("video-pullup")) {
3165 } else if (PARAM_IS ("seamless-loop")) {
3167 if (play_loop && transport_rolling()) {
3168 // to reset diskstreams etc
3169 request_play_loop (true);
3172 } else if (PARAM_IS ("rf-speed")) {
3174 cumulative_rf_motion = 0;
3177 } else if (PARAM_IS ("click-sound")) {
3179 setup_click_sounds (1);
3181 } else if (PARAM_IS ("click-emphasis-sound")) {
3183 setup_click_sounds (-1);
3185 } else if (PARAM_IS ("clicking")) {
3187 if (Config->get_clicking()) {
3188 if (_click_io && click_data) { // don't require emphasis data
3195 } else if (PARAM_IS ("send-mtc")) {
3197 /* only set the internal flag if we have
3201 if (_mtc_port != 0) {
3202 session_send_mtc = Config->get_send_mtc();
3203 if (session_send_mtc) {
3204 /* mark us ready to send */
3205 next_quarter_frame_to_send = 0;
3208 session_send_mtc = false;
3211 } else if (PARAM_IS ("send-mmc")) {
3213 /* only set the internal flag if we have
3217 if (_mmc_port != 0) {
3218 session_send_mmc = Config->get_send_mmc();
3221 session_send_mmc = false;
3224 } else if (PARAM_IS ("midi-feedback")) {
3226 /* only set the internal flag if we have
3230 if (_mtc_port != 0) {
3231 session_midi_feedback = Config->get_midi_feedback();
3234 } else if (PARAM_IS ("jack-time-master")) {
3236 engine().reset_timebase ();
3238 } else if (PARAM_IS ("native-file-header-format")) {
3240 if (!first_file_header_format_reset) {
3241 reset_native_file_format ();
3244 first_file_header_format_reset = false;
3246 } else if (PARAM_IS ("native-file-data-format")) {
3248 if (!first_file_data_format_reset) {
3249 reset_native_file_format ();
3252 first_file_data_format_reset = false;
3254 } else if (PARAM_IS ("slave-source")) {
3255 set_slave_source (Config->get_slave_source());
3256 } else if (PARAM_IS ("remote-model")) {
3257 set_remote_control_ids ();
3258 } else if (PARAM_IS ("denormal-model")) {
3260 } else if (PARAM_IS ("history-depth")) {
3261 set_history_depth (Config->get_history_depth());
3262 } else if (PARAM_IS ("sync-all-route-ordering")) {
3264 } else if (PARAM_IS ("initial-program-change")) {
3266 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3269 buf[0] = MIDI::program; // channel zero by default
3270 buf[1] = (Config->get_initial_program_change() & 0x7f);
3272 _mmc_port->midimsg (buf, sizeof (buf), 0);
3283 Session::set_history_depth (uint32_t d)
3285 _history.set_depth (d);