2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #define __STDC_FORMAT_MACROS 1
28 #include <sigc++/bind.h>
30 #include <cstdio> /* snprintf(3) ... grrr */
45 #include <sys/param.h>
46 #include <sys/mount.h>
50 #include <glibmm/thread.h>
52 #include "midi++/mmc.h"
53 #include "midi++/port.h"
55 #include "pbd/error.h"
56 #include "pbd/pathscanner.h"
57 #include "pbd/pthread_utils.h"
58 #include "pbd/search_path.h"
59 #include "pbd/stacktrace.h"
61 #include "ardour/audioengine.h"
62 #include "ardour/configuration.h"
63 #include "ardour/session.h"
64 #include "ardour/session_directory.h"
65 #include "ardour/session_utils.h"
66 #include "ardour/session_state_utils.h"
67 #include "ardour/session_metadata.h"
68 #include "ardour/buffer.h"
69 #include "ardour/audio_diskstream.h"
70 #include "ardour/midi_diskstream.h"
71 #include "ardour/utils.h"
72 #include "ardour/audioplaylist.h"
73 #include "ardour/midi_playlist.h"
74 #include "ardour/smf_source.h"
75 #include "ardour/audiofilesource.h"
76 #include "ardour/silentfilesource.h"
77 #include "ardour/sndfilesource.h"
78 #include "ardour/midi_source.h"
79 #include "ardour/sndfile_helpers.h"
80 #include "ardour/auditioner.h"
81 #include "ardour/io_processor.h"
82 #include "ardour/send.h"
83 #include "ardour/processor.h"
84 #include "ardour/user_bundle.h"
85 #include "ardour/slave.h"
86 #include "ardour/tempo.h"
87 #include "ardour/audio_track.h"
88 #include "ardour/midi_track.h"
89 #include "ardour/midi_patch_manager.h"
90 #include "ardour/cycle_timer.h"
91 #include "ardour/utils.h"
92 #include "ardour/named_selection.h"
93 #include "ardour/version.h"
94 #include "ardour/location.h"
95 #include "ardour/audioregion.h"
96 #include "ardour/midi_region.h"
97 #include "ardour/crossfade.h"
98 #include "ardour/control_protocol_manager.h"
99 #include "ardour/region_factory.h"
100 #include "ardour/source_factory.h"
101 #include "ardour/playlist_factory.h"
102 #include "ardour/filename_extensions.h"
103 #include "ardour/directory_names.h"
104 #include "ardour/template_utils.h"
105 #include "ardour/ticker.h"
106 #include "ardour/route_group.h"
108 #include "control_protocol/control_protocol.h"
114 using namespace ARDOUR;
118 Session::first_stage_init (string fullpath, string snapshot_name)
120 if (fullpath.length() == 0) {
122 throw failed_constructor();
125 char buf[PATH_MAX+1];
126 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
127 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
129 throw failed_constructor();
134 if (_path[_path.length()-1] != '/') {
138 /* these two are just provisional settings. set_state()
139 will likely override them.
142 _name = _current_snapshot_name = snapshot_name;
144 set_history_depth (Config->get_history_depth());
146 _current_frame_rate = _engine.frame_rate ();
147 _nominal_frame_rate = _current_frame_rate;
148 _base_frame_rate = _current_frame_rate;
150 _tempo_map = new TempoMap (_current_frame_rate);
151 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
155 g_atomic_int_set (&processing_prohibited, 0);
157 _transport_speed = 0;
158 _last_transport_speed = 0;
159 phi = (uint64_t) (0x1000000);
161 auto_play_legal = false;
162 transport_sub_state = 0;
163 _transport_frame = 0;
164 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
165 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
166 _end_location_is_free = true;
167 g_atomic_int_set (&_record_status, Disabled);
168 loop_changing = false;
171 _last_roll_location = 0;
172 _last_record_location = 0;
173 pending_locate_frame = 0;
174 pending_locate_roll = false;
175 pending_locate_flush = false;
176 audio_dstream_buffer_size = 0;
177 midi_dstream_buffer_size = 0;
178 state_was_pending = false;
180 outbound_mtc_smpte_frame = 0;
181 next_quarter_frame_to_send = -1;
182 current_block_size = 0;
183 solo_update_disabled = false;
184 currently_soloing = false;
185 _have_captured = false;
186 _worst_output_latency = 0;
187 _worst_input_latency = 0;
188 _worst_track_latency = 0;
189 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
192 session_send_mmc = false;
193 session_send_mtc = false;
194 post_transport_work = PostTransportWork (0);
195 g_atomic_int_set (&butler_should_do_transport_work, 0);
196 g_atomic_int_set (&_playback_load, 100);
197 g_atomic_int_set (&_capture_load, 100);
198 g_atomic_int_set (&_playback_load_min, 100);
199 g_atomic_int_set (&_capture_load_min, 100);
202 _exporting_realtime = false;
203 _gain_automation_buffer = 0;
204 _pan_automation_buffer = 0;
206 pending_abort = false;
207 destructive_index = 0;
208 first_file_data_format_reset = true;
209 first_file_header_format_reset = true;
210 butler_thread = (pthread_t) 0;
211 //midi_thread = (pthread_t) 0;
213 AudioDiskstream::allocate_working_buffers();
215 /* default short fade = 15ms */
217 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
218 SndFileSource::setup_standard_crossfades (frame_rate());
220 last_mmc_step.tv_sec = 0;
221 last_mmc_step.tv_usec = 0;
224 /* click sounds are unset by default, which causes us to internal
225 waveforms for clicks.
229 click_emphasis_length = 0;
232 process_function = &Session::process_with_events;
234 if (Config->get_use_video_sync()) {
235 waiting_for_sync_offset = true;
237 waiting_for_sync_offset = false;
242 _smpte_offset_negative = true;
243 last_smpte_valid = false;
247 last_rr_session_dir = session_dirs.begin();
248 refresh_disk_space ();
250 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
254 average_slave_delta = 1800; // !!! why 1800 ????
255 have_first_delta_accumulator = false;
256 delta_accumulator_cnt = 0;
257 slave_state = Stopped;
259 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
261 /* These are all static "per-class" signals */
263 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
264 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
265 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
266 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
267 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
268 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
270 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
272 IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
274 /* stop IO objects from doing stuff until we're ready for them */
276 IO::disable_panners ();
277 IO::disable_ports ();
278 IO::disable_connecting ();
282 Session::second_stage_init (bool new_session)
284 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
287 if (load_state (_current_snapshot_name)) {
290 remove_empty_sounds ();
293 if (start_butler_thread()) {
297 if (start_midi_thread ()) {
301 // set_state() will call setup_raid_path(), but if it's a new session we need
302 // to call setup_raid_path() here.
305 if (set_state (*state_tree->root())) {
309 setup_raid_path(_path);
312 /* we can't save till after ::when_engine_running() is called,
313 because otherwise we save state with no connections made.
314 therefore, we reset _state_of_the_state because ::set_state()
315 will have cleared it.
317 we also have to include Loading so that any events that get
318 generated between here and the end of ::when_engine_running()
319 will be processed directly rather than queued.
322 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
325 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
326 _locations.added.connect (mem_fun (this, &Session::locations_added));
327 setup_click_sounds (0);
328 setup_midi_control ();
330 /* Pay attention ... */
332 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
333 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
336 when_engine_running();
339 /* handle this one in a different way than all others, so that its clear what happened */
341 catch (AudioEngine::PortRegistrationFailure& err) {
342 error << err.what() << endmsg;
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;
415 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
416 sp.path = (*i).to_string ();
417 sp.blocks = 0; // not needed
418 session_dirs.push_back (sp);
420 SessionDirectory sdir(sp.path);
422 sound_search_path += sdir.sound_path ();
423 midi_search_path += sdir.midi_path ();
426 // set the search path for each data type
427 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
428 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
430 // reset the round-robin soundfile path thingie
431 last_rr_session_dir = session_dirs.begin();
435 Session::ensure_subdirs ()
439 dir = session_directory().peak_path().to_string();
441 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
442 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
446 dir = session_directory().sound_path().to_string();
448 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
449 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
453 dir = session_directory().midi_path().to_string();
455 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
456 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
460 dir = session_directory().dead_sound_path().to_string();
462 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
463 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
467 dir = session_directory().export_path().to_string();
469 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
470 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
474 dir = analysis_dir ();
476 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
477 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
485 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
488 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
489 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
493 if (ensure_subdirs ()) {
497 /* check new_session so we don't overwrite an existing one */
499 if (!mix_template.empty()) {
500 std::string in_path = mix_template;
502 ifstream in(in_path.c_str());
505 string out_path = _path;
507 out_path += statefile_suffix;
509 ofstream out(out_path.c_str());
514 // okay, session is set up. Treat like normal saved
515 // session from now on.
521 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
527 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
534 /* Instantiate metadata */
536 _metadata = new SessionMetadata ();
538 /* set initial start + end point */
540 start_location->set_end (0);
541 _locations.add (start_location);
543 end_location->set_end (initial_length);
544 _locations.add (end_location);
546 _state_of_the_state = Clean;
555 Session::load_diskstreams (const XMLNode& node)
558 XMLNodeConstIterator citer;
560 clist = node.children();
562 for (citer = clist.begin(); citer != clist.end(); ++citer) {
565 /* diskstreams added automatically by DiskstreamCreated handler */
566 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
567 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
568 add_diskstream (dstream);
569 } else if ((*citer)->name() == "MidiDiskstream") {
570 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
571 add_diskstream (dstream);
573 error << _("Session: unknown diskstream type in XML") << endmsg;
577 catch (failed_constructor& err) {
578 error << _("Session: could not load diskstream via XML state") << endmsg;
587 Session::maybe_write_autosave()
589 if (dirty() && record_status() != Recording) {
590 save_state("", true);
595 Session::remove_pending_capture_state ()
597 sys::path pending_state_file_path(_session_dir->root_path());
599 pending_state_file_path /= _current_snapshot_name + pending_suffix;
603 sys::remove (pending_state_file_path);
605 catch(sys::filesystem_error& ex)
607 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
608 pending_state_file_path.to_string(), ex.what()) << endmsg;
612 /** Rename a state file.
613 * @param snapshot_name Snapshot name.
616 Session::rename_state (string old_name, string new_name)
618 if (old_name == _current_snapshot_name || old_name == _name) {
619 /* refuse to rename the current snapshot or the "main" one */
623 const string old_xml_filename = old_name + statefile_suffix;
624 const string new_xml_filename = new_name + statefile_suffix;
626 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
627 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
631 sys::rename (old_xml_path, new_xml_path);
633 catch (const sys::filesystem_error& err)
635 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
636 old_name, new_name, err.what()) << endmsg;
640 /** Remove a state file.
641 * @param snapshot_name Snapshot name.
644 Session::remove_state (string snapshot_name)
646 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
647 // refuse to remove the current snapshot or the "main" one
651 sys::path xml_path(_session_dir->root_path());
653 xml_path /= snapshot_name + statefile_suffix;
655 if (!create_backup_file (xml_path)) {
656 // don't remove it if a backup can't be made
657 // create_backup_file will log the error.
662 sys::remove (xml_path);
666 Session::save_state (string snapshot_name, bool pending)
669 sys::path xml_path(_session_dir->root_path());
671 if (_state_of_the_state & CannotSave) {
675 if (!_engine.connected ()) {
676 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
681 /* tell sources we're saving first, in case they write out to a new file
682 * which should be saved with the state rather than the old one */
683 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
684 i->second->session_saved();
686 tree.set_root (&get_state());
688 if (snapshot_name.empty()) {
689 snapshot_name = _current_snapshot_name;
694 /* proper save: use statefile_suffix (.ardour in English) */
696 xml_path /= snapshot_name + statefile_suffix;
698 /* make a backup copy of the old file */
700 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
701 // create_backup_file will log the error
707 /* pending save: use pending_suffix (.pending in English) */
708 xml_path /= snapshot_name + pending_suffix;
711 sys::path tmp_path(_session_dir->root_path());
713 tmp_path /= snapshot_name + temp_suffix;
715 // cerr << "actually writing state to " << xml_path.to_string() << endl;
717 if (!tree.write (tmp_path.to_string())) {
718 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
719 sys::remove (tmp_path);
724 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
725 error << string_compose (_("could not rename temporary session file %1 to %2"),
726 tmp_path.to_string(), xml_path.to_string()) << endmsg;
727 sys::remove (tmp_path);
734 save_history (snapshot_name);
736 bool was_dirty = dirty();
738 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
741 DirtyChanged (); /* EMIT SIGNAL */
744 StateSaved (snapshot_name); /* EMIT SIGNAL */
751 Session::restore_state (string snapshot_name)
753 if (load_state (snapshot_name) == 0) {
754 set_state (*state_tree->root());
761 Session::load_state (string snapshot_name)
766 state_was_pending = false;
768 /* check for leftover pending state from a crashed capture attempt */
770 sys::path xmlpath(_session_dir->root_path());
771 xmlpath /= snapshot_name + pending_suffix;
773 if (sys::exists (xmlpath)) {
775 /* there is pending state from a crashed capture attempt */
777 if (AskAboutPendingState()) {
778 state_was_pending = true;
782 if (!state_was_pending) {
783 xmlpath = _session_dir->root_path();
784 xmlpath /= snapshot_name + statefile_suffix;
787 if (!sys::exists (xmlpath)) {
788 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
792 state_tree = new XMLTree;
796 if (!state_tree->read (xmlpath.to_string())) {
797 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
803 XMLNode& root (*state_tree->root());
805 if (root.name() != X_("Session")) {
806 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
812 const XMLProperty* prop;
813 bool is_old = false; // session is _very_ old (pre-2.0)
815 if ((prop = root.property ("version")) == 0) {
816 /* no version implies very old version of Ardour */
820 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
821 if (major_version < 2) {
828 sys::path backup_path(_session_dir->root_path());
830 backup_path /= snapshot_name + "-1" + statefile_suffix;
832 // only create a backup once
833 if (sys::exists (backup_path)) {
837 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
838 xmlpath.to_string(), backup_path.to_string())
843 sys::copy_file (xmlpath, backup_path);
845 catch(sys::filesystem_error& ex)
847 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
848 xmlpath.to_string(), ex.what())
858 Session::load_options (const XMLNode& node)
862 LocaleGuard lg (X_("POSIX"));
864 Config->set_variables (node, ConfigVariableBase::Session);
866 /* now reset MIDI ports because the session can have its own
872 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
873 if ((prop = child->property ("val")) != 0) {
874 _end_location_is_free = (prop->value() == "yes");
882 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
884 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
885 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
887 return owner & modified_by_session_or_user;
891 Session::get_options () const
894 LocaleGuard lg (X_("POSIX"));
896 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
898 child = option_root.add_child ("end-marker-is-free");
899 child->add_property ("val", _end_location_is_free ? "yes" : "no");
911 Session::get_template()
913 /* if we don't disable rec-enable, diskstreams
914 will believe they need to store their capture
915 sources in their state node.
918 disable_record (false);
924 Session::state(bool full_state)
926 XMLNode* node = new XMLNode("Session");
929 // store libardour version, just in case
931 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
932 node->add_property("version", string(buf));
934 /* store configuration settings */
938 node->add_property ("name", _name);
939 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
940 node->add_property ("sample-rate", buf);
942 if (session_dirs.size() > 1) {
946 vector<space_and_path>::iterator i = session_dirs.begin();
947 vector<space_and_path>::iterator next;
949 ++i; /* skip the first one */
953 while (i != session_dirs.end()) {
957 if (next != session_dirs.end()) {
967 child = node->add_child ("Path");
968 child->add_content (p);
972 /* save the ID counter */
974 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
975 node->add_property ("id-counter", buf);
977 /* various options */
979 node->add_child_nocopy (get_options());
981 node->add_child_nocopy (_metadata->get_state());
983 child = node->add_child ("Sources");
986 Glib::Mutex::Lock sl (source_lock);
988 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
990 /* Don't save information about non-destructive file sources that are empty */
991 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
993 boost::shared_ptr<AudioFileSource> fs;
994 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
995 if (!fs->destructive()) {
996 if (fs->length(fs->timeline_position()) == 0) {
1002 child->add_child_nocopy (siter->second->get_state());
1006 child = node->add_child ("Regions");
1009 Glib::Mutex::Lock rl (region_lock);
1011 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
1013 /* only store regions not attached to playlists */
1015 if (i->second->playlist() == 0) {
1016 child->add_child_nocopy (i->second->state (true));
1021 child = node->add_child ("DiskStreams");
1024 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1025 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1026 if (!(*i)->hidden()) {
1027 child->add_child_nocopy ((*i)->get_state());
1033 node->add_child_nocopy (_locations.get_state());
1035 // for a template, just create a new Locations, populate it
1036 // with the default start and end, and get the state for that.
1038 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1039 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1042 end->set_end(compute_initial_length());
1044 node->add_child_nocopy (loc.get_state());
1047 child = node->add_child ("Bundles");
1049 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1050 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1051 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1053 child->add_child_nocopy (b->get_state());
1058 child = node->add_child ("Routes");
1060 boost::shared_ptr<RouteList> r = routes.reader ();
1062 RoutePublicOrderSorter cmp;
1063 RouteList public_order (*r);
1064 public_order.sort (cmp);
1066 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1067 if (!(*i)->is_hidden()) {
1069 child->add_child_nocopy ((*i)->get_state());
1071 child->add_child_nocopy ((*i)->get_template());
1078 child = node->add_child ("EditGroups");
1079 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1080 child->add_child_nocopy ((*i)->get_state());
1083 child = node->add_child ("MixGroups");
1084 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1085 child->add_child_nocopy ((*i)->get_state());
1088 child = node->add_child ("Playlists");
1089 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1090 if (!(*i)->hidden()) {
1091 if (!(*i)->empty()) {
1093 child->add_child_nocopy ((*i)->get_state());
1095 child->add_child_nocopy ((*i)->get_template());
1101 child = node->add_child ("UnusedPlaylists");
1102 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1103 if (!(*i)->hidden()) {
1104 if (!(*i)->empty()) {
1106 child->add_child_nocopy ((*i)->get_state());
1108 child->add_child_nocopy ((*i)->get_template());
1116 child = node->add_child ("Click");
1117 child->add_child_nocopy (_click_io->state (full_state));
1121 child = node->add_child ("NamedSelections");
1122 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1124 child->add_child_nocopy ((*i)->get_state());
1129 node->add_child_nocopy (_tempo_map->get_state());
1131 node->add_child_nocopy (get_control_protocol_state());
1134 node->add_child_copy (*_extra_xml);
1141 Session::get_control_protocol_state ()
1143 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1144 return cpm.get_state();
1148 Session::set_state (const XMLNode& node)
1152 const XMLProperty* prop;
1155 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1157 if (node.name() != X_("Session")){
1158 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1162 if ((prop = node.property ("name")) != 0) {
1163 _name = prop->value ();
1166 if ((prop = node.property (X_("sample-rate"))) != 0) {
1168 _nominal_frame_rate = atoi (prop->value());
1170 if (_nominal_frame_rate != _current_frame_rate) {
1171 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1177 setup_raid_path(_session_dir->root_path().to_string());
1179 if ((prop = node.property (X_("id-counter"))) != 0) {
1181 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1182 ID::init_counter (x);
1184 /* old sessions used a timebased counter, so fake
1185 the startup ID counter based on a standard
1190 ID::init_counter (now);
1194 IO::disable_ports ();
1195 IO::disable_connecting ();
1197 /* Object loading order:
1202 MIDI Control // relies on data from Options/Config
1216 if ((child = find_named_node (node, "Extra")) != 0) {
1217 _extra_xml = new XMLNode (*child);
1220 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1221 load_options (*child);
1222 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1223 load_options (*child);
1225 error << _("Session: XML state has no options section") << endmsg;
1228 if (use_config_midi_ports ()) {
1231 if ((child = find_named_node (node, "Metadata")) == 0) {
1232 warning << _("Session: XML state has no metadata section (2.0 session?)") << endmsg;
1233 } else if (_metadata->set_state (*child)) {
1237 if ((child = find_named_node (node, "Locations")) == 0) {
1238 error << _("Session: XML state has no locations section") << endmsg;
1240 } else if (_locations.set_state (*child)) {
1246 if ((location = _locations.auto_loop_location()) != 0) {
1247 set_auto_loop_location (location);
1250 if ((location = _locations.auto_punch_location()) != 0) {
1251 set_auto_punch_location (location);
1254 if ((location = _locations.end_location()) == 0) {
1255 _locations.add (end_location);
1257 delete end_location;
1258 end_location = location;
1261 if ((location = _locations.start_location()) == 0) {
1262 _locations.add (start_location);
1264 delete start_location;
1265 start_location = location;
1268 AudioFileSource::set_header_position_offset (start_location->start());
1270 if ((child = find_named_node (node, "Sources")) == 0) {
1271 error << _("Session: XML state has no sources section") << endmsg;
1273 } else if (load_sources (*child)) {
1277 if ((child = find_named_node (node, "Regions")) == 0) {
1278 error << _("Session: XML state has no Regions section") << endmsg;
1280 } else if (load_regions (*child)) {
1284 if ((child = find_named_node (node, "Playlists")) == 0) {
1285 error << _("Session: XML state has no playlists section") << endmsg;
1287 } else if (load_playlists (*child)) {
1291 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1293 } else if (load_unused_playlists (*child)) {
1297 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1298 if (load_named_selections (*child)) {
1303 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1304 error << _("Session: XML state has no diskstreams section") << endmsg;
1306 } else if (load_diskstreams (*child)) {
1310 if ((child = find_named_node (node, "Bundles")) == 0) {
1311 warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg;
1314 /* We can't load Bundles yet as they need to be able
1315 to convert from port names to Port objects, which can't happen until
1317 _bundle_xml_node = new XMLNode (*child);
1320 if ((child = find_named_node (node, "EditGroups")) == 0) {
1321 error << _("Session: XML state has no edit groups section") << endmsg;
1323 } else if (load_edit_groups (*child)) {
1327 if ((child = find_named_node (node, "MixGroups")) == 0) {
1328 error << _("Session: XML state has no mix groups section") << endmsg;
1330 } else if (load_mix_groups (*child)) {
1334 if ((child = find_named_node (node, "TempoMap")) == 0) {
1335 error << _("Session: XML state has no Tempo Map section") << endmsg;
1337 } else if (_tempo_map->set_state (*child)) {
1341 if ((child = find_named_node (node, "Routes")) == 0) {
1342 error << _("Session: XML state has no routes section") << endmsg;
1344 } else if (load_routes (*child)) {
1348 if ((child = find_named_node (node, "Click")) == 0) {
1349 warning << _("Session: XML state has no click section") << endmsg;
1350 } else if (_click_io) {
1351 _click_io->set_state (*child);
1354 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1355 ControlProtocolManager::instance().set_protocol_states (*child);
1358 /* here beginneth the second phase ... */
1360 StateReady (); /* EMIT SIGNAL */
1369 Session::load_routes (const XMLNode& node)
1372 XMLNodeConstIterator niter;
1373 RouteList new_routes;
1375 nlist = node.children();
1379 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1381 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1384 error << _("Session: cannot create Route from XML description.") << endmsg;
1388 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1390 new_routes.push_back (route);
1393 add_routes (new_routes, false);
1398 boost::shared_ptr<Route>
1399 Session::XMLRouteFactory (const XMLNode& node)
1401 if (node.name() != "Route") {
1402 return boost::shared_ptr<Route> ((Route*) 0);
1405 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1407 DataType type = DataType::AUDIO;
1408 const XMLProperty* prop = node.property("default-type");
1411 type = DataType(prop->value());
1414 assert(type != DataType::NIL);
1416 if (has_diskstream) {
1417 if (type == DataType::AUDIO) {
1418 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1421 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1425 boost::shared_ptr<Route> ret (new Route (*this, node));
1431 Session::load_regions (const XMLNode& node)
1434 XMLNodeConstIterator niter;
1435 boost::shared_ptr<Region> region;
1437 nlist = node.children();
1441 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1442 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1443 error << _("Session: cannot create Region from XML description.");
1444 const XMLProperty *name = (**niter).property("name");
1447 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1457 boost::shared_ptr<Region>
1458 Session::XMLRegionFactory (const XMLNode& node, bool full)
1460 const XMLProperty* type = node.property("type");
1464 if ( !type || type->value() == "audio" ) {
1466 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1468 } else if (type->value() == "midi") {
1470 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1474 } catch (failed_constructor& err) {
1475 return boost::shared_ptr<Region> ();
1478 return boost::shared_ptr<Region> ();
1481 boost::shared_ptr<AudioRegion>
1482 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1484 const XMLProperty* prop;
1485 boost::shared_ptr<Source> source;
1486 boost::shared_ptr<AudioSource> as;
1488 SourceList master_sources;
1489 uint32_t nchans = 1;
1492 if (node.name() != X_("Region")) {
1493 return boost::shared_ptr<AudioRegion>();
1496 if ((prop = node.property (X_("channels"))) != 0) {
1497 nchans = atoi (prop->value().c_str());
1500 if ((prop = node.property ("name")) == 0) {
1501 cerr << "no name for this region\n";
1505 if ((prop = node.property (X_("source-0"))) == 0) {
1506 if ((prop = node.property ("source")) == 0) {
1507 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1508 return boost::shared_ptr<AudioRegion>();
1512 PBD::ID s_id (prop->value());
1514 if ((source = source_by_id (s_id)) == 0) {
1515 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1516 return boost::shared_ptr<AudioRegion>();
1519 as = boost::dynamic_pointer_cast<AudioSource>(source);
1521 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1522 return boost::shared_ptr<AudioRegion>();
1525 sources.push_back (as);
1527 /* pickup other channels */
1529 for (uint32_t n=1; n < nchans; ++n) {
1530 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1531 if ((prop = node.property (buf)) != 0) {
1533 PBD::ID id2 (prop->value());
1535 if ((source = source_by_id (id2)) == 0) {
1536 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1537 return boost::shared_ptr<AudioRegion>();
1540 as = boost::dynamic_pointer_cast<AudioSource>(source);
1542 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1543 return boost::shared_ptr<AudioRegion>();
1545 sources.push_back (as);
1549 for (uint32_t n=1; n < nchans; ++n) {
1550 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1551 if ((prop = node.property (buf)) != 0) {
1553 PBD::ID id2 (prop->value());
1555 if ((source = source_by_id (id2)) == 0) {
1556 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1557 return boost::shared_ptr<AudioRegion>();
1560 as = boost::dynamic_pointer_cast<AudioSource>(source);
1562 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1563 return boost::shared_ptr<AudioRegion>();
1565 master_sources.push_back (as);
1570 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1572 /* a final detail: this is the one and only place that we know how long missing files are */
1574 if (region->whole_file()) {
1575 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1576 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1578 sfp->set_length (region->length());
1583 if (!master_sources.empty()) {
1584 if (master_sources.size() == nchans) {
1585 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1587 region->set_master_sources (master_sources);
1595 catch (failed_constructor& err) {
1596 return boost::shared_ptr<AudioRegion>();
1600 boost::shared_ptr<MidiRegion>
1601 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1603 const XMLProperty* prop;
1604 boost::shared_ptr<Source> source;
1605 boost::shared_ptr<MidiSource> ms;
1607 uint32_t nchans = 1;
1609 if (node.name() != X_("Region")) {
1610 return boost::shared_ptr<MidiRegion>();
1613 if ((prop = node.property (X_("channels"))) != 0) {
1614 nchans = atoi (prop->value().c_str());
1617 if ((prop = node.property ("name")) == 0) {
1618 cerr << "no name for this region\n";
1622 // Multiple midi channels? that's just crazy talk
1623 assert(nchans == 1);
1625 if ((prop = node.property (X_("source-0"))) == 0) {
1626 if ((prop = node.property ("source")) == 0) {
1627 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1628 return boost::shared_ptr<MidiRegion>();
1632 PBD::ID s_id (prop->value());
1634 if ((source = source_by_id (s_id)) == 0) {
1635 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1636 return boost::shared_ptr<MidiRegion>();
1639 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1641 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1642 return boost::shared_ptr<MidiRegion>();
1645 sources.push_back (ms);
1648 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1649 /* a final detail: this is the one and only place that we know how long missing files are */
1651 if (region->whole_file()) {
1652 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1653 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1655 sfp->set_length (region->length());
1663 catch (failed_constructor& err) {
1664 return boost::shared_ptr<MidiRegion>();
1669 Session::get_sources_as_xml ()
1672 XMLNode* node = new XMLNode (X_("Sources"));
1673 Glib::Mutex::Lock lm (source_lock);
1675 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1676 node->add_child_nocopy (i->second->get_state());
1683 Session::path_from_region_name (DataType type, string name, string identifier)
1685 char buf[PATH_MAX+1];
1687 SessionDirectory sdir(get_best_session_directory_for_new_source());
1688 sys::path source_dir = ((type == DataType::AUDIO)
1689 ? sdir.sound_path() : sdir.midi_path());
1691 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1693 for (n = 0; n < 999999; ++n) {
1694 if (identifier.length()) {
1695 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1696 identifier.c_str(), n, ext.c_str());
1698 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1702 sys::path source_path = source_dir / buf;
1704 if (!sys::exists (source_path)) {
1705 return source_path.to_string();
1709 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1718 Session::load_sources (const XMLNode& node)
1721 XMLNodeConstIterator niter;
1722 boost::shared_ptr<Source> source;
1724 nlist = node.children();
1728 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1730 if ((source = XMLSourceFactory (**niter)) == 0) {
1731 error << _("Session: cannot create Source from XML description.") << endmsg;
1733 } catch (MissingSource& err) {
1734 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1735 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1742 boost::shared_ptr<Source>
1743 Session::XMLSourceFactory (const XMLNode& node)
1745 if (node.name() != "Source") {
1746 return boost::shared_ptr<Source>();
1750 /* note: do peak building in another thread when loading session state */
1751 return SourceFactory::create (*this, node, true);
1754 catch (failed_constructor& err) {
1755 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1756 return boost::shared_ptr<Source>();
1761 Session::save_template (string template_name)
1765 if (_state_of_the_state & CannotSave) {
1769 sys::path user_template_dir(user_template_directory());
1773 sys::create_directories (user_template_dir);
1775 catch(sys::filesystem_error& ex)
1777 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1778 user_template_dir.to_string(), ex.what()) << endmsg;
1782 tree.set_root (&get_template());
1784 sys::path template_file_path(user_template_dir);
1785 template_file_path /= template_name + template_suffix;
1787 if (sys::exists (template_file_path))
1789 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1790 template_file_path.to_string()) << endmsg;
1794 if (!tree.write (template_file_path.to_string())) {
1795 error << _("mix template not saved") << endmsg;
1803 Session::rename_template (string old_name, string new_name)
1805 sys::path old_path (user_template_directory());
1806 old_path /= old_name + template_suffix;
1808 sys::path new_path(user_template_directory());
1809 new_path /= new_name + template_suffix;
1811 if (sys::exists (new_path)) {
1812 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1813 new_path.to_string()) << endmsg;
1818 sys::rename (old_path, new_path);
1826 Session::delete_template (string name)
1828 sys::path path = user_template_directory();
1829 path /= name + template_suffix;
1840 Session::refresh_disk_space ()
1843 struct statfs statfsbuf;
1844 vector<space_and_path>::iterator i;
1845 Glib::Mutex::Lock lm (space_lock);
1848 /* get freespace on every FS that is part of the session path */
1850 _total_free_4k_blocks = 0;
1852 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1853 statfs ((*i).path.c_str(), &statfsbuf);
1855 scale = statfsbuf.f_bsize/4096.0;
1857 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1858 _total_free_4k_blocks += (*i).blocks;
1864 Session::get_best_session_directory_for_new_source ()
1866 vector<space_and_path>::iterator i;
1867 string result = _session_dir->root_path().to_string();
1869 /* handle common case without system calls */
1871 if (session_dirs.size() == 1) {
1875 /* OK, here's the algorithm we're following here:
1877 We want to select which directory to use for
1878 the next file source to be created. Ideally,
1879 we'd like to use a round-robin process so as to
1880 get maximum performance benefits from splitting
1881 the files across multiple disks.
1883 However, in situations without much diskspace, an
1884 RR approach may end up filling up a filesystem
1885 with new files while others still have space.
1886 Its therefore important to pay some attention to
1887 the freespace in the filesystem holding each
1888 directory as well. However, if we did that by
1889 itself, we'd keep creating new files in the file
1890 system with the most space until it was as full
1891 as all others, thus negating any performance
1892 benefits of this RAID-1 like approach.
1894 So, we use a user-configurable space threshold. If
1895 there are at least 2 filesystems with more than this
1896 much space available, we use RR selection between them.
1897 If not, then we pick the filesystem with the most space.
1899 This gets a good balance between the two
1903 refresh_disk_space ();
1905 int free_enough = 0;
1907 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1908 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1913 if (free_enough >= 2) {
1914 /* use RR selection process, ensuring that the one
1918 i = last_rr_session_dir;
1921 if (++i == session_dirs.end()) {
1922 i = session_dirs.begin();
1925 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1926 if (create_session_directory ((*i).path)) {
1928 last_rr_session_dir = i;
1933 } while (i != last_rr_session_dir);
1937 /* pick FS with the most freespace (and that
1938 seems to actually work ...)
1941 vector<space_and_path> sorted;
1942 space_and_path_ascending_cmp cmp;
1944 sorted = session_dirs;
1945 sort (sorted.begin(), sorted.end(), cmp);
1947 for (i = sorted.begin(); i != sorted.end(); ++i) {
1948 if (create_session_directory ((*i).path)) {
1950 last_rr_session_dir = i;
1960 Session::load_playlists (const XMLNode& node)
1963 XMLNodeConstIterator niter;
1964 boost::shared_ptr<Playlist> playlist;
1966 nlist = node.children();
1970 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1972 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1973 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1981 Session::load_unused_playlists (const XMLNode& node)
1984 XMLNodeConstIterator niter;
1985 boost::shared_ptr<Playlist> playlist;
1987 nlist = node.children();
1991 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1993 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1994 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1998 // now manually untrack it
2000 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
2006 boost::shared_ptr<Playlist>
2007 Session::XMLPlaylistFactory (const XMLNode& node)
2010 return PlaylistFactory::create (*this, node);
2013 catch (failed_constructor& err) {
2014 return boost::shared_ptr<Playlist>();
2019 Session::load_named_selections (const XMLNode& node)
2022 XMLNodeConstIterator niter;
2025 nlist = node.children();
2029 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2031 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2032 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2040 Session::XMLNamedSelectionFactory (const XMLNode& node)
2043 return new NamedSelection (*this, node);
2046 catch (failed_constructor& err) {
2052 Session::automation_dir () const
2054 return Glib::build_filename (_path, "automation");
2058 Session::analysis_dir () const
2060 return Glib::build_filename (_path, "analysis");
2064 Session::load_bundles (XMLNode const & node)
2066 XMLNodeList nlist = node.children();
2067 XMLNodeConstIterator niter;
2071 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2072 if ((*niter)->name() == "InputBundle") {
2073 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2074 } else if ((*niter)->name() == "OutputBundle") {
2075 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2077 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2086 Session::load_edit_groups (const XMLNode& node)
2088 return load_route_groups (node, true);
2092 Session::load_mix_groups (const XMLNode& node)
2094 return load_route_groups (node, false);
2098 Session::load_route_groups (const XMLNode& node, bool edit)
2100 XMLNodeList nlist = node.children();
2101 XMLNodeConstIterator niter;
2106 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2107 if ((*niter)->name() == "RouteGroup") {
2109 rg = add_edit_group ("");
2110 rg->set_state (**niter);
2112 rg = add_mix_group ("");
2113 rg->set_state (**niter);
2122 Session::auto_save()
2124 save_state (_current_snapshot_name);
2128 state_file_filter (const string &str, void *arg)
2130 return (str.length() > strlen(statefile_suffix) &&
2131 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2135 bool operator()(const string* a, const string* b) {
2141 remove_end(string* state)
2143 string statename(*state);
2145 string::size_type start,end;
2146 if ((start = statename.find_last_of ('/')) != string::npos) {
2147 statename = statename.substr (start+1);
2150 if ((end = statename.rfind(".ardour")) == string::npos) {
2151 end = statename.length();
2154 return new string(statename.substr (0, end));
2158 Session::possible_states (string path)
2160 PathScanner scanner;
2161 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2163 transform(states->begin(), states->end(), states->begin(), remove_end);
2166 sort (states->begin(), states->end(), cmp);
2172 Session::possible_states () const
2174 return possible_states(_path);
2178 Session::add_edit_group (string name)
2180 RouteGroup* rg = new RouteGroup (*this, name);
2181 edit_groups.push_back (rg);
2182 edit_group_added (rg); /* EMIT SIGNAL */
2188 Session::add_mix_group (string name)
2190 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2191 mix_groups.push_back (rg);
2192 mix_group_added (rg); /* EMIT SIGNAL */
2198 Session::remove_edit_group (RouteGroup& rg)
2200 list<RouteGroup*>::iterator i;
2202 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2203 (*i)->apply (&Route::drop_edit_group, this);
2204 edit_groups.erase (i);
2205 edit_group_removed (); /* EMIT SIGNAL */
2212 Session::remove_mix_group (RouteGroup& rg)
2214 list<RouteGroup*>::iterator i;
2216 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2217 (*i)->apply (&Route::drop_mix_group, this);
2218 mix_groups.erase (i);
2219 mix_group_removed (); /* EMIT SIGNAL */
2226 Session::mix_group_by_name (string name)
2228 list<RouteGroup *>::iterator i;
2230 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2231 if ((*i)->name() == name) {
2239 Session::edit_group_by_name (string name)
2241 list<RouteGroup *>::iterator i;
2243 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2244 if ((*i)->name() == name) {
2252 Session::begin_reversible_command(const string& name)
2254 UndoTransaction* trans = new UndoTransaction();
2255 trans->set_name(name);
2256 if (!_current_trans.empty()) {
2257 _current_trans.top()->add_command(trans);
2259 _current_trans.push(trans);
2263 Session::commit_reversible_command(Command *cmd)
2265 assert(!_current_trans.empty());
2269 _current_trans.top()->add_command(cmd);
2272 if (_current_trans.top()->empty()) {
2273 _current_trans.pop();
2277 gettimeofday(&now, 0);
2278 _current_trans.top()->set_timestamp(now);
2280 _history.add(_current_trans.top());
2281 _current_trans.pop();
2284 Session::GlobalRouteBooleanState
2285 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2287 GlobalRouteBooleanState s;
2288 boost::shared_ptr<RouteList> r = routes.reader ();
2290 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2291 if (!(*i)->is_hidden()) {
2292 RouteBooleanState v;
2295 Route* r = (*i).get();
2296 v.second = (r->*method)();
2305 Session::GlobalRouteMeterState
2306 Session::get_global_route_metering ()
2308 GlobalRouteMeterState s;
2309 boost::shared_ptr<RouteList> r = routes.reader ();
2311 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2312 if (!(*i)->is_hidden()) {
2316 v.second = (*i)->meter_point();
2326 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2328 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2330 boost::shared_ptr<Route> r = (i->first.lock());
2333 r->set_meter_point (i->second, arg);
2339 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2341 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2343 boost::shared_ptr<Route> r = (i->first.lock());
2346 Route* rp = r.get();
2347 (rp->*method) (i->second, arg);
2353 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2355 set_global_route_boolean (s, &Route::set_mute, src);
2359 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2361 set_global_route_boolean (s, &Route::set_solo, src);
2365 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2367 set_global_route_boolean (s, &Route::set_record_enable, src);
2371 accept_all_non_peak_files (const string& path, void *arg)
2373 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2377 accept_all_state_files (const string& path, void *arg)
2379 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2383 Session::find_all_sources (string path, set<string>& result)
2388 if (!tree.read (path)) {
2392 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2397 XMLNodeConstIterator niter;
2399 nlist = node->children();
2403 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2407 if ((prop = (*niter)->property (X_("name"))) == 0) {
2411 if (prop->value()[0] == '/') {
2412 /* external file, ignore */
2416 sys::path source_path = _session_dir->sound_path ();
2418 source_path /= prop->value ();
2420 result.insert (source_path.to_string ());
2427 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2429 PathScanner scanner;
2430 vector<string*>* state_files;
2432 string this_snapshot_path;
2438 if (ripped[ripped.length()-1] == '/') {
2439 ripped = ripped.substr (0, ripped.length() - 1);
2442 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2444 if (state_files == 0) {
2449 this_snapshot_path = _path;
2450 this_snapshot_path += _current_snapshot_name;
2451 this_snapshot_path += statefile_suffix;
2453 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2455 if (exclude_this_snapshot && **i == this_snapshot_path) {
2459 if (find_all_sources (**i, result) < 0) {
2467 struct RegionCounter {
2468 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2469 AudioSourceList::iterator iter;
2470 boost::shared_ptr<Region> region;
2473 RegionCounter() : count (0) {}
2477 Session::cleanup_sources (Session::cleanup_report& rep)
2479 // FIXME: needs adaptation to midi
2481 vector<boost::shared_ptr<Source> > dead_sources;
2482 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2483 PathScanner scanner;
2485 vector<space_and_path>::iterator i;
2486 vector<space_and_path>::iterator nexti;
2487 vector<string*>* soundfiles;
2488 vector<string> unused;
2489 set<string> all_sources;
2494 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2497 /* step 1: consider deleting all unused playlists */
2499 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2502 status = AskAboutPlaylistDeletion (*x);
2511 playlists_tbd.push_back (*x);
2515 /* leave it alone */
2520 /* now delete any that were marked for deletion */
2522 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2523 (*x)->drop_references ();
2526 playlists_tbd.clear ();
2528 /* step 2: find all un-used sources */
2533 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2535 SourceMap::iterator tmp;
2540 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2544 if (!i->second->used() && i->second->length(i->second->timeline_position()) > 0) {
2545 dead_sources.push_back (i->second);
2546 i->second->GoingAway();
2552 /* build a list of all the possible sound directories for the session */
2554 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2559 SessionDirectory sdir ((*i).path);
2560 sound_path += sdir.sound_path().to_string();
2562 if (nexti != session_dirs.end()) {
2569 /* now do the same thing for the files that ended up in the sounds dir(s)
2570 but are not referenced as sources in any snapshot.
2573 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2575 if (soundfiles == 0) {
2579 /* find all sources, but don't use this snapshot because the
2580 state file on disk still references sources we may have already
2584 find_all_sources_across_snapshots (all_sources, true);
2586 /* add our current source list
2589 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2590 boost::shared_ptr<FileSource> fs;
2592 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2593 all_sources.insert (fs->path());
2597 char tmppath1[PATH_MAX+1];
2598 char tmppath2[PATH_MAX+1];
2600 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2605 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2607 realpath(spath.c_str(), tmppath1);
2608 realpath((*i).c_str(), tmppath2);
2610 if (strcmp(tmppath1, tmppath2) == 0) {
2617 unused.push_back (spath);
2621 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2623 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2624 struct stat statbuf;
2626 rep.paths.push_back (*x);
2627 if (stat ((*x).c_str(), &statbuf) == 0) {
2628 rep.space += statbuf.st_size;
2633 /* don't move the file across filesystems, just
2634 stick it in the `dead_sound_dir_name' directory
2635 on whichever filesystem it was already on.
2638 if ((*x).find ("/sounds/") != string::npos) {
2640 /* old school, go up 1 level */
2642 newpath = Glib::path_get_dirname (*x); // "sounds"
2643 newpath = Glib::path_get_dirname (newpath); // "session-name"
2647 /* new school, go up 4 levels */
2649 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2650 newpath = Glib::path_get_dirname (newpath); // "session-name"
2651 newpath = Glib::path_get_dirname (newpath); // "interchange"
2652 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2656 newpath += dead_sound_dir_name;
2658 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2659 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2664 newpath += Glib::path_get_basename ((*x));
2666 if (access (newpath.c_str(), F_OK) == 0) {
2668 /* the new path already exists, try versioning */
2670 char buf[PATH_MAX+1];
2674 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2677 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2678 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2682 if (version == 999) {
2683 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2687 newpath = newpath_v;
2692 /* it doesn't exist, or we can't read it or something */
2696 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2697 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2698 (*x), newpath, strerror (errno))
2703 /* see if there an easy to find peakfile for this file, and remove it.
2706 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2707 peakpath += peakfile_suffix;
2709 if (access (peakpath.c_str(), W_OK) == 0) {
2710 if (::unlink (peakpath.c_str()) != 0) {
2711 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2712 peakpath, _path, strerror (errno))
2714 /* try to back out */
2715 rename (newpath.c_str(), _path.c_str());
2723 /* dump the history list */
2727 /* save state so we don't end up a session file
2728 referring to non-existent sources.
2734 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2740 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2742 // FIXME: needs adaptation for MIDI
2744 vector<space_and_path>::iterator i;
2745 string dead_sound_dir;
2746 struct dirent* dentry;
2747 struct stat statbuf;
2753 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2755 dead_sound_dir = (*i).path;
2756 dead_sound_dir += dead_sound_dir_name;
2758 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2762 while ((dentry = readdir (dead)) != 0) {
2764 /* avoid '.' and '..' */
2766 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2767 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2773 fullpath = dead_sound_dir;
2775 fullpath += dentry->d_name;
2777 if (stat (fullpath.c_str(), &statbuf)) {
2781 if (!S_ISREG (statbuf.st_mode)) {
2785 if (unlink (fullpath.c_str())) {
2786 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2787 fullpath, strerror (errno))
2791 rep.paths.push_back (dentry->d_name);
2792 rep.space += statbuf.st_size;
2803 Session::set_dirty ()
2805 bool was_dirty = dirty();
2807 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2811 DirtyChanged(); /* EMIT SIGNAL */
2817 Session::set_clean ()
2819 bool was_dirty = dirty();
2821 _state_of_the_state = Clean;
2825 DirtyChanged(); /* EMIT SIGNAL */
2830 Session::set_deletion_in_progress ()
2832 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2836 Session::clear_deletion_in_progress ()
2838 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2842 Session::add_controllable (boost::shared_ptr<Controllable> c)
2844 /* this adds a controllable to the list managed by the Session.
2845 this is a subset of those managed by the Controllable class
2846 itself, and represents the only ones whose state will be saved
2847 as part of the session.
2850 Glib::Mutex::Lock lm (controllables_lock);
2851 controllables.insert (c);
2854 struct null_deleter { void operator()(void const *) const {} };
2857 Session::remove_controllable (Controllable* c)
2859 if (_state_of_the_state | Deletion) {
2863 Glib::Mutex::Lock lm (controllables_lock);
2865 Controllables::iterator x = controllables.find(
2866 boost::shared_ptr<Controllable>(c, null_deleter()));
2868 if (x != controllables.end()) {
2869 controllables.erase (x);
2873 boost::shared_ptr<Controllable>
2874 Session::controllable_by_id (const PBD::ID& id)
2876 Glib::Mutex::Lock lm (controllables_lock);
2878 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2879 if ((*i)->id() == id) {
2884 return boost::shared_ptr<Controllable>();
2888 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2890 Stateful::add_instant_xml (node, _path);
2891 if (write_to_config) {
2892 Config->add_instant_xml (node);
2897 Session::instant_xml (const string& node_name)
2899 return Stateful::instant_xml (node_name, _path);
2903 Session::save_history (string snapshot_name)
2907 if (snapshot_name.empty()) {
2908 snapshot_name = _current_snapshot_name;
2911 const string history_filename = snapshot_name + history_suffix;
2912 const string backup_filename = history_filename + backup_suffix;
2913 const sys::path xml_path = _session_dir->root_path() / history_filename;
2914 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2916 if (sys::exists (xml_path)) {
2919 sys::rename (xml_path, backup_path);
2921 catch (const sys::filesystem_error& err)
2923 error << _("could not backup old history file, current history not saved") << endmsg;
2929 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2933 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2935 if (!tree.write (xml_path.to_string()))
2937 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2941 sys::remove (xml_path);
2942 sys::rename (backup_path, xml_path);
2944 catch (const sys::filesystem_error& err)
2946 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2947 backup_path.to_string(), err.what()) << endmsg;
2957 Session::restore_history (string snapshot_name)
2961 if (snapshot_name.empty()) {
2962 snapshot_name = _current_snapshot_name;
2965 const string xml_filename = snapshot_name + history_suffix;
2966 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2968 cerr << "Loading history from " << xml_path.to_string() << endmsg;
2970 if (!sys::exists (xml_path)) {
2971 info << string_compose (_("%1: no history file \"%2\" for this session."),
2972 _name, xml_path.to_string()) << endmsg;
2976 if (!tree.read (xml_path.to_string())) {
2977 error << string_compose (_("Could not understand session history file \"%1\""),
2978 xml_path.to_string()) << endmsg;
2985 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2988 UndoTransaction* ut = new UndoTransaction ();
2991 ut->set_name(t->property("name")->value());
2992 stringstream ss(t->property("tv-sec")->value());
2994 ss.str(t->property("tv-usec")->value());
2996 ut->set_timestamp(tv);
2998 for (XMLNodeConstIterator child_it = t->children().begin();
2999 child_it != t->children().end(); child_it++)
3001 XMLNode *n = *child_it;
3004 if (n->name() == "MementoCommand" ||
3005 n->name() == "MementoUndoCommand" ||
3006 n->name() == "MementoRedoCommand") {
3008 if ((c = memento_command_factory(n))) {
3012 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3014 if ((c = global_state_command_factory (*n))) {
3015 ut->add_command (c);
3018 } else if (n->name() == "DeltaCommand") {
3019 PBD::ID id(n->property("midi-source")->value());
3020 boost::shared_ptr<MidiSource> midi_source =
3021 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3023 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
3025 error << "FIXME: Failed to downcast MidiSource for DeltaCommand" << endmsg;
3028 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3039 Session::config_changed (const char* parameter_name)
3041 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3043 if (PARAM_IS ("seamless-loop")) {
3045 } else if (PARAM_IS ("rf-speed")) {
3047 } else if (PARAM_IS ("auto-loop")) {
3049 } else if (PARAM_IS ("auto-input")) {
3051 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3052 /* auto-input only makes a difference if we're rolling */
3054 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3056 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3057 if ((*i)->record_enabled ()) {
3058 (*i)->monitor_input (!Config->get_auto_input());
3063 } else if (PARAM_IS ("punch-in")) {
3067 if ((location = _locations.auto_punch_location()) != 0) {
3069 if (Config->get_punch_in ()) {
3070 replace_event (Event::PunchIn, location->start());
3072 remove_event (location->start(), Event::PunchIn);
3076 } else if (PARAM_IS ("punch-out")) {
3080 if ((location = _locations.auto_punch_location()) != 0) {
3082 if (Config->get_punch_out()) {
3083 replace_event (Event::PunchOut, location->end());
3085 clear_events (Event::PunchOut);
3089 } else if (PARAM_IS ("edit-mode")) {
3091 Glib::Mutex::Lock lm (playlist_lock);
3093 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3094 (*i)->set_edit_mode (Config->get_edit_mode ());
3097 } else if (PARAM_IS ("use-video-sync")) {
3099 waiting_for_sync_offset = Config->get_use_video_sync();
3101 } else if (PARAM_IS ("mmc-control")) {
3103 //poke_midi_thread ();
3105 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
3108 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3111 } else if (PARAM_IS ("mmc-send-id")) {
3114 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3117 } else if (PARAM_IS ("midi-control")) {
3119 //poke_midi_thread ();
3121 } else if (PARAM_IS ("raid-path")) {
3123 setup_raid_path (Config->get_raid_path());
3125 } else if (PARAM_IS ("smpte-format")) {
3129 } else if (PARAM_IS ("video-pullup")) {
3133 } else if (PARAM_IS ("seamless-loop")) {
3135 if (play_loop && transport_rolling()) {
3136 // to reset diskstreams etc
3137 request_play_loop (true);
3140 } else if (PARAM_IS ("rf-speed")) {
3142 cumulative_rf_motion = 0;
3145 } else if (PARAM_IS ("click-sound")) {
3147 setup_click_sounds (1);
3149 } else if (PARAM_IS ("click-emphasis-sound")) {
3151 setup_click_sounds (-1);
3153 } else if (PARAM_IS ("clicking")) {
3155 if (Config->get_clicking()) {
3156 if (_click_io && click_data) { // don't require emphasis data
3163 } else if (PARAM_IS ("send-mtc")) {
3165 /* only set the internal flag if we have
3169 if (_mtc_port != 0) {
3170 session_send_mtc = Config->get_send_mtc();
3171 if (session_send_mtc) {
3172 /* mark us ready to send */
3173 next_quarter_frame_to_send = 0;
3176 session_send_mtc = false;
3179 } else if (PARAM_IS ("send-mmc")) {
3181 /* only set the internal flag if we have
3185 if (_mmc_port != 0) {
3186 session_send_mmc = Config->get_send_mmc();
3189 session_send_mmc = false;
3192 } else if (PARAM_IS ("midi-feedback")) {
3194 /* only set the internal flag if we have
3198 if (_mtc_port != 0) {
3199 session_midi_feedback = Config->get_midi_feedback();
3202 } else if (PARAM_IS ("jack-time-master")) {
3204 engine().reset_timebase ();
3206 } else if (PARAM_IS ("native-file-header-format")) {
3208 if (!first_file_header_format_reset) {
3209 reset_native_file_format ();
3212 first_file_header_format_reset = false;
3214 } else if (PARAM_IS ("native-file-data-format")) {
3216 if (!first_file_data_format_reset) {
3217 reset_native_file_format ();
3220 first_file_data_format_reset = false;
3222 } else if (PARAM_IS ("slave-source")) {
3223 set_slave_source (Config->get_slave_source());
3224 } else if (PARAM_IS ("remote-model")) {
3225 set_remote_control_ids ();
3226 } else if (PARAM_IS ("denormal-model")) {
3228 } else if (PARAM_IS ("history-depth")) {
3229 set_history_depth (Config->get_history_depth());
3230 } else if (PARAM_IS ("sync-all-route-ordering")) {
3231 sync_order_keys ("session");
3232 } else if (PARAM_IS ("initial-program-change")) {
3234 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3237 buf[0] = MIDI::program; // channel zero by default
3238 buf[1] = (Config->get_initial_program_change() & 0x7f);
3240 _mmc_port->midimsg (buf, sizeof (buf), 0);
3242 } else if (PARAM_IS ("initial-program-change")) {
3244 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3245 MIDI::byte* buf = new MIDI::byte[2];
3247 buf[0] = MIDI::program; // channel zero by default
3248 buf[1] = (Config->get_initial_program_change() & 0x7f);
3249 // deliver_midi (_mmc_port, buf, 2);
3251 } else if (PARAM_IS ("solo-mute-override")) {
3252 catch_up_on_solo_mute_override ();
3262 Session::set_history_depth (uint32_t d)
3264 _history.set_depth (d);