2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #define __STDC_FORMAT_MACROS 1
28 #include <sigc++/bind.h>
30 #include <cstdio> /* snprintf(3) ... grrr */
45 #include <sys/param.h>
46 #include <sys/mount.h>
50 #include <glibmm/thread.h>
52 #include <midi++/mmc.h>
53 #include <midi++/port.h>
55 #include <pbd/error.h>
56 #include <pbd/pathscanner.h>
57 #include <pbd/pthread_utils.h>
58 #include <pbd/search_path.h>
59 #include <pbd/stacktrace.h>
61 #include <ardour/audioengine.h>
62 #include <ardour/configuration.h>
63 #include <ardour/session.h>
64 #include <ardour/session_directory.h>
65 #include <ardour/session_utils.h>
66 #include <ardour/session_state_utils.h>
67 #include <ardour/session_metadata.h>
68 #include <ardour/buffer.h>
69 #include <ardour/audio_diskstream.h>
70 #include <ardour/midi_diskstream.h>
71 #include <ardour/utils.h>
72 #include <ardour/audioplaylist.h>
73 #include <ardour/midi_playlist.h>
74 #include <ardour/smf_source.h>
75 #include <ardour/audiofilesource.h>
76 #include <ardour/silentfilesource.h>
77 #include <ardour/sndfilesource.h>
78 #include <ardour/midi_source.h>
79 #include <ardour/sndfile_helpers.h>
80 #include <ardour/auditioner.h>
81 #include <ardour/io_processor.h>
82 #include <ardour/send.h>
83 #include <ardour/processor.h>
84 #include <ardour/bundle.h>
85 #include <ardour/slave.h>
86 #include <ardour/tempo.h>
87 #include <ardour/audio_track.h>
88 #include <ardour/midi_track.h>
89 #include <ardour/midi_patch_manager.h>
90 #include <ardour/cycle_timer.h>
91 #include <ardour/utils.h>
92 #include <ardour/named_selection.h>
93 #include <ardour/version.h>
94 #include <ardour/location.h>
95 #include <ardour/audioregion.h>
96 #include <ardour/midi_region.h>
97 #include <ardour/crossfade.h>
98 #include <ardour/control_protocol_manager.h>
99 #include <ardour/region_factory.h>
100 #include <ardour/source_factory.h>
101 #include <ardour/playlist_factory.h>
102 #include <ardour/filename_extensions.h>
103 #include <ardour/directory_names.h>
104 #include <ardour/template_utils.h>
105 #include <ardour/ticker.h>
107 #include <control_protocol/control_protocol.h>
113 using namespace ARDOUR;
117 Session::first_stage_init (string fullpath, string snapshot_name)
119 if (fullpath.length() == 0) {
121 throw failed_constructor();
124 char buf[PATH_MAX+1];
125 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
126 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
128 throw failed_constructor();
133 if (_path[_path.length()-1] != '/') {
137 /* these two are just provisional settings. set_state()
138 will likely override them.
141 _name = _current_snapshot_name = snapshot_name;
143 set_history_depth (Config->get_history_depth());
145 _current_frame_rate = _engine.frame_rate ();
146 _nominal_frame_rate = _current_frame_rate;
147 _base_frame_rate = _current_frame_rate;
149 _tempo_map = new TempoMap (_current_frame_rate);
150 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
154 g_atomic_int_set (&processing_prohibited, 0);
156 _transport_speed = 0;
157 _last_transport_speed = 0;
158 auto_play_legal = false;
159 transport_sub_state = 0;
160 _transport_frame = 0;
162 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
163 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
164 _end_location_is_free = true;
165 g_atomic_int_set (&_record_status, Disabled);
166 loop_changing = false;
169 _last_roll_location = 0;
170 _last_record_location = 0;
171 pending_locate_frame = 0;
172 pending_locate_roll = false;
173 pending_locate_flush = false;
174 audio_dstream_buffer_size = 0;
175 midi_dstream_buffer_size = 0;
176 state_was_pending = false;
178 outbound_mtc_smpte_frame = 0;
179 next_quarter_frame_to_send = -1;
180 current_block_size = 0;
181 solo_update_disabled = false;
182 currently_soloing = false;
183 _have_captured = false;
184 _worst_output_latency = 0;
185 _worst_input_latency = 0;
186 _worst_track_latency = 0;
187 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
190 session_send_mmc = false;
191 session_send_mtc = false;
192 post_transport_work = PostTransportWork (0);
193 g_atomic_int_set (&butler_should_do_transport_work, 0);
194 g_atomic_int_set (&_playback_load, 100);
195 g_atomic_int_set (&_capture_load, 100);
196 g_atomic_int_set (&_playback_load_min, 100);
197 g_atomic_int_set (&_capture_load_min, 100);
200 _exporting_realtime = false;
201 _gain_automation_buffer = 0;
202 _pan_automation_buffer = 0;
204 pending_abort = false;
205 destructive_index = 0;
207 first_file_data_format_reset = true;
208 first_file_header_format_reset = true;
209 butler_thread = (pthread_t) 0;
210 //midi_thread = (pthread_t) 0;
212 AudioDiskstream::allocate_working_buffers();
214 /* default short fade = 15ms */
216 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
217 SndFileSource::setup_standard_crossfades (frame_rate());
219 last_mmc_step.tv_sec = 0;
220 last_mmc_step.tv_usec = 0;
223 /* click sounds are unset by default, which causes us to internal
224 waveforms for clicks.
228 click_emphasis_length = 0;
231 process_function = &Session::process_with_events;
233 if (Config->get_use_video_sync()) {
234 waiting_for_sync_offset = true;
236 waiting_for_sync_offset = false;
241 _smpte_offset_negative = true;
242 last_smpte_valid = false;
246 last_rr_session_dir = session_dirs.begin();
247 refresh_disk_space ();
249 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
253 average_slave_delta = 1800; // !!! why 1800 ????
254 have_first_delta_accumulator = false;
255 delta_accumulator_cnt = 0;
256 slave_state = Stopped;
258 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
260 /* These are all static "per-class" signals */
262 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
263 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
264 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
265 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
266 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
267 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
269 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
271 IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
273 /* stop IO objects from doing stuff until we're ready for them */
275 IO::disable_panners ();
276 IO::disable_ports ();
277 IO::disable_connecting ();
281 Session::second_stage_init (bool new_session)
283 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
286 if (load_state (_current_snapshot_name)) {
289 remove_empty_sounds ();
292 if (start_butler_thread()) {
296 if (start_midi_thread ()) {
300 // set_state() will call setup_raid_path(), but if it's a new session we need
301 // to call setup_raid_path() here.
304 if (set_state (*state_tree->root())) {
308 setup_raid_path(_path);
311 /* we can't save till after ::when_engine_running() is called,
312 because otherwise we save state with no connections made.
313 therefore, we reset _state_of_the_state because ::set_state()
314 will have cleared it.
316 we also have to include Loading so that any events that get
317 generated between here and the end of ::when_engine_running()
318 will be processed directly rather than queued.
321 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
324 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
325 _locations.added.connect (mem_fun (this, &Session::locations_added));
326 setup_click_sounds (0);
327 setup_midi_control ();
329 /* Pay attention ... */
331 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
332 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
335 when_engine_running();
338 /* handle this one in a different way than all others, so that its clear what happened */
340 catch (AudioEngine::PortRegistrationFailure& err) {
341 error << _("Unable to create all required ports")
350 BootMessage (_("Reset Remote Controls"));
352 send_full_time_code (0);
353 _engine.transport_locate (0);
354 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
355 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
357 MidiClockTicker::instance().set_session(*this);
358 MIDI::Name::MidiPatchManager::instance().set_session(*this);
360 /* initial program change will be delivered later; see ::config_changed() */
362 BootMessage (_("Reset Control Protocols"));
364 ControlProtocolManager::instance().set_session (*this);
367 _end_location_is_free = true;
369 _end_location_is_free = false;
372 _state_of_the_state = Clean;
374 DirtyChanged (); /* EMIT SIGNAL */
376 if (state_was_pending) {
377 save_state (_current_snapshot_name);
378 remove_pending_capture_state ();
379 state_was_pending = false;
382 BootMessage (_("Session loading complete"));
388 Session::raid_path () const
390 SearchPath raid_search_path;
392 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
393 raid_search_path += sys::path((*i).path);
396 return raid_search_path.to_string ();
400 Session::setup_raid_path (string path)
409 session_dirs.clear ();
411 SearchPath search_path(path);
412 SearchPath sound_search_path;
413 SearchPath midi_search_path;
416 SearchPath::const_iterator i = search_path.begin();
417 i != search_path.end();
421 sp.path = (*i).to_string ();
422 sp.blocks = 0; // not needed
423 session_dirs.push_back (sp);
425 SessionDirectory sdir(sp.path);
427 sound_search_path += sdir.sound_path ();
428 midi_search_path += sdir.midi_path ();
431 // set the AudioFileSource and SMFSource search path
433 AudioFileSource::set_search_path (sound_search_path.to_string ());
434 SMFSource::set_search_path (midi_search_path.to_string ());
437 // reset the round-robin soundfile path thingie
439 last_rr_session_dir = session_dirs.begin();
443 Session::ensure_subdirs ()
447 dir = session_directory().peak_path().to_string();
449 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
450 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
454 dir = session_directory().sound_path().to_string();
456 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
457 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
461 dir = session_directory().midi_path().to_string();
463 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
464 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
468 dir = session_directory().dead_sound_path().to_string();
470 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
471 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
475 dir = session_directory().export_path().to_string();
477 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
478 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
482 dir = analysis_dir ();
484 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
485 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
493 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
496 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
497 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
501 if (ensure_subdirs ()) {
505 /* check new_session so we don't overwrite an existing one */
507 if (!mix_template.empty()) {
508 std::string in_path = mix_template;
510 ifstream in(in_path.c_str());
513 string out_path = _path;
515 out_path += statefile_suffix;
517 ofstream out(out_path.c_str());
522 // okay, session is set up. Treat like normal saved
523 // session from now on.
529 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
535 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
542 /* Instantiate metadata */
544 _metadata = new SessionMetadata ();
546 /* set initial start + end point */
548 start_location->set_end (0);
549 _locations.add (start_location);
551 end_location->set_end (initial_length);
552 _locations.add (end_location);
554 _state_of_the_state = Clean;
563 Session::load_diskstreams (const XMLNode& node)
566 XMLNodeConstIterator citer;
568 clist = node.children();
570 for (citer = clist.begin(); citer != clist.end(); ++citer) {
573 /* diskstreams added automatically by DiskstreamCreated handler */
574 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
575 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
576 add_diskstream (dstream);
577 } else if ((*citer)->name() == "MidiDiskstream") {
578 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
579 add_diskstream (dstream);
581 error << _("Session: unknown diskstream type in XML") << endmsg;
585 catch (failed_constructor& err) {
586 error << _("Session: could not load diskstream via XML state") << endmsg;
595 Session::maybe_write_autosave()
597 if (dirty() && record_status() != Recording) {
598 save_state("", true);
603 Session::remove_pending_capture_state ()
605 sys::path pending_state_file_path(_session_dir->root_path());
607 pending_state_file_path /= _current_snapshot_name + pending_suffix;
611 sys::remove (pending_state_file_path);
613 catch(sys::filesystem_error& ex)
615 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
616 pending_state_file_path.to_string(), ex.what()) << endmsg;
620 /** Rename a state file.
621 * @param snapshot_name Snapshot name.
624 Session::rename_state (string old_name, string new_name)
626 if (old_name == _current_snapshot_name || old_name == _name) {
627 /* refuse to rename the current snapshot or the "main" one */
631 const string old_xml_filename = old_name + statefile_suffix;
632 const string new_xml_filename = new_name + statefile_suffix;
634 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
635 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
639 sys::rename (old_xml_path, new_xml_path);
641 catch (const sys::filesystem_error& err)
643 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
644 old_name, new_name, err.what()) << endmsg;
648 /** Remove a state file.
649 * @param snapshot_name Snapshot name.
652 Session::remove_state (string snapshot_name)
654 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
655 // refuse to remove the current snapshot or the "main" one
659 sys::path xml_path(_session_dir->root_path());
661 xml_path /= snapshot_name + statefile_suffix;
663 if (!create_backup_file (xml_path)) {
664 // don't remove it if a backup can't be made
665 // create_backup_file will log the error.
670 sys::remove (xml_path);
674 Session::save_state (string snapshot_name, bool pending)
677 sys::path xml_path(_session_dir->root_path());
679 if (_state_of_the_state & CannotSave) {
683 if (!_engine.connected ()) {
684 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
689 /* tell sources we're saving first, in case they write out to a new file
690 * which should be saved with the state rather than the old one */
691 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
692 i->second->session_saved();
694 tree.set_root (&get_state());
696 if (snapshot_name.empty()) {
697 snapshot_name = _current_snapshot_name;
702 /* proper save: use statefile_suffix (.ardour in English) */
704 xml_path /= snapshot_name + statefile_suffix;
706 /* make a backup copy of the old file */
708 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
709 // create_backup_file will log the error
715 /* pending save: use pending_suffix (.pending in English) */
716 xml_path /= snapshot_name + pending_suffix;
719 sys::path tmp_path(_session_dir->root_path());
721 tmp_path /= snapshot_name + temp_suffix;
723 // cerr << "actually writing state to " << xml_path.to_string() << endl;
725 if (!tree.write (tmp_path.to_string())) {
726 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
727 sys::remove (tmp_path);
732 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
733 error << string_compose (_("could not rename temporary session file %1 to %2"),
734 tmp_path.to_string(), xml_path.to_string()) << endmsg;
735 sys::remove (tmp_path);
742 save_history (snapshot_name);
744 bool was_dirty = dirty();
746 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
749 DirtyChanged (); /* EMIT SIGNAL */
752 StateSaved (snapshot_name); /* EMIT SIGNAL */
759 Session::restore_state (string snapshot_name)
761 if (load_state (snapshot_name) == 0) {
762 set_state (*state_tree->root());
769 Session::load_state (string snapshot_name)
776 state_was_pending = false;
778 /* check for leftover pending state from a crashed capture attempt */
780 sys::path xmlpath(_session_dir->root_path());
781 xmlpath /= snapshot_name + pending_suffix;
783 if (sys::exists (xmlpath)) {
785 /* there is pending state from a crashed capture attempt */
787 if (AskAboutPendingState()) {
788 state_was_pending = true;
792 if (!state_was_pending) {
793 xmlpath = _session_dir->root_path();
794 xmlpath /= snapshot_name + statefile_suffix;
797 if (!sys::exists (xmlpath)) {
798 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
802 state_tree = new XMLTree;
806 if (!state_tree->read (xmlpath.to_string())) {
807 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
813 XMLNode& root (*state_tree->root());
815 if (root.name() != X_("Session")) {
816 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
822 const XMLProperty* prop;
823 bool is_old = false; // session is _very_ old (pre-2.0)
825 if ((prop = root.property ("version")) == 0) {
826 /* no version implies very old version of Ardour */
830 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
831 if (major_version < 2) {
838 sys::path backup_path(_session_dir->root_path());
840 backup_path /= snapshot_name + "-1" + statefile_suffix;
842 // only create a backup once
843 if (sys::exists (backup_path)) {
847 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
848 xmlpath.to_string(), backup_path.to_string())
853 sys::copy_file (xmlpath, backup_path);
855 catch(sys::filesystem_error& ex)
857 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
858 xmlpath.to_string(), ex.what())
868 Session::load_options (const XMLNode& node)
872 LocaleGuard lg (X_("POSIX"));
874 Config->set_variables (node, ConfigVariableBase::Session);
876 /* now reset MIDI ports because the session can have its own
882 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
883 if ((prop = child->property ("val")) != 0) {
884 _end_location_is_free = (prop->value() == "yes");
892 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
894 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
895 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
897 return owner & modified_by_session_or_user;
901 Session::get_options () const
904 LocaleGuard lg (X_("POSIX"));
906 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
908 child = option_root.add_child ("end-marker-is-free");
909 child->add_property ("val", _end_location_is_free ? "yes" : "no");
921 Session::get_template()
923 /* if we don't disable rec-enable, diskstreams
924 will believe they need to store their capture
925 sources in their state node.
928 disable_record (false);
934 Session::state(bool full_state)
936 XMLNode* node = new XMLNode("Session");
939 // store libardour version, just in case
941 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
942 node->add_property("version", string(buf));
944 /* store configuration settings */
948 node->add_property ("name", _name);
949 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
950 node->add_property ("sample-rate", buf);
952 if (session_dirs.size() > 1) {
956 vector<space_and_path>::iterator i = session_dirs.begin();
957 vector<space_and_path>::iterator next;
959 ++i; /* skip the first one */
963 while (i != session_dirs.end()) {
967 if (next != session_dirs.end()) {
977 child = node->add_child ("Path");
978 child->add_content (p);
982 /* save the ID counter */
984 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
985 node->add_property ("id-counter", buf);
987 /* various options */
989 node->add_child_nocopy (get_options());
991 node->add_child_nocopy (_metadata->get_state());
993 child = node->add_child ("Sources");
996 Glib::Mutex::Lock sl (source_lock);
998 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1000 /* Don't save information about AudioFileSources that are empty */
1002 boost::shared_ptr<AudioFileSource> fs;
1004 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
1006 /* Don't save sources that are empty, unless they're destructive (which are OK
1007 if they are empty, because we will re-use them every time.)
1010 if (!fs->destructive()) {
1011 if (fs->length() == 0) {
1017 child->add_child_nocopy (siter->second->get_state());
1021 child = node->add_child ("Regions");
1024 Glib::Mutex::Lock rl (region_lock);
1026 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
1028 /* only store regions not attached to playlists */
1030 if (i->second->playlist() == 0) {
1031 child->add_child_nocopy (i->second->state (true));
1036 child = node->add_child ("DiskStreams");
1039 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1040 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1041 if (!(*i)->hidden()) {
1042 child->add_child_nocopy ((*i)->get_state());
1048 node->add_child_nocopy (_locations.get_state());
1050 // for a template, just create a new Locations, populate it
1051 // with the default start and end, and get the state for that.
1053 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1054 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1057 end->set_end(compute_initial_length());
1059 node->add_child_nocopy (loc.get_state());
1062 child = node->add_child ("Bundles");
1064 Glib::Mutex::Lock lm (bundle_lock);
1065 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
1066 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1068 child->add_child_nocopy (b->get_state());
1073 child = node->add_child ("Routes");
1075 boost::shared_ptr<RouteList> r = routes.reader ();
1077 RoutePublicOrderSorter cmp;
1078 RouteList public_order (*r);
1079 public_order.sort (cmp);
1081 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1082 if (!(*i)->is_hidden()) {
1084 child->add_child_nocopy ((*i)->get_state());
1086 child->add_child_nocopy ((*i)->get_template());
1093 child = node->add_child ("EditGroups");
1094 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1095 child->add_child_nocopy ((*i)->get_state());
1098 child = node->add_child ("MixGroups");
1099 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1100 child->add_child_nocopy ((*i)->get_state());
1103 child = node->add_child ("Playlists");
1104 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1105 if (!(*i)->hidden()) {
1106 if (!(*i)->empty()) {
1108 child->add_child_nocopy ((*i)->get_state());
1110 child->add_child_nocopy ((*i)->get_template());
1116 child = node->add_child ("UnusedPlaylists");
1117 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1118 if (!(*i)->hidden()) {
1119 if (!(*i)->empty()) {
1121 child->add_child_nocopy ((*i)->get_state());
1123 child->add_child_nocopy ((*i)->get_template());
1131 child = node->add_child ("Click");
1132 child->add_child_nocopy (_click_io->state (full_state));
1136 child = node->add_child ("NamedSelections");
1137 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1139 child->add_child_nocopy ((*i)->get_state());
1144 node->add_child_nocopy (_tempo_map->get_state());
1146 node->add_child_nocopy (get_control_protocol_state());
1149 node->add_child_copy (*_extra_xml);
1156 Session::get_control_protocol_state ()
1158 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1159 return cpm.get_state();
1163 Session::set_state (const XMLNode& node)
1167 const XMLProperty* prop;
1170 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1172 if (node.name() != X_("Session")){
1173 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1177 if ((prop = node.property ("name")) != 0) {
1178 _name = prop->value ();
1181 if ((prop = node.property (X_("sample-rate"))) != 0) {
1183 _nominal_frame_rate = atoi (prop->value());
1185 if (_nominal_frame_rate != _current_frame_rate) {
1186 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1192 setup_raid_path(_session_dir->root_path().to_string());
1194 if ((prop = node.property (X_("id-counter"))) != 0) {
1196 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1197 ID::init_counter (x);
1199 /* old sessions used a timebased counter, so fake
1200 the startup ID counter based on a standard
1205 ID::init_counter (now);
1209 IO::disable_ports ();
1210 IO::disable_connecting ();
1212 /* Object loading order:
1217 MIDI Control // relies on data from Options/Config
1231 if ((child = find_named_node (node, "extra")) != 0) {
1232 _extra_xml = new XMLNode (*child);
1235 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1236 load_options (*child);
1237 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1238 load_options (*child);
1240 error << _("Session: XML state has no options section") << endmsg;
1243 if (use_config_midi_ports ()) {
1246 if ((child = find_named_node (node, "Metadata")) == 0) {
1247 warning << _("Session: XML state has no metadata section (2.0 session?)") << endmsg;
1248 } else if (_metadata->set_state (*child)) {
1252 if ((child = find_named_node (node, "Locations")) == 0) {
1253 error << _("Session: XML state has no locations section") << endmsg;
1255 } else if (_locations.set_state (*child)) {
1261 if ((location = _locations.auto_loop_location()) != 0) {
1262 set_auto_loop_location (location);
1265 if ((location = _locations.auto_punch_location()) != 0) {
1266 set_auto_punch_location (location);
1269 if ((location = _locations.end_location()) == 0) {
1270 _locations.add (end_location);
1272 delete end_location;
1273 end_location = location;
1276 if ((location = _locations.start_location()) == 0) {
1277 _locations.add (start_location);
1279 delete start_location;
1280 start_location = location;
1283 AudioFileSource::set_header_position_offset (start_location->start());
1285 if ((child = find_named_node (node, "Sources")) == 0) {
1286 error << _("Session: XML state has no sources section") << endmsg;
1288 } else if (load_sources (*child)) {
1292 if ((child = find_named_node (node, "Regions")) == 0) {
1293 error << _("Session: XML state has no Regions section") << endmsg;
1295 } else if (load_regions (*child)) {
1299 if ((child = find_named_node (node, "Playlists")) == 0) {
1300 error << _("Session: XML state has no playlists section") << endmsg;
1302 } else if (load_playlists (*child)) {
1306 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1308 } else if (load_unused_playlists (*child)) {
1312 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1313 if (load_named_selections (*child)) {
1318 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1319 error << _("Session: XML state has no diskstreams section") << endmsg;
1321 } else if (load_diskstreams (*child)) {
1325 if ((child = find_named_node (node, "Bundles")) == 0) {
1326 warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg;
1329 /* We can't load Bundles yet as they need to be able
1330 to convert from port names to Port objects, which can't happen until
1332 _bundle_xml_node = new XMLNode (*child);
1335 if ((child = find_named_node (node, "EditGroups")) == 0) {
1336 error << _("Session: XML state has no edit groups section") << endmsg;
1338 } else if (load_edit_groups (*child)) {
1342 if ((child = find_named_node (node, "MixGroups")) == 0) {
1343 error << _("Session: XML state has no mix groups section") << endmsg;
1345 } else if (load_mix_groups (*child)) {
1349 if ((child = find_named_node (node, "TempoMap")) == 0) {
1350 error << _("Session: XML state has no Tempo Map section") << endmsg;
1352 } else if (_tempo_map->set_state (*child)) {
1356 if ((child = find_named_node (node, "Routes")) == 0) {
1357 error << _("Session: XML state has no routes section") << endmsg;
1359 } else if (load_routes (*child)) {
1363 if ((child = find_named_node (node, "Click")) == 0) {
1364 warning << _("Session: XML state has no click section") << endmsg;
1365 } else if (_click_io) {
1366 _click_io->set_state (*child);
1369 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1370 ControlProtocolManager::instance().set_protocol_states (*child);
1373 /* here beginneth the second phase ... */
1375 StateReady (); /* EMIT SIGNAL */
1384 Session::load_routes (const XMLNode& node)
1387 XMLNodeConstIterator niter;
1388 RouteList new_routes;
1390 nlist = node.children();
1394 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1396 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1399 error << _("Session: cannot create Route from XML description.") << endmsg;
1403 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1405 new_routes.push_back (route);
1408 add_routes (new_routes, false);
1413 boost::shared_ptr<Route>
1414 Session::XMLRouteFactory (const XMLNode& node)
1416 if (node.name() != "Route") {
1417 return boost::shared_ptr<Route> ((Route*) 0);
1420 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1422 DataType type = DataType::AUDIO;
1423 const XMLProperty* prop = node.property("default-type");
1425 type = DataType(prop->value());
1427 assert(type != DataType::NIL);
1429 if (has_diskstream) {
1430 if (type == DataType::AUDIO) {
1431 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1434 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1438 boost::shared_ptr<Route> ret (new Route (*this, node));
1444 Session::load_regions (const XMLNode& node)
1447 XMLNodeConstIterator niter;
1448 boost::shared_ptr<Region> region;
1450 nlist = node.children();
1454 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1455 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1456 error << _("Session: cannot create Region from XML description.");
1457 const XMLProperty *name = (**niter).property("name");
1460 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1470 boost::shared_ptr<Region>
1471 Session::XMLRegionFactory (const XMLNode& node, bool full)
1473 const XMLProperty* type = node.property("type");
1477 if ( !type || type->value() == "audio" ) {
1479 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1481 } else if (type->value() == "midi") {
1483 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1487 } catch (failed_constructor& err) {
1488 return boost::shared_ptr<Region> ();
1491 return boost::shared_ptr<Region> ();
1494 boost::shared_ptr<AudioRegion>
1495 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1497 const XMLProperty* prop;
1498 boost::shared_ptr<Source> source;
1499 boost::shared_ptr<AudioSource> as;
1501 SourceList master_sources;
1502 uint32_t nchans = 1;
1505 if (node.name() != X_("Region")) {
1506 return boost::shared_ptr<AudioRegion>();
1509 if ((prop = node.property (X_("channels"))) != 0) {
1510 nchans = atoi (prop->value().c_str());
1513 if ((prop = node.property ("name")) == 0) {
1514 cerr << "no name for this region\n";
1518 if ((prop = node.property (X_("source-0"))) == 0) {
1519 if ((prop = node.property ("source")) == 0) {
1520 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1521 return boost::shared_ptr<AudioRegion>();
1525 PBD::ID s_id (prop->value());
1527 if ((source = source_by_id (s_id)) == 0) {
1528 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1529 return boost::shared_ptr<AudioRegion>();
1532 as = boost::dynamic_pointer_cast<AudioSource>(source);
1534 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1535 return boost::shared_ptr<AudioRegion>();
1538 sources.push_back (as);
1540 /* pickup other channels */
1542 for (uint32_t n=1; n < nchans; ++n) {
1543 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1544 if ((prop = node.property (buf)) != 0) {
1546 PBD::ID id2 (prop->value());
1548 if ((source = source_by_id (id2)) == 0) {
1549 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1550 return boost::shared_ptr<AudioRegion>();
1553 as = boost::dynamic_pointer_cast<AudioSource>(source);
1555 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1556 return boost::shared_ptr<AudioRegion>();
1558 sources.push_back (as);
1562 for (uint32_t n=1; n < nchans; ++n) {
1563 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1564 if ((prop = node.property (buf)) != 0) {
1566 PBD::ID id2 (prop->value());
1568 if ((source = source_by_id (id2)) == 0) {
1569 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1570 return boost::shared_ptr<AudioRegion>();
1573 as = boost::dynamic_pointer_cast<AudioSource>(source);
1575 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1576 return boost::shared_ptr<AudioRegion>();
1578 master_sources.push_back (as);
1583 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1585 /* a final detail: this is the one and only place that we know how long missing files are */
1587 if (region->whole_file()) {
1588 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1589 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1591 sfp->set_length (region->length());
1596 if (!master_sources.empty()) {
1597 if (master_sources.size() == nchans) {
1598 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1600 region->set_master_sources (master_sources);
1608 catch (failed_constructor& err) {
1609 return boost::shared_ptr<AudioRegion>();
1613 boost::shared_ptr<MidiRegion>
1614 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1616 const XMLProperty* prop;
1617 boost::shared_ptr<Source> source;
1618 boost::shared_ptr<MidiSource> ms;
1620 uint32_t nchans = 1;
1622 if (node.name() != X_("Region")) {
1623 return boost::shared_ptr<MidiRegion>();
1626 if ((prop = node.property (X_("channels"))) != 0) {
1627 nchans = atoi (prop->value().c_str());
1630 if ((prop = node.property ("name")) == 0) {
1631 cerr << "no name for this region\n";
1635 // Multiple midi channels? that's just crazy talk
1636 assert(nchans == 1);
1638 if ((prop = node.property (X_("source-0"))) == 0) {
1639 if ((prop = node.property ("source")) == 0) {
1640 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1641 return boost::shared_ptr<MidiRegion>();
1645 PBD::ID s_id (prop->value());
1647 if ((source = source_by_id (s_id)) == 0) {
1648 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1649 return boost::shared_ptr<MidiRegion>();
1652 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1654 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1655 return boost::shared_ptr<MidiRegion>();
1658 sources.push_back (ms);
1661 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1662 /* a final detail: this is the one and only place that we know how long missing files are */
1664 if (region->whole_file()) {
1665 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1666 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1668 sfp->set_length (region->length());
1676 catch (failed_constructor& err) {
1677 return boost::shared_ptr<MidiRegion>();
1682 Session::get_sources_as_xml ()
1685 XMLNode* node = new XMLNode (X_("Sources"));
1686 Glib::Mutex::Lock lm (source_lock);
1688 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1689 node->add_child_nocopy (i->second->get_state());
1696 Session::path_from_region_name (DataType type, string name, string identifier)
1698 char buf[PATH_MAX+1];
1700 SessionDirectory sdir(get_best_session_directory_for_new_source());
1701 sys::path source_dir = ((type == DataType::AUDIO)
1702 ? sdir.sound_path() : sdir.midi_path());
1704 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1706 for (n = 0; n < 999999; ++n) {
1707 if (identifier.length()) {
1708 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1709 identifier.c_str(), n, ext.c_str());
1711 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1715 sys::path source_path = source_dir / buf;
1717 if (!sys::exists (source_path)) {
1718 return source_path.to_string();
1722 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1731 Session::load_sources (const XMLNode& node)
1734 XMLNodeConstIterator niter;
1735 boost::shared_ptr<Source> source;
1737 nlist = node.children();
1741 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1744 if ((source = XMLSourceFactory (**niter)) == 0) {
1745 error << _("Session: cannot create Source from XML description.") << endmsg;
1749 catch (non_existent_source& err) {
1750 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1751 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1758 boost::shared_ptr<Source>
1759 Session::XMLSourceFactory (const XMLNode& node)
1761 if (node.name() != "Source") {
1762 return boost::shared_ptr<Source>();
1766 /* note: do peak building in another thread when loading session state */
1767 return SourceFactory::create (*this, node, true);
1770 catch (failed_constructor& err) {
1771 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1772 return boost::shared_ptr<Source>();
1777 Session::save_template (string template_name)
1781 if (_state_of_the_state & CannotSave) {
1785 sys::path user_template_dir(user_template_directory());
1789 sys::create_directories (user_template_dir);
1791 catch(sys::filesystem_error& ex)
1793 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1794 user_template_dir.to_string(), ex.what()) << endmsg;
1798 tree.set_root (&get_template());
1800 sys::path template_file_path(user_template_dir);
1801 template_file_path /= template_name + template_suffix;
1803 if (sys::exists (template_file_path))
1805 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1806 template_file_path.to_string()) << endmsg;
1810 if (!tree.write (template_file_path.to_string())) {
1811 error << _("mix template not saved") << endmsg;
1819 Session::rename_template (string old_name, string new_name)
1821 sys::path old_path (user_template_directory());
1822 old_path /= old_name + template_suffix;
1824 sys::path new_path(user_template_directory());
1825 new_path /= new_name + template_suffix;
1827 if (sys::exists (new_path)) {
1828 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1829 new_path.to_string()) << endmsg;
1834 sys::rename (old_path, new_path);
1842 Session::delete_template (string name)
1844 sys::path path = user_template_directory();
1845 path /= name + template_suffix;
1856 Session::refresh_disk_space ()
1859 struct statfs statfsbuf;
1860 vector<space_and_path>::iterator i;
1861 Glib::Mutex::Lock lm (space_lock);
1864 /* get freespace on every FS that is part of the session path */
1866 _total_free_4k_blocks = 0;
1868 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1869 statfs ((*i).path.c_str(), &statfsbuf);
1871 scale = statfsbuf.f_bsize/4096.0;
1873 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1874 _total_free_4k_blocks += (*i).blocks;
1880 Session::get_best_session_directory_for_new_source ()
1882 vector<space_and_path>::iterator i;
1883 string result = _session_dir->root_path().to_string();
1885 /* handle common case without system calls */
1887 if (session_dirs.size() == 1) {
1891 /* OK, here's the algorithm we're following here:
1893 We want to select which directory to use for
1894 the next file source to be created. Ideally,
1895 we'd like to use a round-robin process so as to
1896 get maximum performance benefits from splitting
1897 the files across multiple disks.
1899 However, in situations without much diskspace, an
1900 RR approach may end up filling up a filesystem
1901 with new files while others still have space.
1902 Its therefore important to pay some attention to
1903 the freespace in the filesystem holding each
1904 directory as well. However, if we did that by
1905 itself, we'd keep creating new files in the file
1906 system with the most space until it was as full
1907 as all others, thus negating any performance
1908 benefits of this RAID-1 like approach.
1910 So, we use a user-configurable space threshold. If
1911 there are at least 2 filesystems with more than this
1912 much space available, we use RR selection between them.
1913 If not, then we pick the filesystem with the most space.
1915 This gets a good balance between the two
1919 refresh_disk_space ();
1921 int free_enough = 0;
1923 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1924 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1929 if (free_enough >= 2) {
1930 /* use RR selection process, ensuring that the one
1934 i = last_rr_session_dir;
1937 if (++i == session_dirs.end()) {
1938 i = session_dirs.begin();
1941 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1942 if (create_session_directory ((*i).path)) {
1944 last_rr_session_dir = i;
1949 } while (i != last_rr_session_dir);
1953 /* pick FS with the most freespace (and that
1954 seems to actually work ...)
1957 vector<space_and_path> sorted;
1958 space_and_path_ascending_cmp cmp;
1960 sorted = session_dirs;
1961 sort (sorted.begin(), sorted.end(), cmp);
1963 for (i = sorted.begin(); i != sorted.end(); ++i) {
1964 if (create_session_directory ((*i).path)) {
1966 last_rr_session_dir = i;
1976 Session::load_playlists (const XMLNode& node)
1979 XMLNodeConstIterator niter;
1980 boost::shared_ptr<Playlist> playlist;
1982 nlist = node.children();
1986 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1988 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1989 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1997 Session::load_unused_playlists (const XMLNode& node)
2000 XMLNodeConstIterator niter;
2001 boost::shared_ptr<Playlist> playlist;
2003 nlist = node.children();
2007 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2009 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2010 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2014 // now manually untrack it
2016 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
2022 boost::shared_ptr<Playlist>
2023 Session::XMLPlaylistFactory (const XMLNode& node)
2026 return PlaylistFactory::create (*this, node);
2029 catch (failed_constructor& err) {
2030 return boost::shared_ptr<Playlist>();
2035 Session::load_named_selections (const XMLNode& node)
2038 XMLNodeConstIterator niter;
2041 nlist = node.children();
2045 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2047 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2048 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2056 Session::XMLNamedSelectionFactory (const XMLNode& node)
2059 return new NamedSelection (*this, node);
2062 catch (failed_constructor& err) {
2068 Session::automation_dir () const
2070 return Glib::build_filename (_path, "automation");
2074 Session::analysis_dir () const
2076 return Glib::build_filename (_path, "analysis");
2080 Session::load_bundles (XMLNode const & node)
2082 XMLNodeList nlist = node.children();
2083 XMLNodeConstIterator niter;
2087 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2088 if ((*niter)->name() == "InputBundle") {
2089 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2090 } else if ((*niter)->name() == "OutputBundle") {
2091 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2093 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2102 Session::load_edit_groups (const XMLNode& node)
2104 return load_route_groups (node, true);
2108 Session::load_mix_groups (const XMLNode& node)
2110 return load_route_groups (node, false);
2114 Session::load_route_groups (const XMLNode& node, bool edit)
2116 XMLNodeList nlist = node.children();
2117 XMLNodeConstIterator niter;
2122 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2123 if ((*niter)->name() == "RouteGroup") {
2125 rg = add_edit_group ("");
2126 rg->set_state (**niter);
2128 rg = add_mix_group ("");
2129 rg->set_state (**niter);
2138 Session::auto_save()
2140 save_state (_current_snapshot_name);
2144 state_file_filter (const string &str, void *arg)
2146 return (str.length() > strlen(statefile_suffix) &&
2147 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2151 bool operator()(const string* a, const string* b) {
2157 remove_end(string* state)
2159 string statename(*state);
2161 string::size_type start,end;
2162 if ((start = statename.find_last_of ('/')) != string::npos) {
2163 statename = statename.substr (start+1);
2166 if ((end = statename.rfind(".ardour")) == string::npos) {
2167 end = statename.length();
2170 return new string(statename.substr (0, end));
2174 Session::possible_states (string path)
2176 PathScanner scanner;
2177 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2179 transform(states->begin(), states->end(), states->begin(), remove_end);
2182 sort (states->begin(), states->end(), cmp);
2188 Session::possible_states () const
2190 return possible_states(_path);
2194 Session::add_edit_group (string name)
2196 RouteGroup* rg = new RouteGroup (*this, name);
2197 edit_groups.push_back (rg);
2198 edit_group_added (rg); /* EMIT SIGNAL */
2204 Session::add_mix_group (string name)
2206 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2207 mix_groups.push_back (rg);
2208 mix_group_added (rg); /* EMIT SIGNAL */
2214 Session::remove_edit_group (RouteGroup& rg)
2216 list<RouteGroup*>::iterator i;
2218 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2219 (*i)->apply (&Route::drop_edit_group, this);
2220 edit_groups.erase (i);
2221 edit_group_removed (); /* EMIT SIGNAL */
2228 Session::remove_mix_group (RouteGroup& rg)
2230 list<RouteGroup*>::iterator i;
2232 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2233 (*i)->apply (&Route::drop_mix_group, this);
2234 mix_groups.erase (i);
2235 mix_group_removed (); /* EMIT SIGNAL */
2242 Session::mix_group_by_name (string name)
2244 list<RouteGroup *>::iterator i;
2246 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2247 if ((*i)->name() == name) {
2255 Session::edit_group_by_name (string name)
2257 list<RouteGroup *>::iterator i;
2259 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2260 if ((*i)->name() == name) {
2268 Session::begin_reversible_command (const string& name)
2270 current_trans = new UndoTransaction;
2271 current_trans->set_name (name);
2275 Session::commit_reversible_command (Command *cmd)
2280 current_trans->add_command (cmd);
2283 if (current_trans->empty()) {
2287 gettimeofday (&now, 0);
2288 current_trans->set_timestamp (now);
2290 _history.add (current_trans);
2293 Session::GlobalRouteBooleanState
2294 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2296 GlobalRouteBooleanState s;
2297 boost::shared_ptr<RouteList> r = routes.reader ();
2299 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2300 if (!(*i)->is_hidden()) {
2301 RouteBooleanState v;
2304 Route* r = (*i).get();
2305 v.second = (r->*method)();
2314 Session::GlobalRouteMeterState
2315 Session::get_global_route_metering ()
2317 GlobalRouteMeterState s;
2318 boost::shared_ptr<RouteList> r = routes.reader ();
2320 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2321 if (!(*i)->is_hidden()) {
2325 v.second = (*i)->meter_point();
2335 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2337 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2339 boost::shared_ptr<Route> r = (i->first.lock());
2342 r->set_meter_point (i->second, arg);
2348 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2350 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2352 boost::shared_ptr<Route> r = (i->first.lock());
2355 Route* rp = r.get();
2356 (rp->*method) (i->second, arg);
2362 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2364 set_global_route_boolean (s, &Route::set_mute, src);
2368 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2370 set_global_route_boolean (s, &Route::set_solo, src);
2374 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2376 set_global_route_boolean (s, &Route::set_record_enable, src);
2381 Session::global_mute_memento (void* src)
2383 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2387 Session::global_metering_memento (void* src)
2389 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2393 Session::global_solo_memento (void* src)
2395 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2399 Session::global_record_enable_memento (void* src)
2401 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2406 accept_all_non_peak_files (const string& path, void *arg)
2408 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2412 accept_all_state_files (const string& path, void *arg)
2414 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2418 Session::find_all_sources (string path, set<string>& result)
2423 if (!tree.read (path)) {
2427 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2432 XMLNodeConstIterator niter;
2434 nlist = node->children();
2438 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2442 if ((prop = (*niter)->property (X_("name"))) == 0) {
2446 if (prop->value()[0] == '/') {
2447 /* external file, ignore */
2451 sys::path source_path = _session_dir->sound_path ();
2453 source_path /= prop->value ();
2455 result.insert (source_path.to_string ());
2462 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2464 PathScanner scanner;
2465 vector<string*>* state_files;
2467 string this_snapshot_path;
2473 if (ripped[ripped.length()-1] == '/') {
2474 ripped = ripped.substr (0, ripped.length() - 1);
2477 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2479 if (state_files == 0) {
2484 this_snapshot_path = _path;
2485 this_snapshot_path += _current_snapshot_name;
2486 this_snapshot_path += statefile_suffix;
2488 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2490 if (exclude_this_snapshot && **i == this_snapshot_path) {
2494 if (find_all_sources (**i, result) < 0) {
2502 struct RegionCounter {
2503 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2504 AudioSourceList::iterator iter;
2505 boost::shared_ptr<Region> region;
2508 RegionCounter() : count (0) {}
2512 Session::cleanup_sources (Session::cleanup_report& rep)
2514 // FIXME: needs adaptation to midi
2516 vector<boost::shared_ptr<Source> > dead_sources;
2517 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2518 PathScanner scanner;
2520 vector<space_and_path>::iterator i;
2521 vector<space_and_path>::iterator nexti;
2522 vector<string*>* soundfiles;
2523 vector<string> unused;
2524 set<string> all_sources;
2529 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2532 /* step 1: consider deleting all unused playlists */
2534 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2537 status = AskAboutPlaylistDeletion (*x);
2546 playlists_tbd.push_back (*x);
2550 /* leave it alone */
2555 /* now delete any that were marked for deletion */
2557 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2558 (*x)->drop_references ();
2561 playlists_tbd.clear ();
2563 /* step 2: find all un-used sources */
2568 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2570 SourceMap::iterator tmp;
2575 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2579 if (!i->second->used() && i->second->length() > 0) {
2580 dead_sources.push_back (i->second);
2581 i->second->GoingAway();
2587 /* build a list of all the possible sound directories for the session */
2589 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2594 SessionDirectory sdir ((*i).path);
2595 sound_path += sdir.sound_path().to_string();
2597 if (nexti != session_dirs.end()) {
2604 /* now do the same thing for the files that ended up in the sounds dir(s)
2605 but are not referenced as sources in any snapshot.
2608 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2610 if (soundfiles == 0) {
2614 /* find all sources, but don't use this snapshot because the
2615 state file on disk still references sources we may have already
2619 find_all_sources_across_snapshots (all_sources, true);
2621 /* add our current source list
2624 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2625 boost::shared_ptr<AudioFileSource> fs;
2627 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2628 all_sources.insert (fs->path());
2632 char tmppath1[PATH_MAX+1];
2633 char tmppath2[PATH_MAX+1];
2635 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2640 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2642 realpath(spath.c_str(), tmppath1);
2643 realpath((*i).c_str(), tmppath2);
2645 if (strcmp(tmppath1, tmppath2) == 0) {
2652 unused.push_back (spath);
2656 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2658 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2659 struct stat statbuf;
2661 rep.paths.push_back (*x);
2662 if (stat ((*x).c_str(), &statbuf) == 0) {
2663 rep.space += statbuf.st_size;
2668 /* don't move the file across filesystems, just
2669 stick it in the `dead_sound_dir_name' directory
2670 on whichever filesystem it was already on.
2673 if ((*x).find ("/sounds/") != string::npos) {
2675 /* old school, go up 1 level */
2677 newpath = Glib::path_get_dirname (*x); // "sounds"
2678 newpath = Glib::path_get_dirname (newpath); // "session-name"
2682 /* new school, go up 4 levels */
2684 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2685 newpath = Glib::path_get_dirname (newpath); // "session-name"
2686 newpath = Glib::path_get_dirname (newpath); // "interchange"
2687 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2691 newpath += dead_sound_dir_name;
2693 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2694 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2699 newpath += Glib::path_get_basename ((*x));
2701 if (access (newpath.c_str(), F_OK) == 0) {
2703 /* the new path already exists, try versioning */
2705 char buf[PATH_MAX+1];
2709 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2712 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2713 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2717 if (version == 999) {
2718 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2722 newpath = newpath_v;
2727 /* it doesn't exist, or we can't read it or something */
2731 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2732 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2733 (*x), newpath, strerror (errno))
2738 /* see if there an easy to find peakfile for this file, and remove it.
2741 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2742 peakpath += peakfile_suffix;
2744 if (access (peakpath.c_str(), W_OK) == 0) {
2745 if (::unlink (peakpath.c_str()) != 0) {
2746 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2747 peakpath, _path, strerror (errno))
2749 /* try to back out */
2750 rename (newpath.c_str(), _path.c_str());
2758 /* dump the history list */
2762 /* save state so we don't end up a session file
2763 referring to non-existent sources.
2769 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2775 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2777 // FIXME: needs adaptation for MIDI
2779 vector<space_and_path>::iterator i;
2780 string dead_sound_dir;
2781 struct dirent* dentry;
2782 struct stat statbuf;
2788 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2790 dead_sound_dir = (*i).path;
2791 dead_sound_dir += dead_sound_dir_name;
2793 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2797 while ((dentry = readdir (dead)) != 0) {
2799 /* avoid '.' and '..' */
2801 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2802 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2808 fullpath = dead_sound_dir;
2810 fullpath += dentry->d_name;
2812 if (stat (fullpath.c_str(), &statbuf)) {
2816 if (!S_ISREG (statbuf.st_mode)) {
2820 if (unlink (fullpath.c_str())) {
2821 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2822 fullpath, strerror (errno))
2826 rep.paths.push_back (dentry->d_name);
2827 rep.space += statbuf.st_size;
2838 Session::set_dirty ()
2840 bool was_dirty = dirty();
2842 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2846 DirtyChanged(); /* EMIT SIGNAL */
2852 Session::set_clean ()
2854 bool was_dirty = dirty();
2856 _state_of_the_state = Clean;
2860 DirtyChanged(); /* EMIT SIGNAL */
2865 Session::set_deletion_in_progress ()
2867 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2872 Session::add_controllable (boost::shared_ptr<Controllable> c)
2874 /* this adds a controllable to the list managed by the Session.
2875 this is a subset of those managed by the Controllable class
2876 itself, and represents the only ones whose state will be saved
2877 as part of the session.
2880 Glib::Mutex::Lock lm (controllables_lock);
2881 controllables.insert (c);
2884 struct null_deleter { void operator()(void const *) const {} };
2887 Session::remove_controllable (Controllable* c)
2889 if (_state_of_the_state | Deletion) {
2893 Glib::Mutex::Lock lm (controllables_lock);
2895 Controllables::iterator x = controllables.find(
2896 boost::shared_ptr<Controllable>(c, null_deleter()));
2898 if (x != controllables.end()) {
2899 controllables.erase (x);
2903 boost::shared_ptr<Controllable>
2904 Session::controllable_by_id (const PBD::ID& id)
2906 Glib::Mutex::Lock lm (controllables_lock);
2908 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2909 if ((*i)->id() == id) {
2914 return boost::shared_ptr<Controllable>();
2918 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2920 Stateful::add_instant_xml (node, _path);
2921 if (write_to_config) {
2922 Config->add_instant_xml (node);
2927 Session::instant_xml (const string& node_name)
2929 return Stateful::instant_xml (node_name, _path);
2933 Session::save_history (string snapshot_name)
2937 if (snapshot_name.empty()) {
2938 snapshot_name = _current_snapshot_name;
2941 const string history_filename = snapshot_name + history_suffix;
2942 const string backup_filename = history_filename + backup_suffix;
2943 const sys::path xml_path = _session_dir->root_path() / history_filename;
2944 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2946 if (sys::exists (xml_path)) {
2949 sys::rename (xml_path, backup_path);
2951 catch (const sys::filesystem_error& err)
2953 error << _("could not backup old history file, current history not saved") << endmsg;
2959 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2963 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2965 if (!tree.write (xml_path.to_string()))
2967 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2971 sys::remove (xml_path);
2972 sys::rename (backup_path, xml_path);
2974 catch (const sys::filesystem_error& err)
2976 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2977 backup_path.to_string(), err.what()) << endmsg;
2987 Session::restore_history (string snapshot_name)
2991 if (snapshot_name.empty()) {
2992 snapshot_name = _current_snapshot_name;
2995 const string xml_filename = snapshot_name + history_suffix;
2996 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2998 cerr << "Loading history from " << xml_path.to_string() << endmsg;
3000 if (!sys::exists (xml_path)) {
3001 info << string_compose (_("%1: no history file \"%2\" for this session."),
3002 _name, xml_path.to_string()) << endmsg;
3006 if (!tree.read (xml_path.to_string())) {
3007 error << string_compose (_("Could not understand session history file \"%1\""),
3008 xml_path.to_string()) << endmsg;
3015 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3018 UndoTransaction* ut = new UndoTransaction ();
3021 ut->set_name(t->property("name")->value());
3022 stringstream ss(t->property("tv-sec")->value());
3024 ss.str(t->property("tv-usec")->value());
3026 ut->set_timestamp(tv);
3028 for (XMLNodeConstIterator child_it = t->children().begin();
3029 child_it != t->children().end(); child_it++)
3031 XMLNode *n = *child_it;
3034 if (n->name() == "MementoCommand" ||
3035 n->name() == "MementoUndoCommand" ||
3036 n->name() == "MementoRedoCommand") {
3038 if ((c = memento_command_factory(n))) {
3042 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3044 if ((c = global_state_command_factory (*n))) {
3045 ut->add_command (c);
3048 } else if (n->name() == "DeltaCommand") {
3049 PBD::ID id(n->property("midi-source")->value());
3050 boost::shared_ptr<MidiSource> midi_source =
3051 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3053 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
3055 error << "FIXME: Failed to downcast MidiSource for DeltaCommand" << endmsg;
3058 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3069 Session::config_changed (const char* parameter_name)
3071 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3073 if (PARAM_IS ("seamless-loop")) {
3075 } else if (PARAM_IS ("rf-speed")) {
3077 } else if (PARAM_IS ("auto-loop")) {
3079 } else if (PARAM_IS ("auto-input")) {
3081 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3082 /* auto-input only makes a difference if we're rolling */
3084 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3086 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3087 if ((*i)->record_enabled ()) {
3088 (*i)->monitor_input (!Config->get_auto_input());
3093 } else if (PARAM_IS ("punch-in")) {
3097 if ((location = _locations.auto_punch_location()) != 0) {
3099 if (Config->get_punch_in ()) {
3100 replace_event (Event::PunchIn, location->start());
3102 remove_event (location->start(), Event::PunchIn);
3106 } else if (PARAM_IS ("punch-out")) {
3110 if ((location = _locations.auto_punch_location()) != 0) {
3112 if (Config->get_punch_out()) {
3113 replace_event (Event::PunchOut, location->end());
3115 clear_events (Event::PunchOut);
3119 } else if (PARAM_IS ("edit-mode")) {
3121 Glib::Mutex::Lock lm (playlist_lock);
3123 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3124 (*i)->set_edit_mode (Config->get_edit_mode ());
3127 } else if (PARAM_IS ("use-video-sync")) {
3129 waiting_for_sync_offset = Config->get_use_video_sync();
3131 } else if (PARAM_IS ("mmc-control")) {
3133 //poke_midi_thread ();
3135 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
3138 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3141 } else if (PARAM_IS ("mmc-send-id")) {
3144 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3147 } else if (PARAM_IS ("midi-control")) {
3149 //poke_midi_thread ();
3151 } else if (PARAM_IS ("raid-path")) {
3153 setup_raid_path (Config->get_raid_path());
3155 } else if (PARAM_IS ("smpte-format")) {
3159 } else if (PARAM_IS ("video-pullup")) {
3163 } else if (PARAM_IS ("seamless-loop")) {
3165 if (play_loop && transport_rolling()) {
3166 // to reset diskstreams etc
3167 request_play_loop (true);
3170 } else if (PARAM_IS ("rf-speed")) {
3172 cumulative_rf_motion = 0;
3175 } else if (PARAM_IS ("click-sound")) {
3177 setup_click_sounds (1);
3179 } else if (PARAM_IS ("click-emphasis-sound")) {
3181 setup_click_sounds (-1);
3183 } else if (PARAM_IS ("clicking")) {
3185 if (Config->get_clicking()) {
3186 if (_click_io && click_data) { // don't require emphasis data
3193 } else if (PARAM_IS ("send-mtc")) {
3195 /* only set the internal flag if we have
3199 if (_mtc_port != 0) {
3200 session_send_mtc = Config->get_send_mtc();
3201 if (session_send_mtc) {
3202 /* mark us ready to send */
3203 next_quarter_frame_to_send = 0;
3206 session_send_mtc = false;
3209 } else if (PARAM_IS ("send-mmc")) {
3211 /* only set the internal flag if we have
3215 if (_mmc_port != 0) {
3216 session_send_mmc = Config->get_send_mmc();
3219 session_send_mmc = false;
3222 } else if (PARAM_IS ("midi-feedback")) {
3224 /* only set the internal flag if we have
3228 if (_mtc_port != 0) {
3229 session_midi_feedback = Config->get_midi_feedback();
3232 } else if (PARAM_IS ("jack-time-master")) {
3234 engine().reset_timebase ();
3236 } else if (PARAM_IS ("native-file-header-format")) {
3238 if (!first_file_header_format_reset) {
3239 reset_native_file_format ();
3242 first_file_header_format_reset = false;
3244 } else if (PARAM_IS ("native-file-data-format")) {
3246 if (!first_file_data_format_reset) {
3247 reset_native_file_format ();
3250 first_file_data_format_reset = false;
3252 } else if (PARAM_IS ("slave-source")) {
3253 set_slave_source (Config->get_slave_source());
3254 } else if (PARAM_IS ("remote-model")) {
3255 set_remote_control_ids ();
3256 } else if (PARAM_IS ("denormal-model")) {
3258 } else if (PARAM_IS ("history-depth")) {
3259 set_history_depth (Config->get_history_depth());
3260 } else if (PARAM_IS ("sync-all-route-ordering")) {
3261 sync_order_keys ("session");
3262 } else if (PARAM_IS ("initial-program-change")) {
3264 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3267 buf[0] = MIDI::program; // channel zero by default
3268 buf[1] = (Config->get_initial_program_change() & 0x7f);
3270 _mmc_port->midimsg (buf, sizeof (buf), 0);
3272 } else if (PARAM_IS ("initial-program-change")) {
3274 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3275 MIDI::byte* buf = new MIDI::byte[2];
3277 buf[0] = MIDI::program; // channel zero by default
3278 buf[1] = (Config->get_initial_program_change() & 0x7f);
3279 // deliver_midi (_mmc_port, buf, 2);
3281 } else if (PARAM_IS ("solo-mute-override")) {
3282 catch_up_on_solo_mute_override ();
3292 Session::set_history_depth (uint32_t d)
3294 _history.set_depth (d);