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 g_atomic_int_set (&_record_status, Disabled);
167 loop_changing = false;
170 _last_roll_location = 0;
171 _last_record_location = 0;
172 pending_locate_frame = 0;
173 pending_locate_roll = false;
174 pending_locate_flush = false;
175 audio_dstream_buffer_size = 0;
176 midi_dstream_buffer_size = 0;
177 state_was_pending = false;
179 outbound_mtc_smpte_frame = 0;
180 next_quarter_frame_to_send = -1;
181 current_block_size = 0;
182 solo_update_disabled = false;
183 currently_soloing = false;
184 _have_captured = false;
185 _worst_output_latency = 0;
186 _worst_input_latency = 0;
187 _worst_track_latency = 0;
188 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
191 session_send_mmc = false;
192 session_send_mtc = false;
193 post_transport_work = PostTransportWork (0);
194 g_atomic_int_set (&butler_should_do_transport_work, 0);
195 g_atomic_int_set (&_playback_load, 100);
196 g_atomic_int_set (&_capture_load, 100);
197 g_atomic_int_set (&_playback_load_min, 100);
198 g_atomic_int_set (&_capture_load_min, 100);
201 _exporting_realtime = false;
202 _gain_automation_buffer = 0;
203 _pan_automation_buffer = 0;
205 pending_abort = false;
206 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 (*this, 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 << err.what() << endmsg;
349 BootMessage (_("Reset Remote Controls"));
351 send_full_time_code (0);
352 _engine.transport_locate (0);
353 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
354 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
356 MidiClockTicker::instance().set_session(*this);
357 MIDI::Name::MidiPatchManager::instance().set_session(*this);
359 /* initial program change will be delivered later; see ::config_changed() */
361 BootMessage (_("Reset Control Protocols"));
363 ControlProtocolManager::instance().set_session (*this);
365 config.set_end_marker_is_free (new_session);
367 _state_of_the_state = Clean;
369 DirtyChanged (); /* EMIT SIGNAL */
371 if (state_was_pending) {
372 save_state (_current_snapshot_name);
373 remove_pending_capture_state ();
374 state_was_pending = false;
377 BootMessage (_("Session loading complete"));
383 Session::raid_path () const
385 SearchPath raid_search_path;
387 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
388 raid_search_path += sys::path((*i).path);
391 return raid_search_path.to_string ();
395 Session::setup_raid_path (string path)
404 session_dirs.clear ();
406 SearchPath search_path(path);
407 SearchPath sound_search_path;
408 SearchPath midi_search_path;
410 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
411 sp.path = (*i).to_string ();
412 sp.blocks = 0; // not needed
413 session_dirs.push_back (sp);
415 SessionDirectory sdir(sp.path);
417 sound_search_path += sdir.sound_path ();
418 midi_search_path += sdir.midi_path ();
421 // set the search path for each data type
422 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
423 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
425 // reset the round-robin soundfile path thingie
426 last_rr_session_dir = session_dirs.begin();
430 Session::ensure_subdirs ()
434 dir = session_directory().peak_path().to_string();
436 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
437 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
441 dir = session_directory().sound_path().to_string();
443 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
444 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
448 dir = session_directory().midi_path().to_string();
450 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
451 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
455 dir = session_directory().dead_sound_path().to_string();
457 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
458 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
462 dir = session_directory().export_path().to_string();
464 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
465 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
469 dir = analysis_dir ();
471 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
472 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
480 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
483 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
484 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
488 if (ensure_subdirs ()) {
492 /* check new_session so we don't overwrite an existing one */
494 if (!mix_template.empty()) {
495 std::string in_path = mix_template;
497 ifstream in(in_path.c_str());
500 string out_path = _path;
502 out_path += statefile_suffix;
504 ofstream out(out_path.c_str());
509 // okay, session is set up. Treat like normal saved
510 // session from now on.
516 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
522 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
529 /* Instantiate metadata */
531 _metadata = new SessionMetadata ();
533 /* set initial start + end point */
535 start_location->set_end (0);
536 _locations.add (start_location);
538 end_location->set_end (initial_length);
539 _locations.add (end_location);
541 _state_of_the_state = Clean;
550 Session::load_diskstreams (const XMLNode& node)
553 XMLNodeConstIterator citer;
555 clist = node.children();
557 for (citer = clist.begin(); citer != clist.end(); ++citer) {
560 /* diskstreams added automatically by DiskstreamCreated handler */
561 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
562 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
563 add_diskstream (dstream);
564 } else if ((*citer)->name() == "MidiDiskstream") {
565 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
566 add_diskstream (dstream);
568 error << _("Session: unknown diskstream type in XML") << endmsg;
572 catch (failed_constructor& err) {
573 error << _("Session: could not load diskstream via XML state") << endmsg;
582 Session::maybe_write_autosave()
584 if (dirty() && record_status() != Recording) {
585 save_state("", true);
590 Session::remove_pending_capture_state ()
592 sys::path pending_state_file_path(_session_dir->root_path());
594 pending_state_file_path /= _current_snapshot_name + pending_suffix;
598 sys::remove (pending_state_file_path);
600 catch(sys::filesystem_error& ex)
602 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
603 pending_state_file_path.to_string(), ex.what()) << endmsg;
607 /** Rename a state file.
608 * @param snapshot_name Snapshot name.
611 Session::rename_state (string old_name, string new_name)
613 if (old_name == _current_snapshot_name || old_name == _name) {
614 /* refuse to rename the current snapshot or the "main" one */
618 const string old_xml_filename = old_name + statefile_suffix;
619 const string new_xml_filename = new_name + statefile_suffix;
621 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
622 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
626 sys::rename (old_xml_path, new_xml_path);
628 catch (const sys::filesystem_error& err)
630 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
631 old_name, new_name, err.what()) << endmsg;
635 /** Remove a state file.
636 * @param snapshot_name Snapshot name.
639 Session::remove_state (string snapshot_name)
641 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
642 // refuse to remove the current snapshot or the "main" one
646 sys::path xml_path(_session_dir->root_path());
648 xml_path /= snapshot_name + statefile_suffix;
650 if (!create_backup_file (xml_path)) {
651 // don't remove it if a backup can't be made
652 // create_backup_file will log the error.
657 sys::remove (xml_path);
661 Session::save_state (string snapshot_name, bool pending)
664 sys::path xml_path(_session_dir->root_path());
666 if (_state_of_the_state & CannotSave) {
670 if (!_engine.connected ()) {
671 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
676 /* tell sources we're saving first, in case they write out to a new file
677 * which should be saved with the state rather than the old one */
678 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
679 i->second->session_saved();
681 tree.set_root (&get_state());
683 if (snapshot_name.empty()) {
684 snapshot_name = _current_snapshot_name;
689 /* proper save: use statefile_suffix (.ardour in English) */
691 xml_path /= snapshot_name + statefile_suffix;
693 /* make a backup copy of the old file */
695 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
696 // create_backup_file will log the error
702 /* pending save: use pending_suffix (.pending in English) */
703 xml_path /= snapshot_name + pending_suffix;
706 sys::path tmp_path(_session_dir->root_path());
708 tmp_path /= snapshot_name + temp_suffix;
710 // cerr << "actually writing state to " << xml_path.to_string() << endl;
712 if (!tree.write (tmp_path.to_string())) {
713 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
714 sys::remove (tmp_path);
719 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
720 error << string_compose (_("could not rename temporary session file %1 to %2"),
721 tmp_path.to_string(), xml_path.to_string()) << endmsg;
722 sys::remove (tmp_path);
729 save_history (snapshot_name);
731 bool was_dirty = dirty();
733 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
736 DirtyChanged (); /* EMIT SIGNAL */
739 StateSaved (snapshot_name); /* EMIT SIGNAL */
746 Session::restore_state (string snapshot_name)
748 if (load_state (snapshot_name) == 0) {
749 set_state (*state_tree->root());
756 Session::load_state (string snapshot_name)
761 state_was_pending = false;
763 /* check for leftover pending state from a crashed capture attempt */
765 sys::path xmlpath(_session_dir->root_path());
766 xmlpath /= snapshot_name + pending_suffix;
768 if (sys::exists (xmlpath)) {
770 /* there is pending state from a crashed capture attempt */
772 if (AskAboutPendingState()) {
773 state_was_pending = true;
777 if (!state_was_pending) {
778 xmlpath = _session_dir->root_path();
779 xmlpath /= snapshot_name + statefile_suffix;
782 if (!sys::exists (xmlpath)) {
783 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
787 state_tree = new XMLTree;
791 if (!state_tree->read (xmlpath.to_string())) {
792 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
798 XMLNode& root (*state_tree->root());
800 if (root.name() != X_("Session")) {
801 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
807 const XMLProperty* prop;
808 bool is_old = false; // session is _very_ old (pre-2.0)
810 if ((prop = root.property ("version")) == 0) {
811 /* no version implies very old version of Ardour */
815 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
816 if (major_version < 2) {
823 sys::path backup_path(_session_dir->root_path());
825 backup_path /= snapshot_name + "-1" + statefile_suffix;
827 // only create a backup once
828 if (sys::exists (backup_path)) {
832 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
833 xmlpath.to_string(), backup_path.to_string())
838 sys::copy_file (xmlpath, backup_path);
840 catch(sys::filesystem_error& ex)
842 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
843 xmlpath.to_string(), ex.what())
853 Session::load_options (const XMLNode& node)
855 LocaleGuard lg (X_("POSIX"));
857 config.set_variables (node);
859 /* now reset MIDI ports because the session can have its own
875 Session::get_template()
877 /* if we don't disable rec-enable, diskstreams
878 will believe they need to store their capture
879 sources in their state node.
882 disable_record (false);
888 Session::state(bool full_state)
890 XMLNode* node = new XMLNode("Session");
893 // store libardour version, just in case
895 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
896 node->add_property("version", string(buf));
898 /* store configuration settings */
902 node->add_property ("name", _name);
903 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
904 node->add_property ("sample-rate", buf);
906 if (session_dirs.size() > 1) {
910 vector<space_and_path>::iterator i = session_dirs.begin();
911 vector<space_and_path>::iterator next;
913 ++i; /* skip the first one */
917 while (i != session_dirs.end()) {
921 if (next != session_dirs.end()) {
931 child = node->add_child ("Path");
932 child->add_content (p);
936 /* save the ID counter */
938 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
939 node->add_property ("id-counter", buf);
941 /* various options */
943 node->add_child_nocopy (config.get_variables ());
945 node->add_child_nocopy (_metadata->get_state());
947 child = node->add_child ("Sources");
950 Glib::Mutex::Lock sl (source_lock);
952 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
954 /* Don't save information about non-destructive file sources that are empty */
955 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
957 boost::shared_ptr<AudioFileSource> fs;
958 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
959 if (!fs->destructive()) {
960 if (fs->length(fs->timeline_position()) == 0) {
966 child->add_child_nocopy (siter->second->get_state());
970 child = node->add_child ("Regions");
973 Glib::Mutex::Lock rl (region_lock);
975 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
977 /* only store regions not attached to playlists */
979 if (i->second->playlist() == 0) {
980 child->add_child_nocopy (i->second->state (true));
985 child = node->add_child ("DiskStreams");
988 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
989 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
990 if (!(*i)->hidden()) {
991 child->add_child_nocopy ((*i)->get_state());
997 node->add_child_nocopy (_locations.get_state());
999 // for a template, just create a new Locations, populate it
1000 // with the default start and end, and get the state for that.
1002 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1003 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1006 end->set_end(compute_initial_length());
1008 node->add_child_nocopy (loc.get_state());
1011 child = node->add_child ("Bundles");
1013 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1014 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1015 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1017 child->add_child_nocopy (b->get_state());
1022 child = node->add_child ("Routes");
1024 boost::shared_ptr<RouteList> r = routes.reader ();
1026 RoutePublicOrderSorter cmp;
1027 RouteList public_order (*r);
1028 public_order.sort (cmp);
1030 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1031 if (!(*i)->is_hidden()) {
1033 child->add_child_nocopy ((*i)->get_state());
1035 child->add_child_nocopy ((*i)->get_template());
1042 child = node->add_child ("EditGroups");
1043 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1044 child->add_child_nocopy ((*i)->get_state());
1047 child = node->add_child ("MixGroups");
1048 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1049 child->add_child_nocopy ((*i)->get_state());
1052 child = node->add_child ("Playlists");
1053 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1054 if (!(*i)->hidden()) {
1055 if (!(*i)->empty()) {
1057 child->add_child_nocopy ((*i)->get_state());
1059 child->add_child_nocopy ((*i)->get_template());
1065 child = node->add_child ("UnusedPlaylists");
1066 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1067 if (!(*i)->hidden()) {
1068 if (!(*i)->empty()) {
1070 child->add_child_nocopy ((*i)->get_state());
1072 child->add_child_nocopy ((*i)->get_template());
1080 child = node->add_child ("Click");
1081 child->add_child_nocopy (_click_io->state (full_state));
1085 child = node->add_child ("NamedSelections");
1086 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1088 child->add_child_nocopy ((*i)->get_state());
1093 node->add_child_nocopy (_tempo_map->get_state());
1095 node->add_child_nocopy (get_control_protocol_state());
1098 node->add_child_copy (*_extra_xml);
1105 Session::get_control_protocol_state ()
1107 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1108 return cpm.get_state();
1112 Session::set_state (const XMLNode& node)
1116 const XMLProperty* prop;
1119 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1121 if (node.name() != X_("Session")){
1122 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1126 if ((prop = node.property ("name")) != 0) {
1127 _name = prop->value ();
1130 if ((prop = node.property (X_("sample-rate"))) != 0) {
1132 _nominal_frame_rate = atoi (prop->value());
1134 if (_nominal_frame_rate != _current_frame_rate) {
1135 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1141 setup_raid_path(_session_dir->root_path().to_string());
1143 if ((prop = node.property (X_("id-counter"))) != 0) {
1145 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1146 ID::init_counter (x);
1148 /* old sessions used a timebased counter, so fake
1149 the startup ID counter based on a standard
1154 ID::init_counter (now);
1158 IO::disable_ports ();
1159 IO::disable_connecting ();
1161 /* Object loading order:
1166 MIDI Control // relies on data from Options/Config
1180 if ((child = find_named_node (node, "Extra")) != 0) {
1181 _extra_xml = new XMLNode (*child);
1184 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1185 load_options (*child);
1186 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1187 load_options (*child);
1189 error << _("Session: XML state has no options section") << endmsg;
1192 if (use_config_midi_ports ()) {
1195 if ((child = find_named_node (node, "Metadata")) == 0) {
1196 warning << _("Session: XML state has no metadata section (2.0 session?)") << endmsg;
1197 } else if (_metadata->set_state (*child)) {
1201 if ((child = find_named_node (node, "Locations")) == 0) {
1202 error << _("Session: XML state has no locations section") << endmsg;
1204 } else if (_locations.set_state (*child)) {
1210 if ((location = _locations.auto_loop_location()) != 0) {
1211 set_auto_loop_location (location);
1214 if ((location = _locations.auto_punch_location()) != 0) {
1215 set_auto_punch_location (location);
1218 if ((location = _locations.end_location()) == 0) {
1219 _locations.add (end_location);
1221 delete end_location;
1222 end_location = location;
1225 if ((location = _locations.start_location()) == 0) {
1226 _locations.add (start_location);
1228 delete start_location;
1229 start_location = location;
1232 AudioFileSource::set_header_position_offset (start_location->start());
1234 if ((child = find_named_node (node, "Sources")) == 0) {
1235 error << _("Session: XML state has no sources section") << endmsg;
1237 } else if (load_sources (*child)) {
1241 if ((child = find_named_node (node, "Regions")) == 0) {
1242 error << _("Session: XML state has no Regions section") << endmsg;
1244 } else if (load_regions (*child)) {
1248 if ((child = find_named_node (node, "Playlists")) == 0) {
1249 error << _("Session: XML state has no playlists section") << endmsg;
1251 } else if (load_playlists (*child)) {
1255 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1257 } else if (load_unused_playlists (*child)) {
1261 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1262 if (load_named_selections (*child)) {
1267 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1268 error << _("Session: XML state has no diskstreams section") << endmsg;
1270 } else if (load_diskstreams (*child)) {
1274 if ((child = find_named_node (node, "Bundles")) == 0) {
1275 warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg;
1278 /* We can't load Bundles yet as they need to be able
1279 to convert from port names to Port objects, which can't happen until
1281 _bundle_xml_node = new XMLNode (*child);
1284 if ((child = find_named_node (node, "EditGroups")) == 0) {
1285 error << _("Session: XML state has no edit groups section") << endmsg;
1287 } else if (load_edit_groups (*child)) {
1291 if ((child = find_named_node (node, "MixGroups")) == 0) {
1292 error << _("Session: XML state has no mix groups section") << endmsg;
1294 } else if (load_mix_groups (*child)) {
1298 if ((child = find_named_node (node, "TempoMap")) == 0) {
1299 error << _("Session: XML state has no Tempo Map section") << endmsg;
1301 } else if (_tempo_map->set_state (*child)) {
1305 if ((child = find_named_node (node, "Routes")) == 0) {
1306 error << _("Session: XML state has no routes section") << endmsg;
1308 } else if (load_routes (*child)) {
1312 if ((child = find_named_node (node, "Click")) == 0) {
1313 warning << _("Session: XML state has no click section") << endmsg;
1314 } else if (_click_io) {
1315 _click_io->set_state (*child);
1318 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1319 ControlProtocolManager::instance().set_protocol_states (*child);
1322 /* here beginneth the second phase ... */
1324 StateReady (); /* EMIT SIGNAL */
1333 Session::load_routes (const XMLNode& node)
1336 XMLNodeConstIterator niter;
1337 RouteList new_routes;
1339 nlist = node.children();
1343 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1345 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1348 error << _("Session: cannot create Route from XML description.") << endmsg;
1352 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1354 new_routes.push_back (route);
1357 add_routes (new_routes, false);
1362 boost::shared_ptr<Route>
1363 Session::XMLRouteFactory (const XMLNode& node)
1365 if (node.name() != "Route") {
1366 return boost::shared_ptr<Route> ((Route*) 0);
1369 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1371 DataType type = DataType::AUDIO;
1372 const XMLProperty* prop = node.property("default-type");
1375 type = DataType(prop->value());
1378 assert(type != DataType::NIL);
1380 if (has_diskstream) {
1381 if (type == DataType::AUDIO) {
1382 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1385 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1389 boost::shared_ptr<Route> ret (new Route (*this, node));
1395 Session::load_regions (const XMLNode& node)
1398 XMLNodeConstIterator niter;
1399 boost::shared_ptr<Region> region;
1401 nlist = node.children();
1405 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1406 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1407 error << _("Session: cannot create Region from XML description.");
1408 const XMLProperty *name = (**niter).property("name");
1411 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1421 boost::shared_ptr<Region>
1422 Session::XMLRegionFactory (const XMLNode& node, bool full)
1424 const XMLProperty* type = node.property("type");
1428 if ( !type || type->value() == "audio" ) {
1430 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1432 } else if (type->value() == "midi") {
1434 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1438 } catch (failed_constructor& err) {
1439 return boost::shared_ptr<Region> ();
1442 return boost::shared_ptr<Region> ();
1445 boost::shared_ptr<AudioRegion>
1446 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1448 const XMLProperty* prop;
1449 boost::shared_ptr<Source> source;
1450 boost::shared_ptr<AudioSource> as;
1452 SourceList master_sources;
1453 uint32_t nchans = 1;
1456 if (node.name() != X_("Region")) {
1457 return boost::shared_ptr<AudioRegion>();
1460 if ((prop = node.property (X_("channels"))) != 0) {
1461 nchans = atoi (prop->value().c_str());
1464 if ((prop = node.property ("name")) == 0) {
1465 cerr << "no name for this region\n";
1469 if ((prop = node.property (X_("source-0"))) == 0) {
1470 if ((prop = node.property ("source")) == 0) {
1471 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1472 return boost::shared_ptr<AudioRegion>();
1476 PBD::ID s_id (prop->value());
1478 if ((source = source_by_id (s_id)) == 0) {
1479 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1480 return boost::shared_ptr<AudioRegion>();
1483 as = boost::dynamic_pointer_cast<AudioSource>(source);
1485 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1486 return boost::shared_ptr<AudioRegion>();
1489 sources.push_back (as);
1491 /* pickup other channels */
1493 for (uint32_t n=1; n < nchans; ++n) {
1494 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1495 if ((prop = node.property (buf)) != 0) {
1497 PBD::ID id2 (prop->value());
1499 if ((source = source_by_id (id2)) == 0) {
1500 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1501 return boost::shared_ptr<AudioRegion>();
1504 as = boost::dynamic_pointer_cast<AudioSource>(source);
1506 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1507 return boost::shared_ptr<AudioRegion>();
1509 sources.push_back (as);
1513 for (uint32_t n=1; n < nchans; ++n) {
1514 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1515 if ((prop = node.property (buf)) != 0) {
1517 PBD::ID id2 (prop->value());
1519 if ((source = source_by_id (id2)) == 0) {
1520 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1521 return boost::shared_ptr<AudioRegion>();
1524 as = boost::dynamic_pointer_cast<AudioSource>(source);
1526 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1527 return boost::shared_ptr<AudioRegion>();
1529 master_sources.push_back (as);
1534 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1536 /* a final detail: this is the one and only place that we know how long missing files are */
1538 if (region->whole_file()) {
1539 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1540 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1542 sfp->set_length (region->length());
1547 if (!master_sources.empty()) {
1548 if (master_sources.size() == nchans) {
1549 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1551 region->set_master_sources (master_sources);
1559 catch (failed_constructor& err) {
1560 return boost::shared_ptr<AudioRegion>();
1564 boost::shared_ptr<MidiRegion>
1565 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1567 const XMLProperty* prop;
1568 boost::shared_ptr<Source> source;
1569 boost::shared_ptr<MidiSource> ms;
1571 uint32_t nchans = 1;
1573 if (node.name() != X_("Region")) {
1574 return boost::shared_ptr<MidiRegion>();
1577 if ((prop = node.property (X_("channels"))) != 0) {
1578 nchans = atoi (prop->value().c_str());
1581 if ((prop = node.property ("name")) == 0) {
1582 cerr << "no name for this region\n";
1586 // Multiple midi channels? that's just crazy talk
1587 assert(nchans == 1);
1589 if ((prop = node.property (X_("source-0"))) == 0) {
1590 if ((prop = node.property ("source")) == 0) {
1591 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1592 return boost::shared_ptr<MidiRegion>();
1596 PBD::ID s_id (prop->value());
1598 if ((source = source_by_id (s_id)) == 0) {
1599 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1600 return boost::shared_ptr<MidiRegion>();
1603 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1605 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1606 return boost::shared_ptr<MidiRegion>();
1609 sources.push_back (ms);
1612 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1613 /* a final detail: this is the one and only place that we know how long missing files are */
1615 if (region->whole_file()) {
1616 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1617 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1619 sfp->set_length (region->length());
1627 catch (failed_constructor& err) {
1628 return boost::shared_ptr<MidiRegion>();
1633 Session::get_sources_as_xml ()
1636 XMLNode* node = new XMLNode (X_("Sources"));
1637 Glib::Mutex::Lock lm (source_lock);
1639 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1640 node->add_child_nocopy (i->second->get_state());
1647 Session::path_from_region_name (DataType type, string name, string identifier)
1649 char buf[PATH_MAX+1];
1651 SessionDirectory sdir(get_best_session_directory_for_new_source());
1652 sys::path source_dir = ((type == DataType::AUDIO)
1653 ? sdir.sound_path() : sdir.midi_path());
1655 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1657 for (n = 0; n < 999999; ++n) {
1658 if (identifier.length()) {
1659 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1660 identifier.c_str(), n, ext.c_str());
1662 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1666 sys::path source_path = source_dir / buf;
1668 if (!sys::exists (source_path)) {
1669 return source_path.to_string();
1673 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1682 Session::load_sources (const XMLNode& node)
1685 XMLNodeConstIterator niter;
1686 boost::shared_ptr<Source> source;
1688 nlist = node.children();
1692 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1694 if ((source = XMLSourceFactory (**niter)) == 0) {
1695 error << _("Session: cannot create Source from XML description.") << endmsg;
1697 } catch (MissingSource& err) {
1698 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1699 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1706 boost::shared_ptr<Source>
1707 Session::XMLSourceFactory (const XMLNode& node)
1709 if (node.name() != "Source") {
1710 return boost::shared_ptr<Source>();
1714 /* note: do peak building in another thread when loading session state */
1715 return SourceFactory::create (*this, node, true);
1718 catch (failed_constructor& err) {
1719 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1720 return boost::shared_ptr<Source>();
1725 Session::save_template (string template_name)
1729 if (_state_of_the_state & CannotSave) {
1733 sys::path user_template_dir(user_template_directory());
1737 sys::create_directories (user_template_dir);
1739 catch(sys::filesystem_error& ex)
1741 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1742 user_template_dir.to_string(), ex.what()) << endmsg;
1746 tree.set_root (&get_template());
1748 sys::path template_file_path(user_template_dir);
1749 template_file_path /= template_name + template_suffix;
1751 if (sys::exists (template_file_path))
1753 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1754 template_file_path.to_string()) << endmsg;
1758 if (!tree.write (template_file_path.to_string())) {
1759 error << _("mix template not saved") << endmsg;
1767 Session::rename_template (string old_name, string new_name)
1769 sys::path old_path (user_template_directory());
1770 old_path /= old_name + template_suffix;
1772 sys::path new_path(user_template_directory());
1773 new_path /= new_name + template_suffix;
1775 if (sys::exists (new_path)) {
1776 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1777 new_path.to_string()) << endmsg;
1782 sys::rename (old_path, new_path);
1790 Session::delete_template (string name)
1792 sys::path path = user_template_directory();
1793 path /= name + template_suffix;
1804 Session::refresh_disk_space ()
1807 struct statfs statfsbuf;
1808 vector<space_and_path>::iterator i;
1809 Glib::Mutex::Lock lm (space_lock);
1812 /* get freespace on every FS that is part of the session path */
1814 _total_free_4k_blocks = 0;
1816 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1817 statfs ((*i).path.c_str(), &statfsbuf);
1819 scale = statfsbuf.f_bsize/4096.0;
1821 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1822 _total_free_4k_blocks += (*i).blocks;
1828 Session::get_best_session_directory_for_new_source ()
1830 vector<space_and_path>::iterator i;
1831 string result = _session_dir->root_path().to_string();
1833 /* handle common case without system calls */
1835 if (session_dirs.size() == 1) {
1839 /* OK, here's the algorithm we're following here:
1841 We want to select which directory to use for
1842 the next file source to be created. Ideally,
1843 we'd like to use a round-robin process so as to
1844 get maximum performance benefits from splitting
1845 the files across multiple disks.
1847 However, in situations without much diskspace, an
1848 RR approach may end up filling up a filesystem
1849 with new files while others still have space.
1850 Its therefore important to pay some attention to
1851 the freespace in the filesystem holding each
1852 directory as well. However, if we did that by
1853 itself, we'd keep creating new files in the file
1854 system with the most space until it was as full
1855 as all others, thus negating any performance
1856 benefits of this RAID-1 like approach.
1858 So, we use a user-configurable space threshold. If
1859 there are at least 2 filesystems with more than this
1860 much space available, we use RR selection between them.
1861 If not, then we pick the filesystem with the most space.
1863 This gets a good balance between the two
1867 refresh_disk_space ();
1869 int free_enough = 0;
1871 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1872 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1877 if (free_enough >= 2) {
1878 /* use RR selection process, ensuring that the one
1882 i = last_rr_session_dir;
1885 if (++i == session_dirs.end()) {
1886 i = session_dirs.begin();
1889 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1890 if (create_session_directory ((*i).path)) {
1892 last_rr_session_dir = i;
1897 } while (i != last_rr_session_dir);
1901 /* pick FS with the most freespace (and that
1902 seems to actually work ...)
1905 vector<space_and_path> sorted;
1906 space_and_path_ascending_cmp cmp;
1908 sorted = session_dirs;
1909 sort (sorted.begin(), sorted.end(), cmp);
1911 for (i = sorted.begin(); i != sorted.end(); ++i) {
1912 if (create_session_directory ((*i).path)) {
1914 last_rr_session_dir = i;
1924 Session::load_playlists (const XMLNode& node)
1927 XMLNodeConstIterator niter;
1928 boost::shared_ptr<Playlist> playlist;
1930 nlist = node.children();
1934 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1936 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1937 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1945 Session::load_unused_playlists (const XMLNode& node)
1948 XMLNodeConstIterator niter;
1949 boost::shared_ptr<Playlist> playlist;
1951 nlist = node.children();
1955 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1957 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1958 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1962 // now manually untrack it
1964 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1970 boost::shared_ptr<Playlist>
1971 Session::XMLPlaylistFactory (const XMLNode& node)
1974 return PlaylistFactory::create (*this, node);
1977 catch (failed_constructor& err) {
1978 return boost::shared_ptr<Playlist>();
1983 Session::load_named_selections (const XMLNode& node)
1986 XMLNodeConstIterator niter;
1989 nlist = node.children();
1993 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1995 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1996 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2004 Session::XMLNamedSelectionFactory (const XMLNode& node)
2007 return new NamedSelection (*this, node);
2010 catch (failed_constructor& err) {
2016 Session::automation_dir () const
2018 return Glib::build_filename (_path, "automation");
2022 Session::analysis_dir () const
2024 return Glib::build_filename (_path, "analysis");
2028 Session::load_bundles (XMLNode const & node)
2030 XMLNodeList nlist = node.children();
2031 XMLNodeConstIterator niter;
2035 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2036 if ((*niter)->name() == "InputBundle") {
2037 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2038 } else if ((*niter)->name() == "OutputBundle") {
2039 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2041 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2050 Session::load_edit_groups (const XMLNode& node)
2052 return load_route_groups (node, true);
2056 Session::load_mix_groups (const XMLNode& node)
2058 return load_route_groups (node, false);
2062 Session::load_route_groups (const XMLNode& node, bool edit)
2064 XMLNodeList nlist = node.children();
2065 XMLNodeConstIterator niter;
2070 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2071 if ((*niter)->name() == "RouteGroup") {
2073 rg = add_edit_group ("");
2074 rg->set_state (**niter);
2076 rg = add_mix_group ("");
2077 rg->set_state (**niter);
2086 Session::auto_save()
2088 save_state (_current_snapshot_name);
2092 state_file_filter (const string &str, void *arg)
2094 return (str.length() > strlen(statefile_suffix) &&
2095 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2099 bool operator()(const string* a, const string* b) {
2105 remove_end(string* state)
2107 string statename(*state);
2109 string::size_type start,end;
2110 if ((start = statename.find_last_of ('/')) != string::npos) {
2111 statename = statename.substr (start+1);
2114 if ((end = statename.rfind(".ardour")) == string::npos) {
2115 end = statename.length();
2118 return new string(statename.substr (0, end));
2122 Session::possible_states (string path)
2124 PathScanner scanner;
2125 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2127 transform(states->begin(), states->end(), states->begin(), remove_end);
2130 sort (states->begin(), states->end(), cmp);
2136 Session::possible_states () const
2138 return possible_states(_path);
2142 Session::add_edit_group (string name)
2144 RouteGroup* rg = new RouteGroup (*this, name);
2145 edit_groups.push_back (rg);
2146 edit_group_added (rg); /* EMIT SIGNAL */
2152 Session::add_mix_group (string name)
2154 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2155 mix_groups.push_back (rg);
2156 mix_group_added (rg); /* EMIT SIGNAL */
2162 Session::remove_edit_group (RouteGroup& rg)
2164 list<RouteGroup*>::iterator i;
2166 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2167 (*i)->apply (&Route::drop_edit_group, this);
2168 edit_groups.erase (i);
2169 edit_group_removed (); /* EMIT SIGNAL */
2176 Session::remove_mix_group (RouteGroup& rg)
2178 list<RouteGroup*>::iterator i;
2180 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2181 (*i)->apply (&Route::drop_mix_group, this);
2182 mix_groups.erase (i);
2183 mix_group_removed (); /* EMIT SIGNAL */
2190 Session::mix_group_by_name (string name)
2192 list<RouteGroup *>::iterator i;
2194 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2195 if ((*i)->name() == name) {
2203 Session::edit_group_by_name (string name)
2205 list<RouteGroup *>::iterator i;
2207 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2208 if ((*i)->name() == name) {
2216 Session::begin_reversible_command(const string& name)
2218 UndoTransaction* trans = new UndoTransaction();
2219 trans->set_name(name);
2220 if (!_current_trans.empty()) {
2221 _current_trans.top()->add_command(trans);
2223 _current_trans.push(trans);
2227 Session::commit_reversible_command(Command *cmd)
2229 assert(!_current_trans.empty());
2233 _current_trans.top()->add_command(cmd);
2236 if (_current_trans.top()->empty()) {
2237 _current_trans.pop();
2241 gettimeofday(&now, 0);
2242 _current_trans.top()->set_timestamp(now);
2244 _history.add(_current_trans.top());
2245 _current_trans.pop();
2248 Session::GlobalRouteBooleanState
2249 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2251 GlobalRouteBooleanState s;
2252 boost::shared_ptr<RouteList> r = routes.reader ();
2254 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2255 if (!(*i)->is_hidden()) {
2256 RouteBooleanState v;
2259 Route* r = (*i).get();
2260 v.second = (r->*method)();
2269 Session::GlobalRouteMeterState
2270 Session::get_global_route_metering ()
2272 GlobalRouteMeterState s;
2273 boost::shared_ptr<RouteList> r = routes.reader ();
2275 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2276 if (!(*i)->is_hidden()) {
2280 v.second = (*i)->meter_point();
2290 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2292 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2294 boost::shared_ptr<Route> r = (i->first.lock());
2297 r->set_meter_point (i->second, arg);
2303 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2305 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2307 boost::shared_ptr<Route> r = (i->first.lock());
2310 Route* rp = r.get();
2311 (rp->*method) (i->second, arg);
2317 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2319 set_global_route_boolean (s, &Route::set_mute, src);
2323 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2325 set_global_route_boolean (s, &Route::set_solo, src);
2329 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2331 set_global_route_boolean (s, &Route::set_record_enable, src);
2335 accept_all_non_peak_files (const string& path, void *arg)
2337 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2341 accept_all_state_files (const string& path, void *arg)
2343 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2347 Session::find_all_sources (string path, set<string>& result)
2352 if (!tree.read (path)) {
2356 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2361 XMLNodeConstIterator niter;
2363 nlist = node->children();
2367 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2371 if ((prop = (*niter)->property (X_("name"))) == 0) {
2375 if (prop->value()[0] == '/') {
2376 /* external file, ignore */
2380 sys::path source_path = _session_dir->sound_path ();
2382 source_path /= prop->value ();
2384 result.insert (source_path.to_string ());
2391 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2393 PathScanner scanner;
2394 vector<string*>* state_files;
2396 string this_snapshot_path;
2402 if (ripped[ripped.length()-1] == '/') {
2403 ripped = ripped.substr (0, ripped.length() - 1);
2406 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2408 if (state_files == 0) {
2413 this_snapshot_path = _path;
2414 this_snapshot_path += _current_snapshot_name;
2415 this_snapshot_path += statefile_suffix;
2417 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2419 if (exclude_this_snapshot && **i == this_snapshot_path) {
2423 if (find_all_sources (**i, result) < 0) {
2431 struct RegionCounter {
2432 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2433 AudioSourceList::iterator iter;
2434 boost::shared_ptr<Region> region;
2437 RegionCounter() : count (0) {}
2441 Session::cleanup_sources (Session::cleanup_report& rep)
2443 // FIXME: needs adaptation to midi
2445 vector<boost::shared_ptr<Source> > dead_sources;
2446 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2447 PathScanner scanner;
2449 vector<space_and_path>::iterator i;
2450 vector<space_and_path>::iterator nexti;
2451 vector<string*>* soundfiles;
2452 vector<string> unused;
2453 set<string> all_sources;
2458 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2461 /* step 1: consider deleting all unused playlists */
2463 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2466 status = AskAboutPlaylistDeletion (*x);
2475 playlists_tbd.push_back (*x);
2479 /* leave it alone */
2484 /* now delete any that were marked for deletion */
2486 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2487 (*x)->drop_references ();
2490 playlists_tbd.clear ();
2492 /* step 2: find all un-used sources */
2497 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2499 SourceMap::iterator tmp;
2504 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2508 if (!i->second->used() && i->second->length(i->second->timeline_position()) > 0) {
2509 dead_sources.push_back (i->second);
2510 i->second->GoingAway();
2516 /* build a list of all the possible sound directories for the session */
2518 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2523 SessionDirectory sdir ((*i).path);
2524 sound_path += sdir.sound_path().to_string();
2526 if (nexti != session_dirs.end()) {
2533 /* now do the same thing for the files that ended up in the sounds dir(s)
2534 but are not referenced as sources in any snapshot.
2537 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2539 if (soundfiles == 0) {
2543 /* find all sources, but don't use this snapshot because the
2544 state file on disk still references sources we may have already
2548 find_all_sources_across_snapshots (all_sources, true);
2550 /* add our current source list
2553 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2554 boost::shared_ptr<FileSource> fs;
2556 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2557 all_sources.insert (fs->path());
2561 char tmppath1[PATH_MAX+1];
2562 char tmppath2[PATH_MAX+1];
2564 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2569 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2571 realpath(spath.c_str(), tmppath1);
2572 realpath((*i).c_str(), tmppath2);
2574 if (strcmp(tmppath1, tmppath2) == 0) {
2581 unused.push_back (spath);
2585 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2587 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2588 struct stat statbuf;
2590 rep.paths.push_back (*x);
2591 if (stat ((*x).c_str(), &statbuf) == 0) {
2592 rep.space += statbuf.st_size;
2597 /* don't move the file across filesystems, just
2598 stick it in the `dead_sound_dir_name' directory
2599 on whichever filesystem it was already on.
2602 if ((*x).find ("/sounds/") != string::npos) {
2604 /* old school, go up 1 level */
2606 newpath = Glib::path_get_dirname (*x); // "sounds"
2607 newpath = Glib::path_get_dirname (newpath); // "session-name"
2611 /* new school, go up 4 levels */
2613 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2614 newpath = Glib::path_get_dirname (newpath); // "session-name"
2615 newpath = Glib::path_get_dirname (newpath); // "interchange"
2616 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2620 newpath += dead_sound_dir_name;
2622 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2623 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2628 newpath += Glib::path_get_basename ((*x));
2630 if (access (newpath.c_str(), F_OK) == 0) {
2632 /* the new path already exists, try versioning */
2634 char buf[PATH_MAX+1];
2638 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2641 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2642 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2646 if (version == 999) {
2647 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2651 newpath = newpath_v;
2656 /* it doesn't exist, or we can't read it or something */
2660 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2661 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2662 (*x), newpath, strerror (errno))
2667 /* see if there an easy to find peakfile for this file, and remove it.
2670 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2671 peakpath += peakfile_suffix;
2673 if (access (peakpath.c_str(), W_OK) == 0) {
2674 if (::unlink (peakpath.c_str()) != 0) {
2675 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2676 peakpath, _path, strerror (errno))
2678 /* try to back out */
2679 rename (newpath.c_str(), _path.c_str());
2687 /* dump the history list */
2691 /* save state so we don't end up a session file
2692 referring to non-existent sources.
2698 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2704 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2706 // FIXME: needs adaptation for MIDI
2708 vector<space_and_path>::iterator i;
2709 string dead_sound_dir;
2710 struct dirent* dentry;
2711 struct stat statbuf;
2717 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2719 dead_sound_dir = (*i).path;
2720 dead_sound_dir += dead_sound_dir_name;
2722 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2726 while ((dentry = readdir (dead)) != 0) {
2728 /* avoid '.' and '..' */
2730 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2731 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2737 fullpath = dead_sound_dir;
2739 fullpath += dentry->d_name;
2741 if (stat (fullpath.c_str(), &statbuf)) {
2745 if (!S_ISREG (statbuf.st_mode)) {
2749 if (unlink (fullpath.c_str())) {
2750 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2751 fullpath, strerror (errno))
2755 rep.paths.push_back (dentry->d_name);
2756 rep.space += statbuf.st_size;
2767 Session::set_dirty ()
2769 bool was_dirty = dirty();
2771 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2775 DirtyChanged(); /* EMIT SIGNAL */
2781 Session::set_clean ()
2783 bool was_dirty = dirty();
2785 _state_of_the_state = Clean;
2789 DirtyChanged(); /* EMIT SIGNAL */
2794 Session::set_deletion_in_progress ()
2796 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2800 Session::clear_deletion_in_progress ()
2802 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2806 Session::add_controllable (boost::shared_ptr<Controllable> c)
2808 /* this adds a controllable to the list managed by the Session.
2809 this is a subset of those managed by the Controllable class
2810 itself, and represents the only ones whose state will be saved
2811 as part of the session.
2814 Glib::Mutex::Lock lm (controllables_lock);
2815 controllables.insert (c);
2818 struct null_deleter { void operator()(void const *) const {} };
2821 Session::remove_controllable (Controllable* c)
2823 if (_state_of_the_state | Deletion) {
2827 Glib::Mutex::Lock lm (controllables_lock);
2829 Controllables::iterator x = controllables.find(
2830 boost::shared_ptr<Controllable>(c, null_deleter()));
2832 if (x != controllables.end()) {
2833 controllables.erase (x);
2837 boost::shared_ptr<Controllable>
2838 Session::controllable_by_id (const PBD::ID& id)
2840 Glib::Mutex::Lock lm (controllables_lock);
2842 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2843 if ((*i)->id() == id) {
2848 return boost::shared_ptr<Controllable>();
2852 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2854 Stateful::add_instant_xml (node, _path);
2855 if (write_to_config) {
2856 Config->add_instant_xml (node);
2861 Session::instant_xml (const string& node_name)
2863 return Stateful::instant_xml (node_name, _path);
2867 Session::save_history (string snapshot_name)
2871 if (snapshot_name.empty()) {
2872 snapshot_name = _current_snapshot_name;
2875 const string history_filename = snapshot_name + history_suffix;
2876 const string backup_filename = history_filename + backup_suffix;
2877 const sys::path xml_path = _session_dir->root_path() / history_filename;
2878 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2880 if (sys::exists (xml_path)) {
2883 sys::rename (xml_path, backup_path);
2885 catch (const sys::filesystem_error& err)
2887 error << _("could not backup old history file, current history not saved") << endmsg;
2893 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2897 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2899 if (!tree.write (xml_path.to_string()))
2901 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2905 sys::remove (xml_path);
2906 sys::rename (backup_path, xml_path);
2908 catch (const sys::filesystem_error& err)
2910 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2911 backup_path.to_string(), err.what()) << endmsg;
2921 Session::restore_history (string snapshot_name)
2925 if (snapshot_name.empty()) {
2926 snapshot_name = _current_snapshot_name;
2929 const string xml_filename = snapshot_name + history_suffix;
2930 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2932 cerr << "Loading history from " << xml_path.to_string() << endmsg;
2934 if (!sys::exists (xml_path)) {
2935 info << string_compose (_("%1: no history file \"%2\" for this session."),
2936 _name, xml_path.to_string()) << endmsg;
2940 if (!tree.read (xml_path.to_string())) {
2941 error << string_compose (_("Could not understand session history file \"%1\""),
2942 xml_path.to_string()) << endmsg;
2949 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2952 UndoTransaction* ut = new UndoTransaction ();
2955 ut->set_name(t->property("name")->value());
2956 stringstream ss(t->property("tv-sec")->value());
2958 ss.str(t->property("tv-usec")->value());
2960 ut->set_timestamp(tv);
2962 for (XMLNodeConstIterator child_it = t->children().begin();
2963 child_it != t->children().end(); child_it++)
2965 XMLNode *n = *child_it;
2968 if (n->name() == "MementoCommand" ||
2969 n->name() == "MementoUndoCommand" ||
2970 n->name() == "MementoRedoCommand") {
2972 if ((c = memento_command_factory(n))) {
2976 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2978 if ((c = global_state_command_factory (*n))) {
2979 ut->add_command (c);
2982 } else if (n->name() == "DeltaCommand") {
2983 PBD::ID id(n->property("midi-source")->value());
2984 boost::shared_ptr<MidiSource> midi_source =
2985 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2987 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
2989 error << "FIXME: Failed to downcast MidiSource for DeltaCommand" << endmsg;
2992 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3003 Session::config_changed (const char* parameter_name)
3005 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3007 if (PARAM_IS ("seamless-loop")) {
3009 } else if (PARAM_IS ("rf-speed")) {
3011 } else if (PARAM_IS ("auto-loop")) {
3013 } else if (PARAM_IS ("auto-input")) {
3015 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3016 /* auto-input only makes a difference if we're rolling */
3018 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3020 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3021 if ((*i)->record_enabled ()) {
3022 (*i)->monitor_input (!config.get_auto_input());
3027 } else if (PARAM_IS ("punch-in")) {
3031 if ((location = _locations.auto_punch_location()) != 0) {
3033 if (config.get_punch_in ()) {
3034 replace_event (Event::PunchIn, location->start());
3036 remove_event (location->start(), Event::PunchIn);
3040 } else if (PARAM_IS ("punch-out")) {
3044 if ((location = _locations.auto_punch_location()) != 0) {
3046 if (config.get_punch_out()) {
3047 replace_event (Event::PunchOut, location->end());
3049 clear_events (Event::PunchOut);
3053 } else if (PARAM_IS ("edit-mode")) {
3055 Glib::Mutex::Lock lm (playlist_lock);
3057 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3058 (*i)->set_edit_mode (Config->get_edit_mode ());
3061 } else if (PARAM_IS ("use-video-sync")) {
3063 waiting_for_sync_offset = Config->get_use_video_sync();
3065 } else if (PARAM_IS ("mmc-control")) {
3067 //poke_midi_thread ();
3069 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
3072 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3075 } else if (PARAM_IS ("mmc-send-id")) {
3078 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3081 } else if (PARAM_IS ("midi-control")) {
3083 //poke_midi_thread ();
3085 } else if (PARAM_IS ("raid-path")) {
3087 setup_raid_path (config.get_raid_path());
3089 } else if (PARAM_IS ("smpte-format")) {
3093 } else if (PARAM_IS ("video-pullup")) {
3097 } else if (PARAM_IS ("seamless-loop")) {
3099 if (play_loop && transport_rolling()) {
3100 // to reset diskstreams etc
3101 request_play_loop (true);
3104 } else if (PARAM_IS ("rf-speed")) {
3106 cumulative_rf_motion = 0;
3109 } else if (PARAM_IS ("click-sound")) {
3111 setup_click_sounds (1);
3113 } else if (PARAM_IS ("click-emphasis-sound")) {
3115 setup_click_sounds (-1);
3117 } else if (PARAM_IS ("clicking")) {
3119 if (Config->get_clicking()) {
3120 if (_click_io && click_data) { // don't require emphasis data
3127 } else if (PARAM_IS ("send-mtc")) {
3129 /* only set the internal flag if we have
3133 if (_mtc_port != 0) {
3134 session_send_mtc = Config->get_send_mtc();
3135 if (session_send_mtc) {
3136 /* mark us ready to send */
3137 next_quarter_frame_to_send = 0;
3140 session_send_mtc = false;
3143 } else if (PARAM_IS ("send-mmc")) {
3145 /* only set the internal flag if we have
3149 if (_mmc_port != 0) {
3150 session_send_mmc = Config->get_send_mmc();
3153 session_send_mmc = false;
3156 } else if (PARAM_IS ("midi-feedback")) {
3158 /* only set the internal flag if we have
3162 if (_mtc_port != 0) {
3163 session_midi_feedback = Config->get_midi_feedback();
3166 } else if (PARAM_IS ("jack-time-master")) {
3168 engine().reset_timebase ();
3170 } else if (PARAM_IS ("native-file-header-format")) {
3172 if (!first_file_header_format_reset) {
3173 reset_native_file_format ();
3176 first_file_header_format_reset = false;
3178 } else if (PARAM_IS ("native-file-data-format")) {
3180 if (!first_file_data_format_reset) {
3181 reset_native_file_format ();
3184 first_file_data_format_reset = false;
3186 } else if (PARAM_IS ("slave-source")) {
3187 set_slave_source (Config->get_slave_source());
3188 } else if (PARAM_IS ("remote-model")) {
3189 set_remote_control_ids ();
3190 } else if (PARAM_IS ("denormal-model")) {
3192 } else if (PARAM_IS ("history-depth")) {
3193 set_history_depth (Config->get_history_depth());
3194 } else if (PARAM_IS ("sync-all-route-ordering")) {
3195 sync_order_keys ("session");
3196 } else if (PARAM_IS ("initial-program-change")) {
3198 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3201 buf[0] = MIDI::program; // channel zero by default
3202 buf[1] = (Config->get_initial_program_change() & 0x7f);
3204 _mmc_port->midimsg (buf, sizeof (buf), 0);
3206 } else if (PARAM_IS ("initial-program-change")) {
3208 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3209 MIDI::byte* buf = new MIDI::byte[2];
3211 buf[0] = MIDI::program; // channel zero by default
3212 buf[1] = (Config->get_initial_program_change() & 0x7f);
3213 // deliver_midi (_mmc_port, buf, 2);
3215 } else if (PARAM_IS ("solo-mute-override")) {
3216 catch_up_on_solo_mute_override ();
3226 Session::set_history_depth (uint32_t d)
3228 _history.set_depth (d);