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;
209 first_file_data_format_reset = true;
210 first_file_header_format_reset = true;
211 butler_thread = (pthread_t) 0;
212 //midi_thread = (pthread_t) 0;
214 AudioDiskstream::allocate_working_buffers();
216 /* default short fade = 15ms */
218 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
219 SndFileSource::setup_standard_crossfades (frame_rate());
221 last_mmc_step.tv_sec = 0;
222 last_mmc_step.tv_usec = 0;
225 /* click sounds are unset by default, which causes us to internal
226 waveforms for clicks.
230 click_emphasis_length = 0;
233 process_function = &Session::process_with_events;
235 if (Config->get_use_video_sync()) {
236 waiting_for_sync_offset = true;
238 waiting_for_sync_offset = false;
243 _smpte_offset_negative = true;
244 last_smpte_valid = false;
248 last_rr_session_dir = session_dirs.begin();
249 refresh_disk_space ();
251 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
255 average_slave_delta = 1800; // !!! why 1800 ????
256 have_first_delta_accumulator = false;
257 delta_accumulator_cnt = 0;
258 slave_state = Stopped;
260 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
262 /* These are all static "per-class" signals */
264 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
265 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
266 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
267 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
268 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
269 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
271 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
273 IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
275 /* stop IO objects from doing stuff until we're ready for them */
277 IO::disable_panners ();
278 IO::disable_ports ();
279 IO::disable_connecting ();
283 Session::second_stage_init (bool new_session)
285 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
288 if (load_state (_current_snapshot_name)) {
291 remove_empty_sounds ();
294 if (start_butler_thread()) {
298 if (start_midi_thread ()) {
302 // set_state() will call setup_raid_path(), but if it's a new session we need
303 // to call setup_raid_path() here.
306 if (set_state (*state_tree->root())) {
310 setup_raid_path(_path);
313 /* we can't save till after ::when_engine_running() is called,
314 because otherwise we save state with no connections made.
315 therefore, we reset _state_of_the_state because ::set_state()
316 will have cleared it.
318 we also have to include Loading so that any events that get
319 generated between here and the end of ::when_engine_running()
320 will be processed directly rather than queued.
323 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
326 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
327 _locations.added.connect (mem_fun (this, &Session::locations_added));
328 setup_click_sounds (0);
329 setup_midi_control ();
331 /* Pay attention ... */
333 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
334 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
337 when_engine_running();
340 /* handle this one in a different way than all others, so that its clear what happened */
342 catch (AudioEngine::PortRegistrationFailure& err) {
343 error << _("Unable to create all required ports")
352 BootMessage (_("Reset Remote Controls"));
354 send_full_time_code (0);
355 _engine.transport_locate (0);
356 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
357 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
359 MidiClockTicker::instance().set_session(*this);
360 MIDI::Name::MidiPatchManager::instance().set_session(*this);
362 /* initial program change will be delivered later; see ::config_changed() */
364 BootMessage (_("Reset Control Protocols"));
366 ControlProtocolManager::instance().set_session (*this);
369 _end_location_is_free = true;
371 _end_location_is_free = false;
374 _state_of_the_state = Clean;
376 DirtyChanged (); /* EMIT SIGNAL */
378 if (state_was_pending) {
379 save_state (_current_snapshot_name);
380 remove_pending_capture_state ();
381 state_was_pending = false;
384 BootMessage (_("Session loading complete"));
390 Session::raid_path () const
392 SearchPath raid_search_path;
394 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
395 raid_search_path += sys::path((*i).path);
398 return raid_search_path.to_string ();
402 Session::setup_raid_path (string path)
411 session_dirs.clear ();
413 SearchPath search_path(path);
414 SearchPath sound_search_path;
415 SearchPath midi_search_path;
418 SearchPath::const_iterator i = search_path.begin();
419 i != search_path.end();
423 sp.path = (*i).to_string ();
424 sp.blocks = 0; // not needed
425 session_dirs.push_back (sp);
427 SessionDirectory sdir(sp.path);
429 sound_search_path += sdir.sound_path ();
430 midi_search_path += sdir.midi_path ();
433 // set the AudioFileSource and SMFSource search path
435 AudioFileSource::set_search_path (sound_search_path.to_string ());
436 SMFSource::set_search_path (midi_search_path.to_string ());
439 // reset the round-robin soundfile path thingie
441 last_rr_session_dir = session_dirs.begin();
445 Session::ensure_subdirs ()
449 dir = session_directory().peak_path().to_string();
451 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
452 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
456 dir = session_directory().sound_path().to_string();
458 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
459 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
463 dir = session_directory().midi_path().to_string();
465 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
466 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
470 dir = session_directory().dead_sound_path().to_string();
472 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
473 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
477 dir = session_directory().export_path().to_string();
479 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
480 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
484 dir = analysis_dir ();
486 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
487 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
495 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
498 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
499 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
503 if (ensure_subdirs ()) {
507 /* check new_session so we don't overwrite an existing one */
509 if (!mix_template.empty()) {
510 std::string in_path = mix_template;
512 ifstream in(in_path.c_str());
515 string out_path = _path;
517 out_path += statefile_suffix;
519 ofstream out(out_path.c_str());
524 // okay, session is set up. Treat like normal saved
525 // session from now on.
531 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
537 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
544 /* Instantiate metadata */
546 _metadata = new SessionMetadata ();
548 /* set initial start + end point */
550 start_location->set_end (0);
551 _locations.add (start_location);
553 end_location->set_end (initial_length);
554 _locations.add (end_location);
556 _state_of_the_state = Clean;
565 Session::load_diskstreams (const XMLNode& node)
568 XMLNodeConstIterator citer;
570 clist = node.children();
572 for (citer = clist.begin(); citer != clist.end(); ++citer) {
575 /* diskstreams added automatically by DiskstreamCreated handler */
576 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
577 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
578 add_diskstream (dstream);
579 } else if ((*citer)->name() == "MidiDiskstream") {
580 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
581 add_diskstream (dstream);
583 error << _("Session: unknown diskstream type in XML") << endmsg;
587 catch (failed_constructor& err) {
588 error << _("Session: could not load diskstream via XML state") << endmsg;
597 Session::maybe_write_autosave()
599 if (dirty() && record_status() != Recording) {
600 save_state("", true);
605 Session::remove_pending_capture_state ()
607 sys::path pending_state_file_path(_session_dir->root_path());
609 pending_state_file_path /= _current_snapshot_name + pending_suffix;
613 sys::remove (pending_state_file_path);
615 catch(sys::filesystem_error& ex)
617 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
618 pending_state_file_path.to_string(), ex.what()) << endmsg;
622 /** Rename a state file.
623 * @param snapshot_name Snapshot name.
626 Session::rename_state (string old_name, string new_name)
628 if (old_name == _current_snapshot_name || old_name == _name) {
629 /* refuse to rename the current snapshot or the "main" one */
633 const string old_xml_filename = old_name + statefile_suffix;
634 const string new_xml_filename = new_name + statefile_suffix;
636 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
637 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
641 sys::rename (old_xml_path, new_xml_path);
643 catch (const sys::filesystem_error& err)
645 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
646 old_name, new_name, err.what()) << endmsg;
650 /** Remove a state file.
651 * @param snapshot_name Snapshot name.
654 Session::remove_state (string snapshot_name)
656 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
657 // refuse to remove the current snapshot or the "main" one
661 sys::path xml_path(_session_dir->root_path());
663 xml_path /= snapshot_name + statefile_suffix;
665 if (!create_backup_file (xml_path)) {
666 // don't remove it if a backup can't be made
667 // create_backup_file will log the error.
672 sys::remove (xml_path);
676 Session::save_state (string snapshot_name, bool pending)
679 sys::path xml_path(_session_dir->root_path());
681 if (_state_of_the_state & CannotSave) {
685 if (!_engine.connected ()) {
686 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
691 /* tell sources we're saving first, in case they write out to a new file
692 * which should be saved with the state rather than the old one */
693 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
694 i->second->session_saved();
696 tree.set_root (&get_state());
698 if (snapshot_name.empty()) {
699 snapshot_name = _current_snapshot_name;
704 /* proper save: use statefile_suffix (.ardour in English) */
706 xml_path /= snapshot_name + statefile_suffix;
708 /* make a backup copy of the old file */
710 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
711 // create_backup_file will log the error
717 /* pending save: use pending_suffix (.pending in English) */
718 xml_path /= snapshot_name + pending_suffix;
721 sys::path tmp_path(_session_dir->root_path());
723 tmp_path /= snapshot_name + temp_suffix;
725 // cerr << "actually writing state to " << xml_path.to_string() << endl;
727 if (!tree.write (tmp_path.to_string())) {
728 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
729 sys::remove (tmp_path);
734 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
735 error << string_compose (_("could not rename temporary session file %1 to %2"),
736 tmp_path.to_string(), xml_path.to_string()) << endmsg;
737 sys::remove (tmp_path);
744 save_history (snapshot_name);
746 bool was_dirty = dirty();
748 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
751 DirtyChanged (); /* EMIT SIGNAL */
754 StateSaved (snapshot_name); /* EMIT SIGNAL */
761 Session::restore_state (string snapshot_name)
763 if (load_state (snapshot_name) == 0) {
764 set_state (*state_tree->root());
771 Session::load_state (string snapshot_name)
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 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
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);