2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #define __STDC_FORMAT_MACROS 1
28 #include <sigc++/bind.h>
30 #include <cstdio> /* snprintf(3) ... grrr */
45 #include <sys/param.h>
46 #include <sys/mount.h>
50 #include <glibmm/thread.h>
52 #include <midi++/mmc.h>
53 #include <midi++/port.h>
55 #include <pbd/error.h>
56 #include <pbd/pathscanner.h>
57 #include <pbd/pthread_utils.h>
58 #include <pbd/search_path.h>
59 #include <pbd/stacktrace.h>
61 #include <ardour/audioengine.h>
62 #include <ardour/configuration.h>
63 #include <ardour/session.h>
64 #include <ardour/session_directory.h>
65 #include <ardour/session_utils.h>
66 #include <ardour/session_state_utils.h>
67 #include <ardour/session_metadata.h>
68 #include <ardour/buffer.h>
69 #include <ardour/audio_diskstream.h>
70 #include <ardour/midi_diskstream.h>
71 #include <ardour/utils.h>
72 #include <ardour/audioplaylist.h>
73 #include <ardour/midi_playlist.h>
74 #include <ardour/smf_source.h>
75 #include <ardour/audiofilesource.h>
76 #include <ardour/silentfilesource.h>
77 #include <ardour/sndfilesource.h>
78 #include <ardour/midi_source.h>
79 #include <ardour/sndfile_helpers.h>
80 #include <ardour/auditioner.h>
81 #include <ardour/io_processor.h>
82 #include <ardour/send.h>
83 #include <ardour/processor.h>
84 #include <ardour/bundle.h>
85 #include <ardour/slave.h>
86 #include <ardour/tempo.h>
87 #include <ardour/audio_track.h>
88 #include <ardour/midi_track.h>
89 #include <ardour/midi_patch_manager.h>
90 #include <ardour/cycle_timer.h>
91 #include <ardour/utils.h>
92 #include <ardour/named_selection.h>
93 #include <ardour/version.h>
94 #include <ardour/location.h>
95 #include <ardour/audioregion.h>
96 #include <ardour/midi_region.h>
97 #include <ardour/crossfade.h>
98 #include <ardour/control_protocol_manager.h>
99 #include <ardour/region_factory.h>
100 #include <ardour/source_factory.h>
101 #include <ardour/playlist_factory.h>
102 #include <ardour/filename_extensions.h>
103 #include <ardour/directory_names.h>
104 #include <ardour/template_utils.h>
105 #include <ardour/ticker.h>
107 #include <control_protocol/control_protocol.h>
113 using namespace ARDOUR;
117 Session::first_stage_init (string fullpath, string snapshot_name)
119 if (fullpath.length() == 0) {
121 throw failed_constructor();
124 char buf[PATH_MAX+1];
125 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
126 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
128 throw failed_constructor();
133 if (_path[_path.length()-1] != '/') {
137 /* these two are just provisional settings. set_state()
138 will likely override them.
141 _name = _current_snapshot_name = snapshot_name;
143 set_history_depth (Config->get_history_depth());
145 _current_frame_rate = _engine.frame_rate ();
146 _nominal_frame_rate = _current_frame_rate;
147 _base_frame_rate = _current_frame_rate;
149 _tempo_map = new TempoMap (_current_frame_rate);
150 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
154 g_atomic_int_set (&processing_prohibited, 0);
156 _transport_speed = 0;
157 _last_transport_speed = 0;
158 auto_play_legal = false;
159 transport_sub_state = 0;
160 _transport_frame = 0;
162 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
163 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
164 _end_location_is_free = true;
165 g_atomic_int_set (&_record_status, Disabled);
166 loop_changing = false;
169 _last_roll_location = 0;
170 _last_record_location = 0;
171 pending_locate_frame = 0;
172 pending_locate_roll = false;
173 pending_locate_flush = false;
174 audio_dstream_buffer_size = 0;
175 midi_dstream_buffer_size = 0;
176 state_was_pending = false;
178 outbound_mtc_smpte_frame = 0;
179 next_quarter_frame_to_send = -1;
180 current_block_size = 0;
181 solo_update_disabled = false;
182 currently_soloing = false;
183 _have_captured = false;
184 _worst_output_latency = 0;
185 _worst_input_latency = 0;
186 _worst_track_latency = 0;
187 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
190 session_send_mmc = false;
191 session_send_mtc = false;
192 post_transport_work = PostTransportWork (0);
193 g_atomic_int_set (&butler_should_do_transport_work, 0);
194 g_atomic_int_set (&_playback_load, 100);
195 g_atomic_int_set (&_capture_load, 100);
196 g_atomic_int_set (&_playback_load_min, 100);
197 g_atomic_int_set (&_capture_load_min, 100);
200 _exporting_realtime = false;
201 _gain_automation_buffer = 0;
202 _pan_automation_buffer = 0;
204 pending_abort = false;
205 destructive_index = 0;
207 first_file_data_format_reset = true;
208 first_file_header_format_reset = true;
209 butler_thread = (pthread_t) 0;
210 //midi_thread = (pthread_t) 0;
212 AudioDiskstream::allocate_working_buffers();
214 /* default short fade = 15ms */
216 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
217 SndFileSource::setup_standard_crossfades (frame_rate());
219 last_mmc_step.tv_sec = 0;
220 last_mmc_step.tv_usec = 0;
223 /* click sounds are unset by default, which causes us to internal
224 waveforms for clicks.
228 click_emphasis_length = 0;
231 process_function = &Session::process_with_events;
233 if (Config->get_use_video_sync()) {
234 waiting_for_sync_offset = true;
236 waiting_for_sync_offset = false;
241 _smpte_offset_negative = true;
242 last_smpte_valid = false;
246 last_rr_session_dir = session_dirs.begin();
247 refresh_disk_space ();
249 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
253 average_slave_delta = 1800; // !!! why 1800 ????
254 have_first_delta_accumulator = false;
255 delta_accumulator_cnt = 0;
256 slave_state = Stopped;
258 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
260 /* These are all static "per-class" signals */
262 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
263 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
264 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
265 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
266 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
267 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
269 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
271 IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
273 /* stop IO objects from doing stuff until we're ready for them */
275 IO::disable_panners ();
276 IO::disable_ports ();
277 IO::disable_connecting ();
281 Session::second_stage_init (bool new_session)
283 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
286 if (load_state (_current_snapshot_name)) {
289 remove_empty_sounds ();
292 if (start_butler_thread()) {
296 if (start_midi_thread ()) {
300 // set_state() will call setup_raid_path(), but if it's a new session we need
301 // to call setup_raid_path() here.
304 if (set_state (*state_tree->root())) {
308 setup_raid_path(_path);
311 /* we can't save till after ::when_engine_running() is called,
312 because otherwise we save state with no connections made.
313 therefore, we reset _state_of_the_state because ::set_state()
314 will have cleared it.
316 we also have to include Loading so that any events that get
317 generated between here and the end of ::when_engine_running()
318 will be processed directly rather than queued.
321 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
324 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
325 _locations.added.connect (mem_fun (this, &Session::locations_added));
326 setup_click_sounds (0);
327 setup_midi_control ();
329 /* Pay attention ... */
331 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
332 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
335 when_engine_running();
338 /* handle this one in a different way than all others, so that its clear what happened */
340 catch (AudioEngine::PortRegistrationFailure& err) {
341 error << _("Unable to create all required ports")
350 BootMessage (_("Reset Remote Controls"));
352 send_full_time_code (0);
353 _engine.transport_locate (0);
354 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
355 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
357 MidiClockTicker::instance().set_session(*this);
358 MIDI::Name::MidiPatchManager::instance().set_session(*this);
360 /* initial program change will be delivered later; see ::config_changed() */
362 BootMessage (_("Reset Control Protocols"));
364 ControlProtocolManager::instance().set_session (*this);
367 _end_location_is_free = true;
369 _end_location_is_free = false;
372 _state_of_the_state = Clean;
374 DirtyChanged (); /* EMIT SIGNAL */
376 if (state_was_pending) {
377 save_state (_current_snapshot_name);
378 remove_pending_capture_state ();
379 state_was_pending = false;
382 BootMessage (_("Session loading complete"));
388 Session::raid_path () const
390 SearchPath raid_search_path;
392 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
393 raid_search_path += sys::path((*i).path);
396 return raid_search_path.to_string ();
400 Session::setup_raid_path (string path)
409 session_dirs.clear ();
411 SearchPath search_path(path);
412 SearchPath sound_search_path;
413 SearchPath midi_search_path;
416 SearchPath::const_iterator i = search_path.begin();
417 i != search_path.end();
421 sp.path = (*i).to_string ();
422 sp.blocks = 0; // not needed
423 session_dirs.push_back (sp);
425 SessionDirectory sdir(sp.path);
427 sound_search_path += sdir.sound_path ();
428 midi_search_path += sdir.midi_path ();
431 // set the AudioFileSource and SMFSource search path
433 AudioFileSource::set_search_path (sound_search_path.to_string ());
434 SMFSource::set_search_path (midi_search_path.to_string ());
437 // reset the round-robin soundfile path thingie
439 last_rr_session_dir = session_dirs.begin();
443 Session::ensure_subdirs ()
447 dir = session_directory().peak_path().to_string();
449 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
450 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
454 dir = session_directory().sound_path().to_string();
456 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
457 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
461 dir = session_directory().midi_path().to_string();
463 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
464 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
468 dir = session_directory().dead_sound_path().to_string();
470 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
471 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
475 dir = session_directory().export_path().to_string();
477 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
478 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
482 dir = analysis_dir ();
484 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
485 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
493 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
496 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
497 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
501 if (ensure_subdirs ()) {
505 /* check new_session so we don't overwrite an existing one */
507 if (!mix_template.empty()) {
508 std::string in_path = mix_template;
510 ifstream in(in_path.c_str());
513 string out_path = _path;
515 out_path += statefile_suffix;
517 ofstream out(out_path.c_str());
522 // okay, session is set up. Treat like normal saved
523 // session from now on.
529 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
535 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
542 /* Instantiate metadata */
544 _metadata = new SessionMetadata ();
546 /* set initial start + end point */
548 start_location->set_end (0);
549 _locations.add (start_location);
551 end_location->set_end (initial_length);
552 _locations.add (end_location);
554 _state_of_the_state = Clean;
563 Session::load_diskstreams (const XMLNode& node)
566 XMLNodeConstIterator citer;
568 clist = node.children();
570 for (citer = clist.begin(); citer != clist.end(); ++citer) {
573 /* diskstreams added automatically by DiskstreamCreated handler */
574 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
575 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
576 add_diskstream (dstream);
577 } else if ((*citer)->name() == "MidiDiskstream") {
578 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
579 add_diskstream (dstream);
581 error << _("Session: unknown diskstream type in XML") << endmsg;
585 catch (failed_constructor& err) {
586 error << _("Session: could not load diskstream via XML state") << endmsg;
595 Session::maybe_write_autosave()
597 if (dirty() && record_status() != Recording) {
598 save_state("", true);
603 Session::remove_pending_capture_state ()
605 sys::path pending_state_file_path(_session_dir->root_path());
607 pending_state_file_path /= _current_snapshot_name + pending_suffix;
611 sys::remove (pending_state_file_path);
613 catch(sys::filesystem_error& ex)
615 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
616 pending_state_file_path.to_string(), ex.what()) << endmsg;
620 /** Rename a state file.
621 * @param snapshot_name Snapshot name.
624 Session::rename_state (string old_name, string new_name)
626 if (old_name == _current_snapshot_name || old_name == _name) {
627 /* refuse to rename the current snapshot or the "main" one */
631 const string old_xml_filename = old_name + statefile_suffix;
632 const string new_xml_filename = new_name + statefile_suffix;
634 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
635 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
639 sys::rename (old_xml_path, new_xml_path);
641 catch (const sys::filesystem_error& err)
643 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
644 old_name, new_name, err.what()) << endmsg;
648 /** Remove a state file.
649 * @param snapshot_name Snapshot name.
652 Session::remove_state (string snapshot_name)
654 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
655 // refuse to remove the current snapshot or the "main" one
659 sys::path xml_path(_session_dir->root_path());
661 xml_path /= snapshot_name + statefile_suffix;
663 if (!create_backup_file (xml_path)) {
664 // don't remove it if a backup can't be made
665 // create_backup_file will log the error.
670 sys::remove (xml_path);
674 Session::save_state (string snapshot_name, bool pending)
677 sys::path xml_path(_session_dir->root_path());
679 if (_state_of_the_state & CannotSave) {
683 if (!_engine.connected ()) {
684 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
689 /* tell sources we're saving first, in case they write out to a new file
690 * which should be saved with the state rather than the old one */
691 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
692 i->second->session_saved();
694 tree.set_root (&get_state());
696 if (snapshot_name.empty()) {
697 snapshot_name = _current_snapshot_name;
702 /* proper save: use statefile_suffix (.ardour in English) */
704 xml_path /= snapshot_name + statefile_suffix;
706 /* make a backup copy of the old file */
708 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
709 // create_backup_file will log the error
715 /* pending save: use pending_suffix (.pending in English) */
716 xml_path /= snapshot_name + pending_suffix;
719 sys::path tmp_path(_session_dir->root_path());
721 tmp_path /= snapshot_name + temp_suffix;
723 // cerr << "actually writing state to " << xml_path.to_string() << endl;
725 if (!tree.write (tmp_path.to_string())) {
726 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
727 sys::remove (tmp_path);
732 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
733 error << string_compose (_("could not rename temporary session file %1 to %2"),
734 tmp_path.to_string(), xml_path.to_string()) << endmsg;
735 sys::remove (tmp_path);
742 save_history (snapshot_name);
744 bool was_dirty = dirty();
746 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
749 DirtyChanged (); /* EMIT SIGNAL */
752 StateSaved (snapshot_name); /* EMIT SIGNAL */
759 Session::restore_state (string snapshot_name)
761 if (load_state (snapshot_name) == 0) {
762 set_state (*state_tree->root());
769 Session::load_state (string snapshot_name)
774 state_was_pending = false;
776 /* check for leftover pending state from a crashed capture attempt */
778 sys::path xmlpath(_session_dir->root_path());
779 xmlpath /= snapshot_name + pending_suffix;
781 if (sys::exists (xmlpath)) {
783 /* there is pending state from a crashed capture attempt */
785 if (AskAboutPendingState()) {
786 state_was_pending = true;
790 if (!state_was_pending) {
791 xmlpath = _session_dir->root_path();
792 xmlpath /= snapshot_name + statefile_suffix;
795 if (!sys::exists (xmlpath)) {
796 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
800 state_tree = new XMLTree;
804 if (!state_tree->read (xmlpath.to_string())) {
805 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
811 XMLNode& root (*state_tree->root());
813 if (root.name() != X_("Session")) {
814 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
820 const XMLProperty* prop;
821 bool is_old = false; // session is _very_ old (pre-2.0)
823 if ((prop = root.property ("version")) == 0) {
824 /* no version implies very old version of Ardour */
828 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
829 if (major_version < 2) {
836 sys::path backup_path(_session_dir->root_path());
838 backup_path /= snapshot_name + "-1" + statefile_suffix;
840 // only create a backup once
841 if (sys::exists (backup_path)) {
845 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
846 xmlpath.to_string(), backup_path.to_string())
851 sys::copy_file (xmlpath, backup_path);
853 catch(sys::filesystem_error& ex)
855 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
856 xmlpath.to_string(), ex.what())
866 Session::load_options (const XMLNode& node)
870 LocaleGuard lg (X_("POSIX"));
872 Config->set_variables (node, ConfigVariableBase::Session);
874 /* now reset MIDI ports because the session can have its own
880 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
881 if ((prop = child->property ("val")) != 0) {
882 _end_location_is_free = (prop->value() == "yes");
890 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
892 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
893 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
895 return owner & modified_by_session_or_user;
899 Session::get_options () const
902 LocaleGuard lg (X_("POSIX"));
904 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
906 child = option_root.add_child ("end-marker-is-free");
907 child->add_property ("val", _end_location_is_free ? "yes" : "no");
919 Session::get_template()
921 /* if we don't disable rec-enable, diskstreams
922 will believe they need to store their capture
923 sources in their state node.
926 disable_record (false);
932 Session::state(bool full_state)
934 XMLNode* node = new XMLNode("Session");
937 // store libardour version, just in case
939 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
940 node->add_property("version", string(buf));
942 /* store configuration settings */
946 node->add_property ("name", _name);
947 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
948 node->add_property ("sample-rate", buf);
950 if (session_dirs.size() > 1) {
954 vector<space_and_path>::iterator i = session_dirs.begin();
955 vector<space_and_path>::iterator next;
957 ++i; /* skip the first one */
961 while (i != session_dirs.end()) {
965 if (next != session_dirs.end()) {
975 child = node->add_child ("Path");
976 child->add_content (p);
980 /* save the ID counter */
982 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
983 node->add_property ("id-counter", buf);
985 /* various options */
987 node->add_child_nocopy (get_options());
989 node->add_child_nocopy (_metadata->get_state());
991 child = node->add_child ("Sources");
994 Glib::Mutex::Lock sl (source_lock);
996 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
998 /* Don't save information about AudioFileSources that are empty */
1000 boost::shared_ptr<AudioFileSource> fs;
1002 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
1004 /* Don't save sources that are empty, unless they're destructive (which are OK
1005 if they are empty, because we will re-use them every time.)
1008 if (!fs->destructive()) {
1009 if (fs->length() == 0) {
1015 child->add_child_nocopy (siter->second->get_state());
1019 child = node->add_child ("Regions");
1022 Glib::Mutex::Lock rl (region_lock);
1024 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
1026 /* only store regions not attached to playlists */
1028 if (i->second->playlist() == 0) {
1029 child->add_child_nocopy (i->second->state (true));
1034 child = node->add_child ("DiskStreams");
1037 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1038 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1039 if (!(*i)->hidden()) {
1040 child->add_child_nocopy ((*i)->get_state());
1046 node->add_child_nocopy (_locations.get_state());
1048 // for a template, just create a new Locations, populate it
1049 // with the default start and end, and get the state for that.
1051 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1052 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1055 end->set_end(compute_initial_length());
1057 node->add_child_nocopy (loc.get_state());
1060 child = node->add_child ("Bundles");
1062 Glib::Mutex::Lock lm (bundle_lock);
1063 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
1064 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1066 child->add_child_nocopy (b->get_state());
1071 child = node->add_child ("Routes");
1073 boost::shared_ptr<RouteList> r = routes.reader ();
1075 RoutePublicOrderSorter cmp;
1076 RouteList public_order (*r);
1077 public_order.sort (cmp);
1079 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1080 if (!(*i)->is_hidden()) {
1082 child->add_child_nocopy ((*i)->get_state());
1084 child->add_child_nocopy ((*i)->get_template());
1091 child = node->add_child ("EditGroups");
1092 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1093 child->add_child_nocopy ((*i)->get_state());
1096 child = node->add_child ("MixGroups");
1097 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1098 child->add_child_nocopy ((*i)->get_state());
1101 child = node->add_child ("Playlists");
1102 for (PlaylistList::iterator i = playlists.begin(); i != 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());
1114 child = node->add_child ("UnusedPlaylists");
1115 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1116 if (!(*i)->hidden()) {
1117 if (!(*i)->empty()) {
1119 child->add_child_nocopy ((*i)->get_state());
1121 child->add_child_nocopy ((*i)->get_template());
1129 child = node->add_child ("Click");
1130 child->add_child_nocopy (_click_io->state (full_state));
1134 child = node->add_child ("NamedSelections");
1135 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1137 child->add_child_nocopy ((*i)->get_state());
1142 node->add_child_nocopy (_tempo_map->get_state());
1144 node->add_child_nocopy (get_control_protocol_state());
1147 node->add_child_copy (*_extra_xml);
1154 Session::get_control_protocol_state ()
1156 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1157 return cpm.get_state();
1161 Session::set_state (const XMLNode& node)
1165 const XMLProperty* prop;
1168 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1170 if (node.name() != X_("Session")){
1171 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1175 if ((prop = node.property ("name")) != 0) {
1176 _name = prop->value ();
1179 if ((prop = node.property (X_("sample-rate"))) != 0) {
1181 _nominal_frame_rate = atoi (prop->value());
1183 if (_nominal_frame_rate != _current_frame_rate) {
1184 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1190 setup_raid_path(_session_dir->root_path().to_string());
1192 if ((prop = node.property (X_("id-counter"))) != 0) {
1194 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1195 ID::init_counter (x);
1197 /* old sessions used a timebased counter, so fake
1198 the startup ID counter based on a standard
1203 ID::init_counter (now);
1207 IO::disable_ports ();
1208 IO::disable_connecting ();
1210 /* Object loading order:
1215 MIDI Control // relies on data from Options/Config
1229 if ((child = find_named_node (node, "extra")) != 0) {
1230 _extra_xml = new XMLNode (*child);
1233 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1234 load_options (*child);
1235 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1236 load_options (*child);
1238 error << _("Session: XML state has no options section") << endmsg;
1241 if (use_config_midi_ports ()) {
1244 if ((child = find_named_node (node, "Metadata")) == 0) {
1245 warning << _("Session: XML state has no metadata section (2.0 session?)") << endmsg;
1246 } else if (_metadata->set_state (*child)) {
1250 if ((child = find_named_node (node, "Locations")) == 0) {
1251 error << _("Session: XML state has no locations section") << endmsg;
1253 } else if (_locations.set_state (*child)) {
1259 if ((location = _locations.auto_loop_location()) != 0) {
1260 set_auto_loop_location (location);
1263 if ((location = _locations.auto_punch_location()) != 0) {
1264 set_auto_punch_location (location);
1267 if ((location = _locations.end_location()) == 0) {
1268 _locations.add (end_location);
1270 delete end_location;
1271 end_location = location;
1274 if ((location = _locations.start_location()) == 0) {
1275 _locations.add (start_location);
1277 delete start_location;
1278 start_location = location;
1281 AudioFileSource::set_header_position_offset (start_location->start());
1283 if ((child = find_named_node (node, "Sources")) == 0) {
1284 error << _("Session: XML state has no sources section") << endmsg;
1286 } else if (load_sources (*child)) {
1290 if ((child = find_named_node (node, "Regions")) == 0) {
1291 error << _("Session: XML state has no Regions section") << endmsg;
1293 } else if (load_regions (*child)) {
1297 if ((child = find_named_node (node, "Playlists")) == 0) {
1298 error << _("Session: XML state has no playlists section") << endmsg;
1300 } else if (load_playlists (*child)) {
1304 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1306 } else if (load_unused_playlists (*child)) {
1310 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1311 if (load_named_selections (*child)) {
1316 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1317 error << _("Session: XML state has no diskstreams section") << endmsg;
1319 } else if (load_diskstreams (*child)) {
1323 if ((child = find_named_node (node, "Bundles")) == 0) {
1324 warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg;
1327 /* We can't load Bundles yet as they need to be able
1328 to convert from port names to Port objects, which can't happen until
1330 _bundle_xml_node = new XMLNode (*child);
1333 if ((child = find_named_node (node, "EditGroups")) == 0) {
1334 error << _("Session: XML state has no edit groups section") << endmsg;
1336 } else if (load_edit_groups (*child)) {
1340 if ((child = find_named_node (node, "MixGroups")) == 0) {
1341 error << _("Session: XML state has no mix groups section") << endmsg;
1343 } else if (load_mix_groups (*child)) {
1347 if ((child = find_named_node (node, "TempoMap")) == 0) {
1348 error << _("Session: XML state has no Tempo Map section") << endmsg;
1350 } else if (_tempo_map->set_state (*child)) {
1354 if ((child = find_named_node (node, "Routes")) == 0) {
1355 error << _("Session: XML state has no routes section") << endmsg;
1357 } else if (load_routes (*child)) {
1361 if ((child = find_named_node (node, "Click")) == 0) {
1362 warning << _("Session: XML state has no click section") << endmsg;
1363 } else if (_click_io) {
1364 _click_io->set_state (*child);
1367 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1368 ControlProtocolManager::instance().set_protocol_states (*child);
1371 /* here beginneth the second phase ... */
1373 StateReady (); /* EMIT SIGNAL */
1382 Session::load_routes (const XMLNode& node)
1385 XMLNodeConstIterator niter;
1386 RouteList new_routes;
1388 nlist = node.children();
1392 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1394 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1397 error << _("Session: cannot create Route from XML description.") << endmsg;
1401 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1403 new_routes.push_back (route);
1406 add_routes (new_routes, false);
1411 boost::shared_ptr<Route>
1412 Session::XMLRouteFactory (const XMLNode& node)
1414 if (node.name() != "Route") {
1415 return boost::shared_ptr<Route> ((Route*) 0);
1418 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1420 DataType type = DataType::AUDIO;
1421 const XMLProperty* prop = node.property("default-type");
1423 type = DataType(prop->value());
1425 assert(type != DataType::NIL);
1427 if (has_diskstream) {
1428 if (type == DataType::AUDIO) {
1429 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1432 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1436 boost::shared_ptr<Route> ret (new Route (*this, node));
1442 Session::load_regions (const XMLNode& node)
1445 XMLNodeConstIterator niter;
1446 boost::shared_ptr<Region> region;
1448 nlist = node.children();
1452 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1453 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1454 error << _("Session: cannot create Region from XML description.");
1455 const XMLProperty *name = (**niter).property("name");
1458 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1468 boost::shared_ptr<Region>
1469 Session::XMLRegionFactory (const XMLNode& node, bool full)
1471 const XMLProperty* type = node.property("type");
1475 if ( !type || type->value() == "audio" ) {
1477 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1479 } else if (type->value() == "midi") {
1481 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1485 } catch (failed_constructor& err) {
1486 return boost::shared_ptr<Region> ();
1489 return boost::shared_ptr<Region> ();
1492 boost::shared_ptr<AudioRegion>
1493 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1495 const XMLProperty* prop;
1496 boost::shared_ptr<Source> source;
1497 boost::shared_ptr<AudioSource> as;
1499 SourceList master_sources;
1500 uint32_t nchans = 1;
1503 if (node.name() != X_("Region")) {
1504 return boost::shared_ptr<AudioRegion>();
1507 if ((prop = node.property (X_("channels"))) != 0) {
1508 nchans = atoi (prop->value().c_str());
1511 if ((prop = node.property ("name")) == 0) {
1512 cerr << "no name for this region\n";
1516 if ((prop = node.property (X_("source-0"))) == 0) {
1517 if ((prop = node.property ("source")) == 0) {
1518 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1519 return boost::shared_ptr<AudioRegion>();
1523 PBD::ID s_id (prop->value());
1525 if ((source = source_by_id (s_id)) == 0) {
1526 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1527 return boost::shared_ptr<AudioRegion>();
1530 as = boost::dynamic_pointer_cast<AudioSource>(source);
1532 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1533 return boost::shared_ptr<AudioRegion>();
1536 sources.push_back (as);
1538 /* pickup other channels */
1540 for (uint32_t n=1; n < nchans; ++n) {
1541 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1542 if ((prop = node.property (buf)) != 0) {
1544 PBD::ID id2 (prop->value());
1546 if ((source = source_by_id (id2)) == 0) {
1547 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1548 return boost::shared_ptr<AudioRegion>();
1551 as = boost::dynamic_pointer_cast<AudioSource>(source);
1553 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1554 return boost::shared_ptr<AudioRegion>();
1556 sources.push_back (as);
1560 for (uint32_t n=1; n < nchans; ++n) {
1561 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1562 if ((prop = node.property (buf)) != 0) {
1564 PBD::ID id2 (prop->value());
1566 if ((source = source_by_id (id2)) == 0) {
1567 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1568 return boost::shared_ptr<AudioRegion>();
1571 as = boost::dynamic_pointer_cast<AudioSource>(source);
1573 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1574 return boost::shared_ptr<AudioRegion>();
1576 master_sources.push_back (as);
1581 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1583 /* a final detail: this is the one and only place that we know how long missing files are */
1585 if (region->whole_file()) {
1586 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1587 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1589 sfp->set_length (region->length());
1594 if (!master_sources.empty()) {
1595 if (master_sources.size() == nchans) {
1596 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1598 region->set_master_sources (master_sources);
1606 catch (failed_constructor& err) {
1607 return boost::shared_ptr<AudioRegion>();
1611 boost::shared_ptr<MidiRegion>
1612 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1614 const XMLProperty* prop;
1615 boost::shared_ptr<Source> source;
1616 boost::shared_ptr<MidiSource> ms;
1618 uint32_t nchans = 1;
1620 if (node.name() != X_("Region")) {
1621 return boost::shared_ptr<MidiRegion>();
1624 if ((prop = node.property (X_("channels"))) != 0) {
1625 nchans = atoi (prop->value().c_str());
1628 if ((prop = node.property ("name")) == 0) {
1629 cerr << "no name for this region\n";
1633 // Multiple midi channels? that's just crazy talk
1634 assert(nchans == 1);
1636 if ((prop = node.property (X_("source-0"))) == 0) {
1637 if ((prop = node.property ("source")) == 0) {
1638 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1639 return boost::shared_ptr<MidiRegion>();
1643 PBD::ID s_id (prop->value());
1645 if ((source = source_by_id (s_id)) == 0) {
1646 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1647 return boost::shared_ptr<MidiRegion>();
1650 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1652 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1653 return boost::shared_ptr<MidiRegion>();
1656 sources.push_back (ms);
1659 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1660 /* a final detail: this is the one and only place that we know how long missing files are */
1662 if (region->whole_file()) {
1663 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1664 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1666 sfp->set_length (region->length());
1674 catch (failed_constructor& err) {
1675 return boost::shared_ptr<MidiRegion>();
1680 Session::get_sources_as_xml ()
1683 XMLNode* node = new XMLNode (X_("Sources"));
1684 Glib::Mutex::Lock lm (source_lock);
1686 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1687 node->add_child_nocopy (i->second->get_state());
1694 Session::path_from_region_name (DataType type, string name, string identifier)
1696 char buf[PATH_MAX+1];
1698 SessionDirectory sdir(get_best_session_directory_for_new_source());
1699 sys::path source_dir = ((type == DataType::AUDIO)
1700 ? sdir.sound_path() : sdir.midi_path());
1702 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1704 for (n = 0; n < 999999; ++n) {
1705 if (identifier.length()) {
1706 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1707 identifier.c_str(), n, ext.c_str());
1709 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1713 sys::path source_path = source_dir / buf;
1715 if (!sys::exists (source_path)) {
1716 return source_path.to_string();
1720 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1729 Session::load_sources (const XMLNode& node)
1732 XMLNodeConstIterator niter;
1733 boost::shared_ptr<Source> source;
1735 nlist = node.children();
1739 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1742 if ((source = XMLSourceFactory (**niter)) == 0) {
1743 error << _("Session: cannot create Source from XML description.") << endmsg;
1747 catch (non_existent_source& err) {
1748 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1749 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1756 boost::shared_ptr<Source>
1757 Session::XMLSourceFactory (const XMLNode& node)
1759 if (node.name() != "Source") {
1760 return boost::shared_ptr<Source>();
1764 /* note: do peak building in another thread when loading session state */
1765 return SourceFactory::create (*this, node, true);
1768 catch (failed_constructor& err) {
1769 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1770 return boost::shared_ptr<Source>();
1775 Session::save_template (string template_name)
1779 if (_state_of_the_state & CannotSave) {
1783 sys::path user_template_dir(user_template_directory());
1787 sys::create_directories (user_template_dir);
1789 catch(sys::filesystem_error& ex)
1791 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1792 user_template_dir.to_string(), ex.what()) << endmsg;
1796 tree.set_root (&get_template());
1798 sys::path template_file_path(user_template_dir);
1799 template_file_path /= template_name + template_suffix;
1801 if (sys::exists (template_file_path))
1803 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1804 template_file_path.to_string()) << endmsg;
1808 if (!tree.write (template_file_path.to_string())) {
1809 error << _("mix template not saved") << endmsg;
1817 Session::rename_template (string old_name, string new_name)
1819 sys::path old_path (user_template_directory());
1820 old_path /= old_name + template_suffix;
1822 sys::path new_path(user_template_directory());
1823 new_path /= new_name + template_suffix;
1825 if (sys::exists (new_path)) {
1826 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1827 new_path.to_string()) << endmsg;
1832 sys::rename (old_path, new_path);
1840 Session::delete_template (string name)
1842 sys::path path = user_template_directory();
1843 path /= name + template_suffix;
1854 Session::refresh_disk_space ()
1857 struct statfs statfsbuf;
1858 vector<space_and_path>::iterator i;
1859 Glib::Mutex::Lock lm (space_lock);
1862 /* get freespace on every FS that is part of the session path */
1864 _total_free_4k_blocks = 0;
1866 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1867 statfs ((*i).path.c_str(), &statfsbuf);
1869 scale = statfsbuf.f_bsize/4096.0;
1871 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1872 _total_free_4k_blocks += (*i).blocks;
1878 Session::get_best_session_directory_for_new_source ()
1880 vector<space_and_path>::iterator i;
1881 string result = _session_dir->root_path().to_string();
1883 /* handle common case without system calls */
1885 if (session_dirs.size() == 1) {
1889 /* OK, here's the algorithm we're following here:
1891 We want to select which directory to use for
1892 the next file source to be created. Ideally,
1893 we'd like to use a round-robin process so as to
1894 get maximum performance benefits from splitting
1895 the files across multiple disks.
1897 However, in situations without much diskspace, an
1898 RR approach may end up filling up a filesystem
1899 with new files while others still have space.
1900 Its therefore important to pay some attention to
1901 the freespace in the filesystem holding each
1902 directory as well. However, if we did that by
1903 itself, we'd keep creating new files in the file
1904 system with the most space until it was as full
1905 as all others, thus negating any performance
1906 benefits of this RAID-1 like approach.
1908 So, we use a user-configurable space threshold. If
1909 there are at least 2 filesystems with more than this
1910 much space available, we use RR selection between them.
1911 If not, then we pick the filesystem with the most space.
1913 This gets a good balance between the two
1917 refresh_disk_space ();
1919 int free_enough = 0;
1921 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1922 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1927 if (free_enough >= 2) {
1928 /* use RR selection process, ensuring that the one
1932 i = last_rr_session_dir;
1935 if (++i == session_dirs.end()) {
1936 i = session_dirs.begin();
1939 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1940 if (create_session_directory ((*i).path)) {
1942 last_rr_session_dir = i;
1947 } while (i != last_rr_session_dir);
1951 /* pick FS with the most freespace (and that
1952 seems to actually work ...)
1955 vector<space_and_path> sorted;
1956 space_and_path_ascending_cmp cmp;
1958 sorted = session_dirs;
1959 sort (sorted.begin(), sorted.end(), cmp);
1961 for (i = sorted.begin(); i != sorted.end(); ++i) {
1962 if (create_session_directory ((*i).path)) {
1964 last_rr_session_dir = i;
1974 Session::load_playlists (const XMLNode& node)
1977 XMLNodeConstIterator niter;
1978 boost::shared_ptr<Playlist> playlist;
1980 nlist = node.children();
1984 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1986 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1987 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1995 Session::load_unused_playlists (const XMLNode& node)
1998 XMLNodeConstIterator niter;
1999 boost::shared_ptr<Playlist> playlist;
2001 nlist = node.children();
2005 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2007 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2008 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2012 // now manually untrack it
2014 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
2020 boost::shared_ptr<Playlist>
2021 Session::XMLPlaylistFactory (const XMLNode& node)
2024 return PlaylistFactory::create (*this, node);
2027 catch (failed_constructor& err) {
2028 return boost::shared_ptr<Playlist>();
2033 Session::load_named_selections (const XMLNode& node)
2036 XMLNodeConstIterator niter;
2039 nlist = node.children();
2043 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2045 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2046 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2054 Session::XMLNamedSelectionFactory (const XMLNode& node)
2057 return new NamedSelection (*this, node);
2060 catch (failed_constructor& err) {
2066 Session::automation_dir () const
2068 return Glib::build_filename (_path, "automation");
2072 Session::analysis_dir () const
2074 return Glib::build_filename (_path, "analysis");
2078 Session::load_bundles (XMLNode const & node)
2080 XMLNodeList nlist = node.children();
2081 XMLNodeConstIterator niter;
2085 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2086 if ((*niter)->name() == "InputBundle") {
2087 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2088 } else if ((*niter)->name() == "OutputBundle") {
2089 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2091 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2100 Session::load_edit_groups (const XMLNode& node)
2102 return load_route_groups (node, true);
2106 Session::load_mix_groups (const XMLNode& node)
2108 return load_route_groups (node, false);
2112 Session::load_route_groups (const XMLNode& node, bool edit)
2114 XMLNodeList nlist = node.children();
2115 XMLNodeConstIterator niter;
2120 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2121 if ((*niter)->name() == "RouteGroup") {
2123 rg = add_edit_group ("");
2124 rg->set_state (**niter);
2126 rg = add_mix_group ("");
2127 rg->set_state (**niter);
2136 Session::auto_save()
2138 save_state (_current_snapshot_name);
2142 state_file_filter (const string &str, void *arg)
2144 return (str.length() > strlen(statefile_suffix) &&
2145 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2149 bool operator()(const string* a, const string* b) {
2155 remove_end(string* state)
2157 string statename(*state);
2159 string::size_type start,end;
2160 if ((start = statename.find_last_of ('/')) != string::npos) {
2161 statename = statename.substr (start+1);
2164 if ((end = statename.rfind(".ardour")) == string::npos) {
2165 end = statename.length();
2168 return new string(statename.substr (0, end));
2172 Session::possible_states (string path)
2174 PathScanner scanner;
2175 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2177 transform(states->begin(), states->end(), states->begin(), remove_end);
2180 sort (states->begin(), states->end(), cmp);
2186 Session::possible_states () const
2188 return possible_states(_path);
2192 Session::add_edit_group (string name)
2194 RouteGroup* rg = new RouteGroup (*this, name);
2195 edit_groups.push_back (rg);
2196 edit_group_added (rg); /* EMIT SIGNAL */
2202 Session::add_mix_group (string name)
2204 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2205 mix_groups.push_back (rg);
2206 mix_group_added (rg); /* EMIT SIGNAL */
2212 Session::remove_edit_group (RouteGroup& rg)
2214 list<RouteGroup*>::iterator i;
2216 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2217 (*i)->apply (&Route::drop_edit_group, this);
2218 edit_groups.erase (i);
2219 edit_group_removed (); /* EMIT SIGNAL */
2226 Session::remove_mix_group (RouteGroup& rg)
2228 list<RouteGroup*>::iterator i;
2230 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2231 (*i)->apply (&Route::drop_mix_group, this);
2232 mix_groups.erase (i);
2233 mix_group_removed (); /* EMIT SIGNAL */
2240 Session::mix_group_by_name (string name)
2242 list<RouteGroup *>::iterator i;
2244 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2245 if ((*i)->name() == name) {
2253 Session::edit_group_by_name (string name)
2255 list<RouteGroup *>::iterator i;
2257 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2258 if ((*i)->name() == name) {
2266 Session::begin_reversible_command (const string& name)
2268 current_trans = new UndoTransaction;
2269 current_trans->set_name (name);
2273 Session::commit_reversible_command (Command *cmd)
2278 current_trans->add_command (cmd);
2281 if (current_trans->empty()) {
2285 gettimeofday (&now, 0);
2286 current_trans->set_timestamp (now);
2288 _history.add (current_trans);
2291 Session::GlobalRouteBooleanState
2292 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2294 GlobalRouteBooleanState s;
2295 boost::shared_ptr<RouteList> r = routes.reader ();
2297 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2298 if (!(*i)->is_hidden()) {
2299 RouteBooleanState v;
2302 Route* r = (*i).get();
2303 v.second = (r->*method)();
2312 Session::GlobalRouteMeterState
2313 Session::get_global_route_metering ()
2315 GlobalRouteMeterState s;
2316 boost::shared_ptr<RouteList> r = routes.reader ();
2318 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2319 if (!(*i)->is_hidden()) {
2323 v.second = (*i)->meter_point();
2333 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2335 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2337 boost::shared_ptr<Route> r = (i->first.lock());
2340 r->set_meter_point (i->second, arg);
2346 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2348 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2350 boost::shared_ptr<Route> r = (i->first.lock());
2353 Route* rp = r.get();
2354 (rp->*method) (i->second, arg);
2360 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2362 set_global_route_boolean (s, &Route::set_mute, src);
2366 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2368 set_global_route_boolean (s, &Route::set_solo, src);
2372 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2374 set_global_route_boolean (s, &Route::set_record_enable, src);
2379 Session::global_mute_memento (void* src)
2381 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2385 Session::global_metering_memento (void* src)
2387 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2391 Session::global_solo_memento (void* src)
2393 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2397 Session::global_record_enable_memento (void* src)
2399 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2404 accept_all_non_peak_files (const string& path, void *arg)
2406 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2410 accept_all_state_files (const string& path, void *arg)
2412 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2416 Session::find_all_sources (string path, set<string>& result)
2421 if (!tree.read (path)) {
2425 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2430 XMLNodeConstIterator niter;
2432 nlist = node->children();
2436 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2440 if ((prop = (*niter)->property (X_("name"))) == 0) {
2444 if (prop->value()[0] == '/') {
2445 /* external file, ignore */
2449 sys::path source_path = _session_dir->sound_path ();
2451 source_path /= prop->value ();
2453 result.insert (source_path.to_string ());
2460 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2462 PathScanner scanner;
2463 vector<string*>* state_files;
2465 string this_snapshot_path;
2471 if (ripped[ripped.length()-1] == '/') {
2472 ripped = ripped.substr (0, ripped.length() - 1);
2475 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2477 if (state_files == 0) {
2482 this_snapshot_path = _path;
2483 this_snapshot_path += _current_snapshot_name;
2484 this_snapshot_path += statefile_suffix;
2486 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2488 if (exclude_this_snapshot && **i == this_snapshot_path) {
2492 if (find_all_sources (**i, result) < 0) {
2500 struct RegionCounter {
2501 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2502 AudioSourceList::iterator iter;
2503 boost::shared_ptr<Region> region;
2506 RegionCounter() : count (0) {}
2510 Session::cleanup_sources (Session::cleanup_report& rep)
2512 // FIXME: needs adaptation to midi
2514 vector<boost::shared_ptr<Source> > dead_sources;
2515 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2516 PathScanner scanner;
2518 vector<space_and_path>::iterator i;
2519 vector<space_and_path>::iterator nexti;
2520 vector<string*>* soundfiles;
2521 vector<string> unused;
2522 set<string> all_sources;
2527 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2530 /* step 1: consider deleting all unused playlists */
2532 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2535 status = AskAboutPlaylistDeletion (*x);
2544 playlists_tbd.push_back (*x);
2548 /* leave it alone */
2553 /* now delete any that were marked for deletion */
2555 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2556 (*x)->drop_references ();
2559 playlists_tbd.clear ();
2561 /* step 2: find all un-used sources */
2566 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2568 SourceMap::iterator tmp;
2573 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2577 if (!i->second->used() && i->second->length() > 0) {
2578 dead_sources.push_back (i->second);
2579 i->second->GoingAway();
2585 /* build a list of all the possible sound directories for the session */
2587 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2592 SessionDirectory sdir ((*i).path);
2593 sound_path += sdir.sound_path().to_string();
2595 if (nexti != session_dirs.end()) {
2602 /* now do the same thing for the files that ended up in the sounds dir(s)
2603 but are not referenced as sources in any snapshot.
2606 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2608 if (soundfiles == 0) {
2612 /* find all sources, but don't use this snapshot because the
2613 state file on disk still references sources we may have already
2617 find_all_sources_across_snapshots (all_sources, true);
2619 /* add our current source list
2622 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2623 boost::shared_ptr<AudioFileSource> fs;
2625 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2626 all_sources.insert (fs->path());
2630 char tmppath1[PATH_MAX+1];
2631 char tmppath2[PATH_MAX+1];
2633 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2638 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2640 realpath(spath.c_str(), tmppath1);
2641 realpath((*i).c_str(), tmppath2);
2643 if (strcmp(tmppath1, tmppath2) == 0) {
2650 unused.push_back (spath);
2654 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2656 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2657 struct stat statbuf;
2659 rep.paths.push_back (*x);
2660 if (stat ((*x).c_str(), &statbuf) == 0) {
2661 rep.space += statbuf.st_size;
2666 /* don't move the file across filesystems, just
2667 stick it in the `dead_sound_dir_name' directory
2668 on whichever filesystem it was already on.
2671 if ((*x).find ("/sounds/") != string::npos) {
2673 /* old school, go up 1 level */
2675 newpath = Glib::path_get_dirname (*x); // "sounds"
2676 newpath = Glib::path_get_dirname (newpath); // "session-name"
2680 /* new school, go up 4 levels */
2682 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2683 newpath = Glib::path_get_dirname (newpath); // "session-name"
2684 newpath = Glib::path_get_dirname (newpath); // "interchange"
2685 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2689 newpath += dead_sound_dir_name;
2691 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2692 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2697 newpath += Glib::path_get_basename ((*x));
2699 if (access (newpath.c_str(), F_OK) == 0) {
2701 /* the new path already exists, try versioning */
2703 char buf[PATH_MAX+1];
2707 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2710 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2711 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2715 if (version == 999) {
2716 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2720 newpath = newpath_v;
2725 /* it doesn't exist, or we can't read it or something */
2729 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2730 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2731 (*x), newpath, strerror (errno))
2736 /* see if there an easy to find peakfile for this file, and remove it.
2739 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2740 peakpath += peakfile_suffix;
2742 if (access (peakpath.c_str(), W_OK) == 0) {
2743 if (::unlink (peakpath.c_str()) != 0) {
2744 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2745 peakpath, _path, strerror (errno))
2747 /* try to back out */
2748 rename (newpath.c_str(), _path.c_str());
2756 /* dump the history list */
2760 /* save state so we don't end up a session file
2761 referring to non-existent sources.
2767 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2773 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2775 // FIXME: needs adaptation for MIDI
2777 vector<space_and_path>::iterator i;
2778 string dead_sound_dir;
2779 struct dirent* dentry;
2780 struct stat statbuf;
2786 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2788 dead_sound_dir = (*i).path;
2789 dead_sound_dir += dead_sound_dir_name;
2791 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2795 while ((dentry = readdir (dead)) != 0) {
2797 /* avoid '.' and '..' */
2799 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2800 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2806 fullpath = dead_sound_dir;
2808 fullpath += dentry->d_name;
2810 if (stat (fullpath.c_str(), &statbuf)) {
2814 if (!S_ISREG (statbuf.st_mode)) {
2818 if (unlink (fullpath.c_str())) {
2819 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2820 fullpath, strerror (errno))
2824 rep.paths.push_back (dentry->d_name);
2825 rep.space += statbuf.st_size;
2836 Session::set_dirty ()
2838 bool was_dirty = dirty();
2840 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2844 DirtyChanged(); /* EMIT SIGNAL */
2850 Session::set_clean ()
2852 bool was_dirty = dirty();
2854 _state_of_the_state = Clean;
2858 DirtyChanged(); /* EMIT SIGNAL */
2863 Session::set_deletion_in_progress ()
2865 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2870 Session::add_controllable (boost::shared_ptr<Controllable> c)
2872 /* this adds a controllable to the list managed by the Session.
2873 this is a subset of those managed by the Controllable class
2874 itself, and represents the only ones whose state will be saved
2875 as part of the session.
2878 Glib::Mutex::Lock lm (controllables_lock);
2879 controllables.insert (c);
2882 struct null_deleter { void operator()(void const *) const {} };
2885 Session::remove_controllable (Controllable* c)
2887 if (_state_of_the_state | Deletion) {
2891 Glib::Mutex::Lock lm (controllables_lock);
2893 Controllables::iterator x = controllables.find(
2894 boost::shared_ptr<Controllable>(c, null_deleter()));
2896 if (x != controllables.end()) {
2897 controllables.erase (x);
2901 boost::shared_ptr<Controllable>
2902 Session::controllable_by_id (const PBD::ID& id)
2904 Glib::Mutex::Lock lm (controllables_lock);
2906 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2907 if ((*i)->id() == id) {
2912 return boost::shared_ptr<Controllable>();
2916 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2918 Stateful::add_instant_xml (node, _path);
2919 if (write_to_config) {
2920 Config->add_instant_xml (node);
2925 Session::instant_xml (const string& node_name)
2927 return Stateful::instant_xml (node_name, _path);
2931 Session::save_history (string snapshot_name)
2935 if (snapshot_name.empty()) {
2936 snapshot_name = _current_snapshot_name;
2939 const string history_filename = snapshot_name + history_suffix;
2940 const string backup_filename = history_filename + backup_suffix;
2941 const sys::path xml_path = _session_dir->root_path() / history_filename;
2942 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2944 if (sys::exists (xml_path)) {
2947 sys::rename (xml_path, backup_path);
2949 catch (const sys::filesystem_error& err)
2951 error << _("could not backup old history file, current history not saved") << endmsg;
2957 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2961 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2963 if (!tree.write (xml_path.to_string()))
2965 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2969 sys::remove (xml_path);
2970 sys::rename (backup_path, xml_path);
2972 catch (const sys::filesystem_error& err)
2974 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2975 backup_path.to_string(), err.what()) << endmsg;
2985 Session::restore_history (string snapshot_name)
2989 if (snapshot_name.empty()) {
2990 snapshot_name = _current_snapshot_name;
2993 const string xml_filename = snapshot_name + history_suffix;
2994 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2996 cerr << "Loading history from " << xml_path.to_string() << endmsg;
2998 if (!sys::exists (xml_path)) {
2999 info << string_compose (_("%1: no history file \"%2\" for this session."),
3000 _name, xml_path.to_string()) << endmsg;
3004 if (!tree.read (xml_path.to_string())) {
3005 error << string_compose (_("Could not understand session history file \"%1\""),
3006 xml_path.to_string()) << endmsg;
3013 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3016 UndoTransaction* ut = new UndoTransaction ();
3019 ut->set_name(t->property("name")->value());
3020 stringstream ss(t->property("tv-sec")->value());
3022 ss.str(t->property("tv-usec")->value());
3024 ut->set_timestamp(tv);
3026 for (XMLNodeConstIterator child_it = t->children().begin();
3027 child_it != t->children().end(); child_it++)
3029 XMLNode *n = *child_it;
3032 if (n->name() == "MementoCommand" ||
3033 n->name() == "MementoUndoCommand" ||
3034 n->name() == "MementoRedoCommand") {
3036 if ((c = memento_command_factory(n))) {
3040 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3042 if ((c = global_state_command_factory (*n))) {
3043 ut->add_command (c);
3046 } else if (n->name() == "DeltaCommand") {
3047 PBD::ID id(n->property("midi-source")->value());
3048 boost::shared_ptr<MidiSource> midi_source =
3049 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3051 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
3053 error << "FIXME: Failed to downcast MidiSource for DeltaCommand" << endmsg;
3056 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3067 Session::config_changed (const char* parameter_name)
3069 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3071 if (PARAM_IS ("seamless-loop")) {
3073 } else if (PARAM_IS ("rf-speed")) {
3075 } else if (PARAM_IS ("auto-loop")) {
3077 } else if (PARAM_IS ("auto-input")) {
3079 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3080 /* auto-input only makes a difference if we're rolling */
3082 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3084 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3085 if ((*i)->record_enabled ()) {
3086 (*i)->monitor_input (!Config->get_auto_input());
3091 } else if (PARAM_IS ("punch-in")) {
3095 if ((location = _locations.auto_punch_location()) != 0) {
3097 if (Config->get_punch_in ()) {
3098 replace_event (Event::PunchIn, location->start());
3100 remove_event (location->start(), Event::PunchIn);
3104 } else if (PARAM_IS ("punch-out")) {
3108 if ((location = _locations.auto_punch_location()) != 0) {
3110 if (Config->get_punch_out()) {
3111 replace_event (Event::PunchOut, location->end());
3113 clear_events (Event::PunchOut);
3117 } else if (PARAM_IS ("edit-mode")) {
3119 Glib::Mutex::Lock lm (playlist_lock);
3121 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3122 (*i)->set_edit_mode (Config->get_edit_mode ());
3125 } else if (PARAM_IS ("use-video-sync")) {
3127 waiting_for_sync_offset = Config->get_use_video_sync();
3129 } else if (PARAM_IS ("mmc-control")) {
3131 //poke_midi_thread ();
3133 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
3136 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3139 } else if (PARAM_IS ("mmc-send-id")) {
3142 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3145 } else if (PARAM_IS ("midi-control")) {
3147 //poke_midi_thread ();
3149 } else if (PARAM_IS ("raid-path")) {
3151 setup_raid_path (Config->get_raid_path());
3153 } else if (PARAM_IS ("smpte-format")) {
3157 } else if (PARAM_IS ("video-pullup")) {
3161 } else if (PARAM_IS ("seamless-loop")) {
3163 if (play_loop && transport_rolling()) {
3164 // to reset diskstreams etc
3165 request_play_loop (true);
3168 } else if (PARAM_IS ("rf-speed")) {
3170 cumulative_rf_motion = 0;
3173 } else if (PARAM_IS ("click-sound")) {
3175 setup_click_sounds (1);
3177 } else if (PARAM_IS ("click-emphasis-sound")) {
3179 setup_click_sounds (-1);
3181 } else if (PARAM_IS ("clicking")) {
3183 if (Config->get_clicking()) {
3184 if (_click_io && click_data) { // don't require emphasis data
3191 } else if (PARAM_IS ("send-mtc")) {
3193 /* only set the internal flag if we have
3197 if (_mtc_port != 0) {
3198 session_send_mtc = Config->get_send_mtc();
3199 if (session_send_mtc) {
3200 /* mark us ready to send */
3201 next_quarter_frame_to_send = 0;
3204 session_send_mtc = false;
3207 } else if (PARAM_IS ("send-mmc")) {
3209 /* only set the internal flag if we have
3213 if (_mmc_port != 0) {
3214 session_send_mmc = Config->get_send_mmc();
3217 session_send_mmc = false;
3220 } else if (PARAM_IS ("midi-feedback")) {
3222 /* only set the internal flag if we have
3226 if (_mtc_port != 0) {
3227 session_midi_feedback = Config->get_midi_feedback();
3230 } else if (PARAM_IS ("jack-time-master")) {
3232 engine().reset_timebase ();
3234 } else if (PARAM_IS ("native-file-header-format")) {
3236 if (!first_file_header_format_reset) {
3237 reset_native_file_format ();
3240 first_file_header_format_reset = false;
3242 } else if (PARAM_IS ("native-file-data-format")) {
3244 if (!first_file_data_format_reset) {
3245 reset_native_file_format ();
3248 first_file_data_format_reset = false;
3250 } else if (PARAM_IS ("slave-source")) {
3251 set_slave_source (Config->get_slave_source());
3252 } else if (PARAM_IS ("remote-model")) {
3253 set_remote_control_ids ();
3254 } else if (PARAM_IS ("denormal-model")) {
3256 } else if (PARAM_IS ("history-depth")) {
3257 set_history_depth (Config->get_history_depth());
3258 } else if (PARAM_IS ("sync-all-route-ordering")) {
3259 sync_order_keys ("session");
3260 } else if (PARAM_IS ("initial-program-change")) {
3262 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3265 buf[0] = MIDI::program; // channel zero by default
3266 buf[1] = (Config->get_initial_program_change() & 0x7f);
3268 _mmc_port->midimsg (buf, sizeof (buf), 0);
3270 } else if (PARAM_IS ("initial-program-change")) {
3272 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3273 MIDI::byte* buf = new MIDI::byte[2];
3275 buf[0] = MIDI::program; // channel zero by default
3276 buf[1] = (Config->get_initial_program_change() & 0x7f);
3277 // deliver_midi (_mmc_port, buf, 2);
3279 } else if (PARAM_IS ("solo-mute-override")) {
3280 catch_up_on_solo_mute_override ();
3290 Session::set_history_depth (uint32_t d)
3292 _history.set_depth (d);