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.
22 #include "libardour-config.h"
25 #define __STDC_FORMAT_MACROS 1
34 #include <cstdio> /* snprintf(3) ... grrr */
49 #include <sys/param.h>
50 #include <sys/mount.h>
54 #include <glibmm/thread.h>
56 #include "midi++/mmc.h"
57 #include "midi++/port.h"
59 #include "pbd/boost_debug.h"
60 #include "pbd/controllable_descriptor.h"
61 #include "pbd/enumwriter.h"
62 #include "pbd/error.h"
63 #include "pbd/pathscanner.h"
64 #include "pbd/pthread_utils.h"
65 #include "pbd/search_path.h"
66 #include "pbd/stacktrace.h"
67 #include "pbd/convert.h"
69 #include "ardour/amp.h"
70 #include "ardour/audio_diskstream.h"
71 #include "ardour/audio_track.h"
72 #include "ardour/audioengine.h"
73 #include "ardour/audiofilesource.h"
74 #include "ardour/audioplaylist.h"
75 #include "ardour/audioregion.h"
76 #include "ardour/auditioner.h"
77 #include "ardour/buffer.h"
78 #include "ardour/butler.h"
79 #include "ardour/configuration.h"
80 #include "ardour/control_protocol_manager.h"
81 #include "ardour/crossfade.h"
82 #include "ardour/cycle_timer.h"
83 #include "ardour/directory_names.h"
84 #include "ardour/filename_extensions.h"
85 #include "ardour/io_processor.h"
86 #include "ardour/location.h"
87 #include "ardour/midi_diskstream.h"
88 #include "ardour/midi_patch_manager.h"
89 #include "ardour/midi_playlist.h"
90 #include "ardour/midi_region.h"
91 #include "ardour/midi_source.h"
92 #include "ardour/midi_track.h"
93 #include "ardour/named_selection.h"
94 #include "ardour/processor.h"
95 #include "ardour/region_factory.h"
96 #include "ardour/route_group.h"
97 #include "ardour/send.h"
98 #include "ardour/session.h"
99 #include "ardour/session_directory.h"
100 #include "ardour/session_metadata.h"
101 #include "ardour/session_state_utils.h"
102 #include "ardour/session_playlists.h"
103 #include "ardour/session_utils.h"
104 #include "ardour/silentfilesource.h"
105 #include "ardour/slave.h"
106 #include "ardour/smf_source.h"
107 #include "ardour/sndfile_helpers.h"
108 #include "ardour/sndfilesource.h"
109 #include "ardour/source_factory.h"
110 #include "ardour/template_utils.h"
111 #include "ardour/tempo.h"
112 #include "ardour/ticker.h"
113 #include "ardour/user_bundle.h"
114 #include "ardour/utils.h"
115 #include "ardour/utils.h"
116 #include "ardour/version.h"
117 #include "ardour/playlist_factory.h"
119 #include "control_protocol/control_protocol.h"
125 using namespace ARDOUR;
129 Session::first_stage_init (string fullpath, string snapshot_name)
131 if (fullpath.length() == 0) {
133 throw failed_constructor();
136 char buf[PATH_MAX+1];
137 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
138 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
140 throw failed_constructor();
145 if (_path[_path.length()-1] != '/') {
149 if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
155 /* these two are just provisional settings. set_state()
156 will likely override them.
159 _name = _current_snapshot_name = snapshot_name;
161 set_history_depth (Config->get_history_depth());
163 _current_frame_rate = _engine.frame_rate ();
164 _nominal_frame_rate = _current_frame_rate;
165 _base_frame_rate = _current_frame_rate;
167 _tempo_map = new TempoMap (_current_frame_rate);
168 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
171 _non_soloed_outs_muted = false;
173 _solo_isolated_cnt = 0;
174 g_atomic_int_set (&processing_prohibited, 0);
175 _transport_speed = 0;
176 _last_transport_speed = 0;
177 _target_transport_speed = 0;
178 auto_play_legal = false;
179 transport_sub_state = 0;
180 _transport_frame = 0;
181 _requested_return_frame = -1;
182 _session_range_location = 0;
183 g_atomic_int_set (&_record_status, Disabled);
184 loop_changing = false;
187 _last_roll_location = 0;
188 _last_roll_or_reversal_location = 0;
189 _last_record_location = 0;
190 pending_locate_frame = 0;
191 pending_locate_roll = false;
192 pending_locate_flush = false;
193 state_was_pending = false;
195 outbound_mtc_timecode_frame = 0;
196 next_quarter_frame_to_send = -1;
197 current_block_size = 0;
198 solo_update_disabled = false;
199 _have_captured = false;
200 _worst_output_latency = 0;
201 _worst_input_latency = 0;
202 _worst_track_latency = 0;
203 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
204 _was_seamless = Config->get_seamless_loop ();
206 session_send_mmc = false;
207 session_send_mtc = false;
208 g_atomic_int_set (&_playback_load, 100);
209 g_atomic_int_set (&_capture_load, 100);
212 pending_abort = false;
213 destructive_index = 0;
214 first_file_data_format_reset = true;
215 first_file_header_format_reset = true;
216 post_export_sync = false;
219 AudioDiskstream::allocate_working_buffers();
221 /* default short fade = 15ms */
223 Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
224 SndFileSource::setup_standard_crossfades (*this, frame_rate());
226 last_mmc_step.tv_sec = 0;
227 last_mmc_step.tv_usec = 0;
230 /* click sounds are unset by default, which causes us to internal
231 waveforms for clicks.
235 click_emphasis_length = 0;
238 process_function = &Session::process_with_events;
240 if (config.get_use_video_sync()) {
241 waiting_for_sync_offset = true;
243 waiting_for_sync_offset = false;
246 last_timecode_when = 0;
247 _timecode_offset = 0;
248 _timecode_offset_negative = true;
249 last_timecode_valid = false;
253 last_rr_session_dir = session_dirs.begin();
254 refresh_disk_space ();
256 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
260 average_slave_delta = 1800; // !!! why 1800 ????
261 have_first_delta_accumulator = false;
262 delta_accumulator_cnt = 0;
263 _slave_state = Stopped;
265 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
267 /* These are all static "per-class" signals */
269 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
270 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
271 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
272 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
273 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
275 /* stop IO objects from doing stuff until we're ready for them */
277 Delivery::disable_panners ();
278 IO::disable_connecting ();
282 Session::second_stage_init ()
284 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
287 if (load_state (_current_snapshot_name)) {
290 remove_empty_sounds ();
293 if (_butler->start_thread()) {
297 if (start_midi_thread ()) {
301 // set_state() will call setup_raid_path(), but if it's a new session we need
302 // to call setup_raid_path() here.
305 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
309 setup_raid_path(_path);
312 /* we can't save till after ::when_engine_running() is called,
313 because otherwise we save state with no connections made.
314 therefore, we reset _state_of_the_state because ::set_state()
315 will have cleared it.
317 we also have to include Loading so that any events that get
318 generated between here and the end of ::when_engine_running()
319 will be processed directly rather than queued.
322 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
325 _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
326 _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
327 setup_click_sounds (0);
328 setup_midi_control ();
330 /* Pay attention ... */
332 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
333 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
336 when_engine_running ();
339 /* handle this one in a different way than all others, so that its clear what happened */
341 catch (AudioEngine::PortRegistrationFailure& err) {
342 error << err.what() << endmsg;
350 BootMessage (_("Reset Remote Controls"));
352 send_full_time_code (0);
353 _engine.transport_locate (0);
354 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
355 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
357 MidiClockTicker::instance().set_session (this);
358 MIDI::Name::MidiPatchManager::instance().set_session (this);
360 /* initial program change will be delivered later; see ::config_changed() */
362 BootMessage (_("Reset Control Protocols"));
364 ControlProtocolManager::instance().set_session (this);
366 _state_of_the_state = Clean;
368 DirtyChanged (); /* EMIT SIGNAL */
370 if (state_was_pending) {
371 save_state (_current_snapshot_name);
372 remove_pending_capture_state ();
373 state_was_pending = false;
376 BootMessage (_("Session loading complete"));
382 Session::raid_path () const
384 SearchPath raid_search_path;
386 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
387 raid_search_path += sys::path((*i).path);
390 return raid_search_path.to_string ();
394 Session::setup_raid_path (string path)
403 session_dirs.clear ();
405 SearchPath search_path(path);
406 SearchPath sound_search_path;
407 SearchPath midi_search_path;
409 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
410 sp.path = (*i).to_string ();
411 sp.blocks = 0; // not needed
412 session_dirs.push_back (sp);
414 SessionDirectory sdir(sp.path);
416 sound_search_path += sdir.sound_path ();
417 midi_search_path += sdir.midi_path ();
420 // set the search path for each data type
421 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
422 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
424 // reset the round-robin soundfile path thingie
425 last_rr_session_dir = session_dirs.begin();
429 Session::path_is_within_session (const std::string& path)
431 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
432 if (path.find ((*i).path) == 0) {
440 Session::ensure_subdirs ()
444 dir = session_directory().peak_path().to_string();
446 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
447 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
451 dir = session_directory().sound_path().to_string();
453 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
454 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
458 dir = session_directory().midi_path().to_string();
460 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
461 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
465 dir = session_directory().dead_sound_path().to_string();
467 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
468 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
472 dir = session_directory().export_path().to_string();
474 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
475 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
479 dir = analysis_dir ();
481 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
482 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
490 Session::create (const string& mix_template, BusProfile* bus_profile)
493 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
494 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
498 if (ensure_subdirs ()) {
502 if (!mix_template.empty()) {
503 std::string in_path = mix_template;
505 ifstream in(in_path.c_str());
508 string out_path = _path;
510 out_path += statefile_suffix;
512 ofstream out(out_path.c_str());
520 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
526 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
533 /* Instantiate metadata */
535 _metadata = new SessionMetadata ();
537 /* set initial start + end point */
539 _state_of_the_state = Clean;
541 /* set up Master Out and Control Out if necessary */
547 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
549 if (bus_profile->master_out_channels) {
550 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
555 boost_debug_shared_ptr_mark_interesting (rt, "Route");
556 boost::shared_ptr<Route> r (rt);
557 r->input()->ensure_io (count, false, this);
558 r->output()->ensure_io (count, false, this);
559 r->set_remote_control_id (control_id++);
563 if (Config->get_use_monitor_bus()) {
564 Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO);
569 boost_debug_shared_ptr_mark_interesting (rt, "Route");
570 boost::shared_ptr<Route> r (rt);
571 r->input()->ensure_io (count, false, this);
572 r->output()->ensure_io (count, false, this);
573 r->set_remote_control_id (control_id);
579 /* prohibit auto-connect to master, because there isn't one */
580 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
584 add_routes (rl, false);
587 /* this allows the user to override settings with an environment variable.
590 if (no_auto_connect()) {
591 bus_profile->input_ac = AutoConnectOption (0);
592 bus_profile->output_ac = AutoConnectOption (0);
595 Config->set_input_auto_connect (bus_profile->input_ac);
596 Config->set_output_auto_connect (bus_profile->output_ac);
605 Session::maybe_write_autosave()
607 if (dirty() && record_status() != Recording) {
608 save_state("", true);
613 Session::remove_pending_capture_state ()
615 sys::path pending_state_file_path(_session_dir->root_path());
617 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
621 sys::remove (pending_state_file_path);
623 catch(sys::filesystem_error& ex)
625 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
626 pending_state_file_path.to_string(), ex.what()) << endmsg;
630 /** Rename a state file.
631 * @param snapshot_name Snapshot name.
634 Session::rename_state (string old_name, string new_name)
636 if (old_name == _current_snapshot_name || old_name == _name) {
637 /* refuse to rename the current snapshot or the "main" one */
641 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
642 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
644 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
645 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
649 sys::rename (old_xml_path, new_xml_path);
651 catch (const sys::filesystem_error& err)
653 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
654 old_name, new_name, err.what()) << endmsg;
658 /** Remove a state file.
659 * @param snapshot_name Snapshot name.
662 Session::remove_state (string snapshot_name)
664 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
665 // refuse to remove the current snapshot or the "main" one
669 sys::path xml_path(_session_dir->root_path());
671 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
673 if (!create_backup_file (xml_path)) {
674 // don't remove it if a backup can't be made
675 // create_backup_file will log the error.
680 sys::remove (xml_path);
683 #ifdef HAVE_JACK_SESSION
685 Session::jack_session_event (jack_session_event_t * event)
689 struct tm local_time;
692 localtime_r (&n, &local_time);
693 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
695 if (event->type == JackSessionSaveTemplate)
697 if (save_template( timebuf )) {
698 event->flags = JackSessionSaveError;
700 string cmd ("ardour3 -U ");
701 cmd += event->client_uuid;
705 event->command_line = strdup (cmd.c_str());
710 if (save_state (timebuf)) {
711 event->flags = JackSessionSaveError;
713 sys::path xml_path (_session_dir->root_path());
714 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
716 string cmd ("ardour3 -U ");
717 cmd += event->client_uuid;
719 cmd += xml_path.to_string();
722 event->command_line = strdup (cmd.c_str());
726 jack_session_reply (_engine.jack(), event);
728 if (event->type == JackSessionSaveAndQuit) {
729 // TODO: make ardour quit.
732 jack_session_event_free( event );
737 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
740 sys::path xml_path(_session_dir->root_path());
742 if (!_writable || (_state_of_the_state & CannotSave)) {
746 if (!_engine.connected ()) {
747 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
753 /* tell sources we're saving first, in case they write out to a new file
754 * which should be saved with the state rather than the old one */
755 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
756 i->second->session_saved();
759 tree.set_root (&get_state());
761 if (snapshot_name.empty()) {
762 snapshot_name = _current_snapshot_name;
763 } else if (switch_to_snapshot) {
764 _current_snapshot_name = snapshot_name;
769 /* proper save: use statefile_suffix (.ardour in English) */
771 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
773 /* make a backup copy of the old file */
775 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
776 // create_backup_file will log the error
782 /* pending save: use pending_suffix (.pending in English) */
783 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
786 sys::path tmp_path(_session_dir->root_path());
788 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
790 // cerr << "actually writing state to " << xml_path.to_string() << endl;
792 if (!tree.write (tmp_path.to_string())) {
793 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
794 sys::remove (tmp_path);
799 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
800 error << string_compose (_("could not rename temporary session file %1 to %2"),
801 tmp_path.to_string(), xml_path.to_string()) << endmsg;
802 sys::remove (tmp_path);
809 save_history (snapshot_name);
811 bool was_dirty = dirty();
813 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
816 DirtyChanged (); /* EMIT SIGNAL */
819 StateSaved (snapshot_name); /* EMIT SIGNAL */
826 Session::restore_state (string snapshot_name)
828 if (load_state (snapshot_name) == 0) {
829 set_state (*state_tree->root(), Stateful::loading_state_version);
836 Session::load_state (string snapshot_name)
841 state_was_pending = false;
843 /* check for leftover pending state from a crashed capture attempt */
845 sys::path xmlpath(_session_dir->root_path());
846 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
848 if (sys::exists (xmlpath)) {
850 /* there is pending state from a crashed capture attempt */
852 if (*AskAboutPendingState()) {
853 state_was_pending = true;
857 if (!state_was_pending) {
858 xmlpath = _session_dir->root_path();
859 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
862 if (!sys::exists (xmlpath)) {
863 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
867 state_tree = new XMLTree;
871 /* writable() really reflects the whole folder, but if for any
872 reason the session state file can't be written to, still
876 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
880 if (!state_tree->read (xmlpath.to_string())) {
881 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
887 XMLNode& root (*state_tree->root());
889 if (root.name() != X_("Session")) {
890 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
896 const XMLProperty* prop;
898 if ((prop = root.property ("version")) == 0) {
899 /* no version implies very old version of Ardour */
900 Stateful::loading_state_version = 1000;
906 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
907 Stateful::loading_state_version = (major * 1000) + minor;
910 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
912 sys::path backup_path(_session_dir->root_path());
914 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
916 // only create a backup once
917 if (sys::exists (backup_path)) {
921 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
922 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
927 sys::copy_file (xmlpath, backup_path);
929 catch(sys::filesystem_error& ex)
931 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
932 xmlpath.to_string(), ex.what())
942 Session::load_options (const XMLNode& node)
944 LocaleGuard lg (X_("POSIX"));
945 config.set_variables (node);
956 Session::get_template()
958 /* if we don't disable rec-enable, diskstreams
959 will believe they need to store their capture
960 sources in their state node.
963 disable_record (false);
969 Session::state(bool full_state)
971 XMLNode* node = new XMLNode("Session");
974 // store libardour version, just in case
976 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
977 node->add_property("version", string(buf));
979 /* store configuration settings */
983 node->add_property ("name", _name);
984 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
985 node->add_property ("sample-rate", buf);
987 if (session_dirs.size() > 1) {
991 vector<space_and_path>::iterator i = session_dirs.begin();
992 vector<space_and_path>::iterator next;
994 ++i; /* skip the first one */
998 while (i != session_dirs.end()) {
1002 if (next != session_dirs.end()) {
1012 child = node->add_child ("Path");
1013 child->add_content (p);
1017 /* save the ID counter */
1019 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1020 node->add_property ("id-counter", buf);
1022 /* various options */
1024 node->add_child_nocopy (config.get_variables ());
1026 node->add_child_nocopy (_metadata->get_state());
1028 child = node->add_child ("Sources");
1031 Glib::Mutex::Lock sl (source_lock);
1033 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1035 /* Don't save information about non-destructive file sources that are empty */
1036 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
1038 boost::shared_ptr<AudioFileSource> fs;
1039 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
1040 if (!fs->destructive()) {
1041 if (fs->length(fs->timeline_position()) == 0) {
1047 child->add_child_nocopy (siter->second->get_state());
1051 child = node->add_child ("Regions");
1054 Glib::Mutex::Lock rl (region_lock);
1055 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1056 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1057 boost::shared_ptr<Region> r = i->second;
1058 /* only store regions not attached to playlists */
1059 if (r->playlist() == 0) {
1060 child->add_child_nocopy (r->state (true));
1066 node->add_child_nocopy (_locations.get_state());
1068 // for a template, just create a new Locations, populate it
1069 // with the default start and end, and get the state for that.
1071 Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
1072 range->set (max_frames, 0);
1074 node->add_child_nocopy (loc.get_state());
1077 child = node->add_child ("Bundles");
1079 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1080 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1081 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1083 child->add_child_nocopy (b->get_state());
1088 child = node->add_child ("Routes");
1090 boost::shared_ptr<RouteList> r = routes.reader ();
1092 RoutePublicOrderSorter cmp;
1093 RouteList public_order (*r);
1094 public_order.sort (cmp);
1096 /* the sort should have put control outs first */
1099 assert (_monitor_out == public_order.front());
1102 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1103 if (!(*i)->is_hidden()) {
1105 child->add_child_nocopy ((*i)->get_state());
1107 child->add_child_nocopy ((*i)->get_template());
1113 playlists->add_state (node, full_state);
1115 child = node->add_child ("RouteGroups");
1116 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1117 child->add_child_nocopy ((*i)->get_state());
1121 child = node->add_child ("Click");
1122 child->add_child_nocopy (_click_io->state (full_state));
1126 child = node->add_child ("NamedSelections");
1127 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1129 child->add_child_nocopy ((*i)->get_state());
1134 node->add_child_nocopy (_tempo_map->get_state());
1136 node->add_child_nocopy (get_control_protocol_state());
1139 node->add_child_copy (*_extra_xml);
1146 Session::get_control_protocol_state ()
1148 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1149 return cpm.get_state();
1153 Session::set_state (const XMLNode& node, int version)
1157 const XMLProperty* prop;
1160 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1162 if (node.name() != X_("Session")){
1163 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1167 if ((prop = node.property ("version")) != 0) {
1168 version = atoi (prop->value ()) * 1000;
1171 if ((prop = node.property ("name")) != 0) {
1172 _name = prop->value ();
1175 if ((prop = node.property (X_("sample-rate"))) != 0) {
1177 _nominal_frame_rate = atoi (prop->value());
1179 if (_nominal_frame_rate != _current_frame_rate) {
1180 if (*AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1186 setup_raid_path(_session_dir->root_path().to_string());
1188 if ((prop = node.property (X_("id-counter"))) != 0) {
1190 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1191 ID::init_counter (x);
1193 /* old sessions used a timebased counter, so fake
1194 the startup ID counter based on a standard
1199 ID::init_counter (now);
1203 IO::disable_connecting ();
1205 /* Object loading order:
1210 MIDI Control // relies on data from Options/Config
1223 if ((child = find_named_node (node, "Extra")) != 0) {
1224 _extra_xml = new XMLNode (*child);
1227 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1228 load_options (*child);
1229 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1230 load_options (*child);
1232 error << _("Session: XML state has no options section") << endmsg;
1235 if (use_config_midi_ports ()) {
1238 if (version >= 3000) {
1239 if ((child = find_named_node (node, "Metadata")) == 0) {
1240 warning << _("Session: XML state has no metadata section") << endmsg;
1241 } else if (_metadata->set_state (*child, version)) {
1246 if ((child = find_named_node (node, "Locations")) == 0) {
1247 error << _("Session: XML state has no locations section") << endmsg;
1249 } else if (_locations.set_state (*child, version)) {
1255 if ((location = _locations.auto_loop_location()) != 0) {
1256 set_auto_loop_location (location);
1259 if ((location = _locations.auto_punch_location()) != 0) {
1260 set_auto_punch_location (location);
1263 if ((location = _locations.session_range_location()) != 0) {
1264 delete _session_range_location;
1265 _session_range_location = location;
1268 if (_session_range_location) {
1269 AudioFileSource::set_header_position_offset (_session_range_location->start());
1272 if ((child = find_named_node (node, "Sources")) == 0) {
1273 error << _("Session: XML state has no sources section") << endmsg;
1275 } else if (load_sources (*child)) {
1279 if ((child = find_named_node (node, "Regions")) == 0) {
1280 error << _("Session: XML state has no Regions section") << endmsg;
1282 } else if (load_regions (*child)) {
1286 if ((child = find_named_node (node, "Playlists")) == 0) {
1287 error << _("Session: XML state has no playlists section") << endmsg;
1289 } else if (playlists->load (*this, *child)) {
1293 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1295 } else if (playlists->load_unused (*this, *child)) {
1299 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1300 if (load_named_selections (*child)) {
1305 if (version >= 3000) {
1306 if ((child = find_named_node (node, "Bundles")) == 0) {
1307 warning << _("Session: XML state has no bundles section") << endmsg;
1310 /* We can't load Bundles yet as they need to be able
1311 to convert from port names to Port objects, which can't happen until
1313 _bundle_xml_node = new XMLNode (*child);
1317 if ((child = find_named_node (node, "TempoMap")) == 0) {
1318 error << _("Session: XML state has no Tempo Map section") << endmsg;
1320 } else if (_tempo_map->set_state (*child, version)) {
1324 if (version < 3000) {
1325 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1326 error << _("Session: XML state has no diskstreams section") << endmsg;
1328 } else if (load_diskstreams_2X (*child, version)) {
1333 if ((child = find_named_node (node, "Routes")) == 0) {
1334 error << _("Session: XML state has no routes section") << endmsg;
1336 } else if (load_routes (*child, version)) {
1340 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1341 _diskstreams_2X.clear ();
1343 if (version >= 3000) {
1345 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1346 error << _("Session: XML state has no route groups section") << endmsg;
1348 } else if (load_route_groups (*child, version)) {
1352 } else if (version < 3000) {
1354 if ((child = find_named_node (node, "EditGroups")) == 0) {
1355 error << _("Session: XML state has no edit groups section") << endmsg;
1357 } else if (load_route_groups (*child, version)) {
1361 if ((child = find_named_node (node, "MixGroups")) == 0) {
1362 error << _("Session: XML state has no mix groups section") << endmsg;
1364 } else if (load_route_groups (*child, version)) {
1369 if ((child = find_named_node (node, "Click")) == 0) {
1370 warning << _("Session: XML state has no click section") << endmsg;
1371 } else if (_click_io) {
1372 _click_io->set_state (*child, version);
1375 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1376 ControlProtocolManager::instance().set_protocol_states (*child);
1379 /* here beginneth the second phase ... */
1381 StateReady (); /* EMIT SIGNAL */
1390 Session::load_routes (const XMLNode& node, int version)
1393 XMLNodeConstIterator niter;
1394 RouteList new_routes;
1396 nlist = node.children();
1400 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1402 boost::shared_ptr<Route> route;
1403 if (version < 3000) {
1404 route = XMLRouteFactory_2X (**niter, version);
1406 route = XMLRouteFactory (**niter, version);
1410 error << _("Session: cannot create Route from XML description.") << endmsg;
1414 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1416 new_routes.push_back (route);
1419 add_routes (new_routes, false);
1424 boost::shared_ptr<Route>
1425 Session::XMLRouteFactory (const XMLNode& node, int version)
1427 boost::shared_ptr<Route> ret;
1429 if (node.name() != "Route") {
1433 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1435 DataType type = DataType::AUDIO;
1436 const XMLProperty* prop = node.property("default-type");
1439 type = DataType (prop->value());
1442 assert (type != DataType::NIL);
1448 if (type == DataType::AUDIO) {
1449 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1452 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1455 if (track->init()) {
1460 if (track->set_state (node, version)) {
1465 boost_debug_shared_ptr_mark_interesting (track, "Track");
1469 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1471 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1472 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1482 boost::shared_ptr<Route>
1483 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1485 boost::shared_ptr<Route> ret;
1487 if (node.name() != "Route") {
1491 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1493 ds_prop = node.property (X_("diskstream"));
1496 DataType type = DataType::AUDIO;
1497 const XMLProperty* prop = node.property("default-type");
1500 type = DataType (prop->value());
1503 assert (type != DataType::NIL);
1507 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1508 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1512 if (i == _diskstreams_2X.end()) {
1513 error << _("Could not find diskstream for route") << endmsg;
1514 return boost::shared_ptr<Route> ();
1519 if (type == DataType::AUDIO) {
1520 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1523 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1526 if (track->init()) {
1531 if (track->set_state (node, version)) {
1536 track->set_diskstream (*i);
1538 boost_debug_shared_ptr_mark_interesting (track, "Track");
1542 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1544 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1545 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1556 Session::load_regions (const XMLNode& node)
1559 XMLNodeConstIterator niter;
1560 boost::shared_ptr<Region> region;
1562 nlist = node.children();
1566 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1567 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1568 error << _("Session: cannot create Region from XML description.");
1569 const XMLProperty *name = (**niter).property("name");
1572 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1582 boost::shared_ptr<Region>
1583 Session::XMLRegionFactory (const XMLNode& node, bool full)
1585 const XMLProperty* type = node.property("type");
1589 if ( !type || type->value() == "audio" ) {
1591 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1593 } else if (type->value() == "midi") {
1595 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1599 } catch (failed_constructor& err) {
1600 return boost::shared_ptr<Region> ();
1603 return boost::shared_ptr<Region> ();
1606 boost::shared_ptr<AudioRegion>
1607 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1609 const XMLProperty* prop;
1610 boost::shared_ptr<Source> source;
1611 boost::shared_ptr<AudioSource> as;
1613 SourceList master_sources;
1614 uint32_t nchans = 1;
1617 if (node.name() != X_("Region")) {
1618 return boost::shared_ptr<AudioRegion>();
1621 if ((prop = node.property (X_("channels"))) != 0) {
1622 nchans = atoi (prop->value().c_str());
1625 if ((prop = node.property ("name")) == 0) {
1626 cerr << "no name for this region\n";
1630 if ((prop = node.property (X_("source-0"))) == 0) {
1631 if ((prop = node.property ("source")) == 0) {
1632 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1633 return boost::shared_ptr<AudioRegion>();
1637 PBD::ID s_id (prop->value());
1639 if ((source = source_by_id (s_id)) == 0) {
1640 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1641 return boost::shared_ptr<AudioRegion>();
1644 as = boost::dynamic_pointer_cast<AudioSource>(source);
1646 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1647 return boost::shared_ptr<AudioRegion>();
1650 sources.push_back (as);
1652 /* pickup other channels */
1654 for (uint32_t n=1; n < nchans; ++n) {
1655 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1656 if ((prop = node.property (buf)) != 0) {
1658 PBD::ID id2 (prop->value());
1660 if ((source = source_by_id (id2)) == 0) {
1661 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1662 return boost::shared_ptr<AudioRegion>();
1665 as = boost::dynamic_pointer_cast<AudioSource>(source);
1667 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1668 return boost::shared_ptr<AudioRegion>();
1670 sources.push_back (as);
1674 for (uint32_t n = 0; n < nchans; ++n) {
1675 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1676 if ((prop = node.property (buf)) != 0) {
1678 PBD::ID id2 (prop->value());
1680 if ((source = source_by_id (id2)) == 0) {
1681 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1682 return boost::shared_ptr<AudioRegion>();
1685 as = boost::dynamic_pointer_cast<AudioSource>(source);
1687 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1688 return boost::shared_ptr<AudioRegion>();
1690 master_sources.push_back (as);
1695 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1697 /* a final detail: this is the one and only place that we know how long missing files are */
1699 if (region->whole_file()) {
1700 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1701 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1703 sfp->set_length (region->length());
1708 if (!master_sources.empty()) {
1709 if (master_sources.size() != nchans) {
1710 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1712 region->set_master_sources (master_sources);
1720 catch (failed_constructor& err) {
1721 return boost::shared_ptr<AudioRegion>();
1725 boost::shared_ptr<MidiRegion>
1726 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1728 const XMLProperty* prop;
1729 boost::shared_ptr<Source> source;
1730 boost::shared_ptr<MidiSource> ms;
1732 uint32_t nchans = 1;
1734 if (node.name() != X_("Region")) {
1735 return boost::shared_ptr<MidiRegion>();
1738 if ((prop = node.property (X_("channels"))) != 0) {
1739 nchans = atoi (prop->value().c_str());
1742 if ((prop = node.property ("name")) == 0) {
1743 cerr << "no name for this region\n";
1747 // Multiple midi channels? that's just crazy talk
1748 assert(nchans == 1);
1750 if ((prop = node.property (X_("source-0"))) == 0) {
1751 if ((prop = node.property ("source")) == 0) {
1752 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1753 return boost::shared_ptr<MidiRegion>();
1757 PBD::ID s_id (prop->value());
1759 if ((source = source_by_id (s_id)) == 0) {
1760 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1761 return boost::shared_ptr<MidiRegion>();
1764 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1766 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1767 return boost::shared_ptr<MidiRegion>();
1770 sources.push_back (ms);
1773 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1774 /* a final detail: this is the one and only place that we know how long missing files are */
1776 if (region->whole_file()) {
1777 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1778 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1780 sfp->set_length (region->length());
1788 catch (failed_constructor& err) {
1789 return boost::shared_ptr<MidiRegion>();
1794 Session::get_sources_as_xml ()
1797 XMLNode* node = new XMLNode (X_("Sources"));
1798 Glib::Mutex::Lock lm (source_lock);
1800 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1801 node->add_child_nocopy (i->second->get_state());
1808 Session::path_from_region_name (DataType type, string name, string identifier)
1810 char buf[PATH_MAX+1];
1812 SessionDirectory sdir(get_best_session_directory_for_new_source());
1813 sys::path source_dir = ((type == DataType::AUDIO)
1814 ? sdir.sound_path() : sdir.midi_path());
1816 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1818 for (n = 0; n < 999999; ++n) {
1819 if (identifier.length()) {
1820 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1821 identifier.c_str(), n, ext.c_str());
1823 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1827 sys::path source_path = source_dir / buf;
1829 if (!sys::exists (source_path)) {
1830 return source_path.to_string();
1834 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1843 Session::load_sources (const XMLNode& node)
1846 XMLNodeConstIterator niter;
1847 boost::shared_ptr<Source> source;
1849 nlist = node.children();
1853 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1855 if ((source = XMLSourceFactory (**niter)) == 0) {
1856 error << _("Session: cannot create Source from XML description.") << endmsg;
1858 } catch (MissingSource& err) {
1859 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1860 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1867 boost::shared_ptr<Source>
1868 Session::XMLSourceFactory (const XMLNode& node)
1870 if (node.name() != "Source") {
1871 return boost::shared_ptr<Source>();
1875 /* note: do peak building in another thread when loading session state */
1876 return SourceFactory::create (*this, node, true);
1879 catch (failed_constructor& err) {
1880 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1881 return boost::shared_ptr<Source>();
1886 Session::save_template (string template_name)
1890 if (_state_of_the_state & CannotSave) {
1894 sys::path user_template_dir(user_template_directory());
1898 sys::create_directories (user_template_dir);
1900 catch(sys::filesystem_error& ex)
1902 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1903 user_template_dir.to_string(), ex.what()) << endmsg;
1907 tree.set_root (&get_template());
1909 sys::path template_file_path(user_template_dir);
1910 template_file_path /= template_name + template_suffix;
1912 if (sys::exists (template_file_path))
1914 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1915 template_file_path.to_string()) << endmsg;
1919 if (!tree.write (template_file_path.to_string())) {
1920 error << _("mix template not saved") << endmsg;
1928 Session::rename_template (string old_name, string new_name)
1930 sys::path old_path (user_template_directory());
1931 old_path /= old_name + template_suffix;
1933 sys::path new_path(user_template_directory());
1934 new_path /= new_name + template_suffix;
1936 if (sys::exists (new_path)) {
1937 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1938 new_path.to_string()) << endmsg;
1943 sys::rename (old_path, new_path);
1951 Session::delete_template (string name)
1953 sys::path path = user_template_directory();
1954 path /= name + template_suffix;
1965 Session::refresh_disk_space ()
1968 struct statfs statfsbuf;
1969 vector<space_and_path>::iterator i;
1970 Glib::Mutex::Lock lm (space_lock);
1973 /* get freespace on every FS that is part of the session path */
1975 _total_free_4k_blocks = 0;
1977 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1978 statfs ((*i).path.c_str(), &statfsbuf);
1980 scale = statfsbuf.f_bsize/4096.0;
1982 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1983 _total_free_4k_blocks += (*i).blocks;
1989 Session::get_best_session_directory_for_new_source ()
1991 vector<space_and_path>::iterator i;
1992 string result = _session_dir->root_path().to_string();
1994 /* handle common case without system calls */
1996 if (session_dirs.size() == 1) {
2000 /* OK, here's the algorithm we're following here:
2002 We want to select which directory to use for
2003 the next file source to be created. Ideally,
2004 we'd like to use a round-robin process so as to
2005 get maximum performance benefits from splitting
2006 the files across multiple disks.
2008 However, in situations without much diskspace, an
2009 RR approach may end up filling up a filesystem
2010 with new files while others still have space.
2011 Its therefore important to pay some attention to
2012 the freespace in the filesystem holding each
2013 directory as well. However, if we did that by
2014 itself, we'd keep creating new files in the file
2015 system with the most space until it was as full
2016 as all others, thus negating any performance
2017 benefits of this RAID-1 like approach.
2019 So, we use a user-configurable space threshold. If
2020 there are at least 2 filesystems with more than this
2021 much space available, we use RR selection between them.
2022 If not, then we pick the filesystem with the most space.
2024 This gets a good balance between the two
2028 refresh_disk_space ();
2030 int free_enough = 0;
2032 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2033 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2038 if (free_enough >= 2) {
2039 /* use RR selection process, ensuring that the one
2043 i = last_rr_session_dir;
2046 if (++i == session_dirs.end()) {
2047 i = session_dirs.begin();
2050 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2051 if (create_session_directory ((*i).path)) {
2053 last_rr_session_dir = i;
2058 } while (i != last_rr_session_dir);
2062 /* pick FS with the most freespace (and that
2063 seems to actually work ...)
2066 vector<space_and_path> sorted;
2067 space_and_path_ascending_cmp cmp;
2069 sorted = session_dirs;
2070 sort (sorted.begin(), sorted.end(), cmp);
2072 for (i = sorted.begin(); i != sorted.end(); ++i) {
2073 if (create_session_directory ((*i).path)) {
2075 last_rr_session_dir = i;
2085 Session::load_named_selections (const XMLNode& node)
2088 XMLNodeConstIterator niter;
2091 nlist = node.children();
2095 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2097 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2098 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2106 Session::XMLNamedSelectionFactory (const XMLNode& node)
2109 return new NamedSelection (*this, node);
2112 catch (failed_constructor& err) {
2118 Session::automation_dir () const
2120 return Glib::build_filename (_path, "automation");
2124 Session::analysis_dir () const
2126 return Glib::build_filename (_path, "analysis");
2130 Session::load_bundles (XMLNode const & node)
2132 XMLNodeList nlist = node.children();
2133 XMLNodeConstIterator niter;
2137 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2138 if ((*niter)->name() == "InputBundle") {
2139 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2140 } else if ((*niter)->name() == "OutputBundle") {
2141 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2143 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2152 Session::load_route_groups (const XMLNode& node, int version)
2154 XMLNodeList nlist = node.children();
2155 XMLNodeConstIterator niter;
2159 if (version >= 3000) {
2161 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2162 if ((*niter)->name() == "RouteGroup") {
2163 RouteGroup* rg = new RouteGroup (*this, "");
2164 add_route_group (rg);
2165 rg->set_state (**niter, version);
2169 } else if (version < 3000) {
2171 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2172 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2173 RouteGroup* rg = new RouteGroup (*this, "");
2174 add_route_group (rg);
2175 rg->set_state (**niter, version);
2184 Session::auto_save()
2186 save_state (_current_snapshot_name);
2190 state_file_filter (const string &str, void */*arg*/)
2192 return (str.length() > strlen(statefile_suffix) &&
2193 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2197 bool operator()(const string* a, const string* b) {
2203 remove_end(string* state)
2205 string statename(*state);
2207 string::size_type start,end;
2208 if ((start = statename.find_last_of ('/')) != string::npos) {
2209 statename = statename.substr (start+1);
2212 if ((end = statename.rfind(".ardour")) == string::npos) {
2213 end = statename.length();
2216 return new string(statename.substr (0, end));
2220 Session::possible_states (string path)
2222 PathScanner scanner;
2223 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2225 transform(states->begin(), states->end(), states->begin(), remove_end);
2228 sort (states->begin(), states->end(), cmp);
2234 Session::possible_states () const
2236 return possible_states(_path);
2240 Session::add_route_group (RouteGroup* g)
2242 _route_groups.push_back (g);
2243 route_group_added (g); /* EMIT SIGNAL */
2248 Session::remove_route_group (RouteGroup& rg)
2250 list<RouteGroup*>::iterator i;
2252 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2253 _route_groups.erase (i);
2256 route_group_removed (); /* EMIT SIGNAL */
2262 Session::route_group_by_name (string name)
2264 list<RouteGroup *>::iterator i;
2266 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2267 if ((*i)->name() == name) {
2275 Session::start_reversible_command (const string& name)
2277 UndoTransaction* trans = new UndoTransaction();
2278 trans->set_name(name);
2283 Session::finish_reversible_command (UndoTransaction& ut)
2286 gettimeofday(&now, 0);
2287 ut.set_timestamp(now);
2292 Session::begin_reversible_command(const string& name)
2294 UndoTransaction* trans = new UndoTransaction();
2295 trans->set_name(name);
2297 if (!_current_trans.empty()) {
2298 _current_trans.top()->add_command (trans);
2300 _current_trans.push(trans);
2305 Session::commit_reversible_command(Command *cmd)
2307 assert(!_current_trans.empty());
2311 _current_trans.top()->add_command(cmd);
2314 if (_current_trans.top()->empty()) {
2315 _current_trans.pop();
2319 gettimeofday(&now, 0);
2320 _current_trans.top()->set_timestamp(now);
2322 _history.add(_current_trans.top());
2323 _current_trans.pop();
2327 accept_all_non_peak_files (const string& path, void */*arg*/)
2329 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2333 accept_all_state_files (const string& path, void */*arg*/)
2335 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2339 Session::find_all_sources (string path, set<string>& result)
2344 if (!tree.read (path)) {
2348 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2353 XMLNodeConstIterator niter;
2355 nlist = node->children();
2359 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2363 if ((prop = (*niter)->property (X_("type"))) == 0) {
2367 DataType type (prop->value());
2369 if ((prop = (*niter)->property (X_("name"))) == 0) {
2373 if (prop->value()[0] == '/') {
2374 /* external file, ignore */
2378 Glib::ustring found_path;
2382 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2383 result.insert (found_path);
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 += legalize_for_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::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2443 return *AskAboutPlaylistDeletion (p);
2447 Session::cleanup_sources (CleanupReport& rep)
2449 // FIXME: needs adaptation to midi
2451 vector<boost::shared_ptr<Source> > dead_sources;
2452 PathScanner scanner;
2454 vector<space_and_path>::iterator i;
2455 vector<space_and_path>::iterator nexti;
2456 vector<string*>* soundfiles;
2457 vector<string> unused;
2458 set<string> all_sources;
2463 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2465 /* step 1: consider deleting all unused playlists */
2467 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2472 /* step 2: find all un-used sources */
2477 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2479 SourceMap::iterator tmp;
2484 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2488 if (!playlists->source_use_count(i->second) && i->second->length(i->second->timeline_position()) > 0) {
2489 dead_sources.push_back (i->second);
2490 i->second->drop_references ();
2496 /* build a list of all the possible sound directories for the session */
2498 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2503 SessionDirectory sdir ((*i).path);
2504 sound_path += sdir.sound_path().to_string();
2506 if (nexti != session_dirs.end()) {
2513 /* now do the same thing for the files that ended up in the sounds dir(s)
2514 but are not referenced as sources in any snapshot.
2517 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2519 if (soundfiles == 0) {
2523 /* find all sources, but don't use this snapshot because the
2524 state file on disk still references sources we may have already
2528 find_all_sources_across_snapshots (all_sources, true);
2530 /* add our current source list
2533 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2534 boost::shared_ptr<FileSource> fs;
2536 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2537 all_sources.insert (fs->path());
2541 char tmppath1[PATH_MAX+1];
2542 char tmppath2[PATH_MAX+1];
2544 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2549 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2551 realpath(spath.c_str(), tmppath1);
2552 realpath((*i).c_str(), tmppath2);
2554 if (strcmp(tmppath1, tmppath2) == 0) {
2561 unused.push_back (spath);
2565 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2567 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2568 struct stat statbuf;
2570 rep.paths.push_back (*x);
2571 if (stat ((*x).c_str(), &statbuf) == 0) {
2572 rep.space += statbuf.st_size;
2577 /* don't move the file across filesystems, just
2578 stick it in the `dead_sound_dir_name' directory
2579 on whichever filesystem it was already on.
2582 if ((*x).find ("/sounds/") != string::npos) {
2584 /* old school, go up 1 level */
2586 newpath = Glib::path_get_dirname (*x); // "sounds"
2587 newpath = Glib::path_get_dirname (newpath); // "session-name"
2591 /* new school, go up 4 levels */
2593 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2594 newpath = Glib::path_get_dirname (newpath); // "session-name"
2595 newpath = Glib::path_get_dirname (newpath); // "interchange"
2596 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2600 newpath += dead_sound_dir_name;
2602 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2603 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2608 newpath += Glib::path_get_basename ((*x));
2610 if (access (newpath.c_str(), F_OK) == 0) {
2612 /* the new path already exists, try versioning */
2614 char buf[PATH_MAX+1];
2618 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2621 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2622 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2626 if (version == 999) {
2627 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2631 newpath = newpath_v;
2636 /* it doesn't exist, or we can't read it or something */
2640 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2641 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2642 (*x), newpath, strerror (errno))
2647 /* see if there an easy to find peakfile for this file, and remove it.
2650 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2651 peakpath += peakfile_suffix;
2653 if (access (peakpath.c_str(), W_OK) == 0) {
2654 if (::unlink (peakpath.c_str()) != 0) {
2655 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2656 peakpath, _path, strerror (errno))
2658 /* try to back out */
2659 rename (newpath.c_str(), _path.c_str());
2667 /* dump the history list */
2671 /* save state so we don't end up a session file
2672 referring to non-existent sources.
2678 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2684 Session::cleanup_trash_sources (CleanupReport& rep)
2686 // FIXME: needs adaptation for MIDI
2688 vector<space_and_path>::iterator i;
2689 string dead_sound_dir;
2690 struct dirent* dentry;
2691 struct stat statbuf;
2697 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2699 dead_sound_dir = (*i).path;
2700 dead_sound_dir += dead_sound_dir_name;
2702 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2706 while ((dentry = readdir (dead)) != 0) {
2708 /* avoid '.' and '..' */
2710 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2711 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2717 fullpath = dead_sound_dir;
2719 fullpath += dentry->d_name;
2721 if (stat (fullpath.c_str(), &statbuf)) {
2725 if (!S_ISREG (statbuf.st_mode)) {
2729 if (unlink (fullpath.c_str())) {
2730 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2731 fullpath, strerror (errno))
2735 rep.paths.push_back (dentry->d_name);
2736 rep.space += statbuf.st_size;
2747 Session::set_dirty ()
2749 bool was_dirty = dirty();
2751 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2755 DirtyChanged(); /* EMIT SIGNAL */
2761 Session::set_clean ()
2763 bool was_dirty = dirty();
2765 _state_of_the_state = Clean;
2769 DirtyChanged(); /* EMIT SIGNAL */
2774 Session::set_deletion_in_progress ()
2776 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2780 Session::clear_deletion_in_progress ()
2782 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2786 Session::add_controllable (boost::shared_ptr<Controllable> c)
2788 /* this adds a controllable to the list managed by the Session.
2789 this is a subset of those managed by the Controllable class
2790 itself, and represents the only ones whose state will be saved
2791 as part of the session.
2794 Glib::Mutex::Lock lm (controllables_lock);
2795 controllables.insert (c);
2798 struct null_deleter { void operator()(void const *) const {} };
2801 Session::remove_controllable (Controllable* c)
2803 if (_state_of_the_state | Deletion) {
2807 Glib::Mutex::Lock lm (controllables_lock);
2809 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2811 if (x != controllables.end()) {
2812 controllables.erase (x);
2816 boost::shared_ptr<Controllable>
2817 Session::controllable_by_id (const PBD::ID& id)
2819 Glib::Mutex::Lock lm (controllables_lock);
2821 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2822 if ((*i)->id() == id) {
2827 return boost::shared_ptr<Controllable>();
2830 boost::shared_ptr<Controllable>
2831 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2833 boost::shared_ptr<Controllable> c;
2834 boost::shared_ptr<Route> r;
2836 switch (desc.top_level_type()) {
2837 case ControllableDescriptor::NamedRoute:
2839 std::string str = desc.top_level_name();
2840 if (str == "master") {
2842 } else if (str == "control" || str == "listen") {
2845 r = route_by_name (desc.top_level_name());
2850 case ControllableDescriptor::RemoteControlID:
2851 r = route_by_remote_id (desc.rid());
2859 switch (desc.subtype()) {
2860 case ControllableDescriptor::Gain:
2861 c = r->gain_control ();
2864 case ControllableDescriptor::Solo:
2865 c = r->solo_control();
2868 case ControllableDescriptor::Mute:
2869 c = r->mute_control();
2872 case ControllableDescriptor::Recenable:
2874 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2877 c = t->rec_enable_control ();
2882 case ControllableDescriptor::Pan:
2883 /* XXX pan control */
2886 case ControllableDescriptor::Balance:
2887 /* XXX simple pan control */
2890 case ControllableDescriptor::PluginParameter:
2892 uint32_t plugin = desc.target (0);
2893 uint32_t parameter_index = desc.target (1);
2895 /* revert to zero based counting */
2901 if (parameter_index > 0) {
2905 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
2908 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
2909 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
2914 case ControllableDescriptor::SendGain:
2916 uint32_t send = desc.target (0);
2918 /* revert to zero-based counting */
2924 boost::shared_ptr<Processor> p = r->nth_send (send);
2927 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
2928 boost::shared_ptr<Amp> a = s->amp();
2931 c = s->amp()->gain_control();
2938 /* relax and return a null pointer */
2946 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2949 Stateful::add_instant_xml (node, _path);
2952 if (write_to_config) {
2953 Config->add_instant_xml (node);
2958 Session::instant_xml (const string& node_name)
2960 return Stateful::instant_xml (node_name, _path);
2964 Session::save_history (string snapshot_name)
2972 if (snapshot_name.empty()) {
2973 snapshot_name = _current_snapshot_name;
2976 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2977 const string backup_filename = history_filename + backup_suffix;
2978 const sys::path xml_path = _session_dir->root_path() / history_filename;
2979 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2981 if (sys::exists (xml_path)) {
2984 sys::rename (xml_path, backup_path);
2986 catch (const sys::filesystem_error& err)
2988 error << _("could not backup old history file, current history not saved") << endmsg;
2993 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2997 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2999 if (!tree.write (xml_path.to_string()))
3001 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3005 sys::remove (xml_path);
3006 sys::rename (backup_path, xml_path);
3008 catch (const sys::filesystem_error& err)
3010 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3011 backup_path.to_string(), err.what()) << endmsg;
3021 Session::restore_history (string snapshot_name)
3025 if (snapshot_name.empty()) {
3026 snapshot_name = _current_snapshot_name;
3029 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3030 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3032 info << "Loading history from " << xml_path.to_string() << endmsg;
3034 if (!sys::exists (xml_path)) {
3035 info << string_compose (_("%1: no history file \"%2\" for this session."),
3036 _name, xml_path.to_string()) << endmsg;
3040 if (!tree.read (xml_path.to_string())) {
3041 error << string_compose (_("Could not understand session history file \"%1\""),
3042 xml_path.to_string()) << endmsg;
3049 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3052 UndoTransaction* ut = new UndoTransaction ();
3055 ut->set_name(t->property("name")->value());
3056 stringstream ss(t->property("tv-sec")->value());
3058 ss.str(t->property("tv-usec")->value());
3060 ut->set_timestamp(tv);
3062 for (XMLNodeConstIterator child_it = t->children().begin();
3063 child_it != t->children().end(); child_it++)
3065 XMLNode *n = *child_it;
3068 if (n->name() == "MementoCommand" ||
3069 n->name() == "MementoUndoCommand" ||
3070 n->name() == "MementoRedoCommand") {
3072 if ((c = memento_command_factory(n))) {
3076 } else if (n->name() == "DeltaCommand") {
3077 PBD::ID id(n->property("midi-source")->value());
3078 boost::shared_ptr<MidiSource> midi_source =
3079 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3081 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
3083 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
3086 } else if (n->name() == "DiffCommand") {
3087 PBD::ID id(n->property("midi-source")->value());
3088 boost::shared_ptr<MidiSource> midi_source =
3089 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3091 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
3093 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
3096 } else if (n->name() == "StatefulDiffCommand") {
3097 if ((c = stateful_diff_command_factory (n))) {
3098 ut->add_command (c);
3101 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3112 Session::config_changed (std::string p, bool ours)
3118 if (p == "seamless-loop") {
3120 } else if (p == "rf-speed") {
3122 } else if (p == "auto-loop") {
3124 } else if (p == "auto-input") {
3126 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3127 /* auto-input only makes a difference if we're rolling */
3129 boost::shared_ptr<RouteList> rl = routes.reader ();
3130 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3131 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3132 if (tr && tr->record_enabled ()) {
3133 tr->monitor_input (!config.get_auto_input());
3138 } else if (p == "punch-in") {
3142 if ((location = _locations.auto_punch_location()) != 0) {
3144 if (config.get_punch_in ()) {
3145 replace_event (SessionEvent::PunchIn, location->start());
3147 remove_event (location->start(), SessionEvent::PunchIn);
3151 } else if (p == "punch-out") {
3155 if ((location = _locations.auto_punch_location()) != 0) {
3157 if (config.get_punch_out()) {
3158 replace_event (SessionEvent::PunchOut, location->end());
3160 clear_events (SessionEvent::PunchOut);
3164 } else if (p == "edit-mode") {
3166 Glib::Mutex::Lock lm (playlists->lock);
3168 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3169 (*i)->set_edit_mode (Config->get_edit_mode ());
3172 } else if (p == "use-video-sync") {
3174 waiting_for_sync_offset = config.get_use_video_sync();
3176 } else if (p == "mmc-control") {
3178 //poke_midi_thread ();
3180 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3183 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3186 } else if (p == "mmc-send-id") {
3189 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3192 } else if (p == "midi-control") {
3194 //poke_midi_thread ();
3196 } else if (p == "raid-path") {
3198 setup_raid_path (config.get_raid_path());
3200 } else if (p == "timecode-format") {
3204 } else if (p == "video-pullup") {
3208 } else if (p == "seamless-loop") {
3210 if (play_loop && transport_rolling()) {
3211 // to reset diskstreams etc
3212 request_play_loop (true);
3215 } else if (p == "rf-speed") {
3217 cumulative_rf_motion = 0;
3220 } else if (p == "click-sound") {
3222 setup_click_sounds (1);
3224 } else if (p == "click-emphasis-sound") {
3226 setup_click_sounds (-1);
3228 } else if (p == "clicking") {
3230 if (Config->get_clicking()) {
3231 if (_click_io && click_data) { // don't require emphasis data
3238 } else if (p == "send-mtc") {
3240 /* only set the internal flag if we have
3244 if (_mtc_port != 0) {
3245 session_send_mtc = Config->get_send_mtc();
3246 if (session_send_mtc) {
3247 /* mark us ready to send */
3248 next_quarter_frame_to_send = 0;
3251 session_send_mtc = false;
3254 } else if (p == "send-mmc") {
3256 /* only set the internal flag if we have
3260 if (_mmc_port != 0) {
3261 session_send_mmc = Config->get_send_mmc();
3264 session_send_mmc = false;
3267 } else if (p == "midi-feedback") {
3269 /* only set the internal flag if we have
3273 if (_mtc_port != 0) {
3274 session_midi_feedback = Config->get_midi_feedback();
3277 } else if (p == "jack-time-master") {
3279 engine().reset_timebase ();
3281 } else if (p == "native-file-header-format") {
3283 if (!first_file_header_format_reset) {
3284 reset_native_file_format ();
3287 first_file_header_format_reset = false;
3289 } else if (p == "native-file-data-format") {
3291 if (!first_file_data_format_reset) {
3292 reset_native_file_format ();
3295 first_file_data_format_reset = false;
3297 } else if (p == "external-sync") {
3298 if (!config.get_external_sync()) {
3299 drop_sync_source ();
3301 switch_to_sync_source (config.get_sync_source());
3303 } else if (p == "remote-model") {
3304 set_remote_control_ids ();
3305 } else if (p == "denormal-model") {
3307 } else if (p == "history-depth") {
3308 set_history_depth (Config->get_history_depth());
3309 } else if (p == "sync-all-route-ordering") {
3310 sync_order_keys ("session");
3311 } else if (p == "initial-program-change") {
3313 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3316 buf[0] = MIDI::program; // channel zero by default
3317 buf[1] = (Config->get_initial_program_change() & 0x7f);
3319 _mmc_port->midimsg (buf, sizeof (buf), 0);
3321 } else if (p == "initial-program-change") {
3323 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3324 MIDI::byte* buf = new MIDI::byte[2];
3326 buf[0] = MIDI::program; // channel zero by default
3327 buf[1] = (Config->get_initial_program_change() & 0x7f);
3328 // deliver_midi (_mmc_port, buf, 2);
3330 } else if (p == "solo-mute-override") {
3331 // catch_up_on_solo_mute_override ();
3332 } else if (p == "listen-position") {
3333 listen_position_changed ();
3334 } else if (p == "solo-control-is-listen-control") {
3335 solo_control_mode_changed ();
3343 Session::set_history_depth (uint32_t d)
3345 _history.set_depth (d);
3349 Session::load_diskstreams_2X (XMLNode const & node, int)
3352 XMLNodeConstIterator citer;
3354 clist = node.children();
3356 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3359 /* diskstreams added automatically by DiskstreamCreated handler */
3360 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3361 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3362 _diskstreams_2X.push_back (dsp);
3364 error << _("Session: unknown diskstream type in XML") << endmsg;
3368 catch (failed_constructor& err) {
3369 error << _("Session: could not load diskstream via XML state") << endmsg;