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 */
48 #include <sys/param.h>
49 #include <sys/mount.h>
53 #include <glibmm/thread.h>
55 #include "midi++/mmc.h"
56 #include "midi++/port.h"
57 #include "midi++/manager.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"
68 #include "pbd/clear_dir.h"
70 #include "ardour/amp.h"
71 #include "ardour/audio_diskstream.h"
72 #include "ardour/audio_track.h"
73 #include "ardour/audioengine.h"
74 #include "ardour/audiofilesource.h"
75 #include "ardour/audioplaylist.h"
76 #include "ardour/audioregion.h"
77 #include "ardour/auditioner.h"
78 #include "ardour/buffer.h"
79 #include "ardour/butler.h"
80 #include "ardour/configuration.h"
81 #include "ardour/control_protocol_manager.h"
82 #include "ardour/crossfade.h"
83 #include "ardour/cycle_timer.h"
84 #include "ardour/directory_names.h"
85 #include "ardour/filename_extensions.h"
86 #include "ardour/io_processor.h"
87 #include "ardour/location.h"
88 #include "ardour/midi_diskstream.h"
89 #include "ardour/midi_patch_manager.h"
90 #include "ardour/midi_playlist.h"
91 #include "ardour/midi_region.h"
92 #include "ardour/midi_source.h"
93 #include "ardour/midi_track.h"
94 #include "ardour/named_selection.h"
95 #include "ardour/processor.h"
96 #include "ardour/port.h"
97 #include "ardour/region_factory.h"
98 #include "ardour/route_group.h"
99 #include "ardour/send.h"
100 #include "ardour/session.h"
101 #include "ardour/session_directory.h"
102 #include "ardour/session_metadata.h"
103 #include "ardour/session_state_utils.h"
104 #include "ardour/session_playlists.h"
105 #include "ardour/session_utils.h"
106 #include "ardour/silentfilesource.h"
107 #include "ardour/slave.h"
108 #include "ardour/smf_source.h"
109 #include "ardour/sndfile_helpers.h"
110 #include "ardour/sndfilesource.h"
111 #include "ardour/source_factory.h"
112 #include "ardour/template_utils.h"
113 #include "ardour/tempo.h"
114 #include "ardour/ticker.h"
115 #include "ardour/user_bundle.h"
116 #include "ardour/utils.h"
117 #include "ardour/utils.h"
118 #include "ardour/version.h"
119 #include "ardour/playlist_factory.h"
121 #include "control_protocol/control_protocol.h"
127 using namespace ARDOUR;
131 Session::first_stage_init (string fullpath, string snapshot_name)
133 if (fullpath.length() == 0) {
135 throw failed_constructor();
138 char buf[PATH_MAX+1];
139 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
140 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
142 throw failed_constructor();
147 if (_path[_path.length()-1] != '/') {
151 if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
157 /* these two are just provisional settings. set_state()
158 will likely override them.
161 _name = _current_snapshot_name = snapshot_name;
163 set_history_depth (Config->get_history_depth());
165 _current_frame_rate = _engine.frame_rate ();
166 _nominal_frame_rate = _current_frame_rate;
167 _base_frame_rate = _current_frame_rate;
169 _tempo_map = new TempoMap (_current_frame_rate);
170 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
173 _non_soloed_outs_muted = false;
175 _solo_isolated_cnt = 0;
176 g_atomic_int_set (&processing_prohibited, 0);
177 _transport_speed = 0;
178 _last_transport_speed = 0;
179 _target_transport_speed = 0;
180 auto_play_legal = false;
181 transport_sub_state = 0;
182 _transport_frame = 0;
183 _requested_return_frame = -1;
184 _session_range_location = 0;
185 g_atomic_int_set (&_record_status, Disabled);
186 loop_changing = false;
189 _last_roll_location = 0;
190 _last_roll_or_reversal_location = 0;
191 _last_record_location = 0;
192 pending_locate_frame = 0;
193 pending_locate_roll = false;
194 pending_locate_flush = false;
195 state_was_pending = false;
197 outbound_mtc_timecode_frame = 0;
198 next_quarter_frame_to_send = -1;
199 current_block_size = 0;
200 solo_update_disabled = false;
201 _have_captured = false;
202 _worst_output_latency = 0;
203 _worst_input_latency = 0;
204 _worst_track_latency = 0;
205 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
206 _was_seamless = Config->get_seamless_loop ();
208 session_send_mtc = false;
209 g_atomic_int_set (&_playback_load, 100);
210 g_atomic_int_set (&_capture_load, 100);
213 pending_abort = false;
214 destructive_index = 0;
215 first_file_data_format_reset = true;
216 first_file_header_format_reset = true;
217 post_export_sync = false;
220 AudioDiskstream::allocate_working_buffers();
222 /* default short fade = 15ms */
224 Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
225 SndFileSource::setup_standard_crossfades (*this, frame_rate());
227 last_mmc_step.tv_sec = 0;
228 last_mmc_step.tv_usec = 0;
231 /* click sounds are unset by default, which causes us to internal
232 waveforms for clicks.
236 click_emphasis_length = 0;
239 process_function = &Session::process_with_events;
241 if (config.get_use_video_sync()) {
242 waiting_for_sync_offset = true;
244 waiting_for_sync_offset = false;
247 last_timecode_when = 0;
248 _timecode_offset = 0;
249 _timecode_offset_negative = true;
250 last_timecode_valid = false;
254 last_rr_session_dir = session_dirs.begin();
255 refresh_disk_space ();
257 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
261 average_slave_delta = 1800; // !!! why 1800 ????
262 have_first_delta_accumulator = false;
263 delta_accumulator_cnt = 0;
264 _slave_state = Stopped;
266 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
268 /* These are all static "per-class" signals */
270 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
271 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
272 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
273 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
274 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
276 /* stop IO objects from doing stuff until we're ready for them */
278 Delivery::disable_panners ();
279 IO::disable_connecting ();
283 Session::second_stage_init ()
285 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
288 if (load_state (_current_snapshot_name)) {
291 cleanup_stubfiles ();
294 if (_butler->start_thread()) {
298 if (start_midi_thread ()) {
302 setup_midi_machine_control ();
304 // set_state() will call setup_raid_path(), but if it's a new session we need
305 // to call setup_raid_path() here.
308 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
312 setup_raid_path(_path);
315 /* we can't save till after ::when_engine_running() is called,
316 because otherwise we save state with no connections made.
317 therefore, we reset _state_of_the_state because ::set_state()
318 will have cleared it.
320 we also have to include Loading so that any events that get
321 generated between here and the end of ::when_engine_running()
322 will be processed directly rather than queued.
325 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
327 _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
328 _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
329 setup_click_sounds (0);
330 setup_midi_control ();
332 /* Pay attention ... */
334 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
335 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
338 when_engine_running ();
341 /* handle this one in a different way than all others, so that its clear what happened */
343 catch (AudioEngine::PortRegistrationFailure& err) {
344 error << err.what() << endmsg;
352 BootMessage (_("Reset Remote Controls"));
354 send_full_time_code (0);
355 _engine.transport_locate (0);
357 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
358 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
360 MidiClockTicker::instance().set_session (this);
361 MIDI::Name::MidiPatchManager::instance().set_session (this);
363 /* initial program change will be delivered later; see ::config_changed() */
365 BootMessage (_("Reset Control Protocols"));
367 ControlProtocolManager::instance().set_session (this);
369 _state_of_the_state = Clean;
371 Port::set_connecting_blocked (false);
373 DirtyChanged (); /* EMIT SIGNAL */
375 if (state_was_pending) {
376 save_state (_current_snapshot_name);
377 remove_pending_capture_state ();
378 state_was_pending = false;
381 BootMessage (_("Session loading complete"));
387 Session::raid_path () const
389 SearchPath raid_search_path;
391 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
392 raid_search_path += sys::path((*i).path);
395 return raid_search_path.to_string ();
399 Session::setup_raid_path (string path)
408 session_dirs.clear ();
410 SearchPath search_path(path);
411 SearchPath sound_search_path;
412 SearchPath midi_search_path;
414 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
415 sp.path = (*i).to_string ();
416 sp.blocks = 0; // not needed
417 session_dirs.push_back (sp);
419 SessionDirectory sdir(sp.path);
421 sound_search_path += sdir.sound_path ();
422 midi_search_path += sdir.midi_path ();
425 // set the search path for each data type
426 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
427 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
429 // reset the round-robin soundfile path thingie
430 last_rr_session_dir = session_dirs.begin();
434 Session::path_is_within_session (const std::string& path)
436 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
437 if (path.find ((*i).path) == 0) {
445 Session::ensure_subdirs ()
449 dir = session_directory().peak_path().to_string();
451 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
452 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
456 dir = session_directory().sound_path().to_string();
458 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
459 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
463 dir = session_directory().sound_stub_path().to_string();
465 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
466 error << string_compose(_("Session: cannot create session stub sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
470 dir = session_directory().midi_path().to_string();
472 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
473 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
477 dir = session_directory().midi_stub_path().to_string();
479 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
480 error << string_compose(_("Session: cannot create session stub midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
484 dir = session_directory().dead_sound_path().to_string();
486 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
487 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
491 dir = session_directory().export_path().to_string();
493 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
494 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
498 dir = analysis_dir ();
500 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
501 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
509 Session::create (const string& mix_template, BusProfile* bus_profile)
512 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
513 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
517 if (ensure_subdirs ()) {
521 if (!mix_template.empty()) {
522 std::string in_path = mix_template;
524 ifstream in(in_path.c_str());
527 string out_path = _path;
529 out_path += statefile_suffix;
531 ofstream out(out_path.c_str());
539 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
545 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
552 /* Instantiate metadata */
554 _metadata = new SessionMetadata ();
556 /* set initial start + end point */
558 _state_of_the_state = Clean;
560 /* set up Master Out and Control Out if necessary */
566 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
568 if (bus_profile->master_out_channels) {
569 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
574 boost_debug_shared_ptr_mark_interesting (rt, "Route");
575 boost::shared_ptr<Route> r (rt);
576 r->input()->ensure_io (count, false, this);
577 r->output()->ensure_io (count, false, this);
578 r->set_remote_control_id (control_id++);
582 if (Config->get_use_monitor_bus()) {
583 Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO);
588 boost_debug_shared_ptr_mark_interesting (rt, "Route");
589 boost::shared_ptr<Route> r (rt);
590 r->input()->ensure_io (count, false, this);
591 r->output()->ensure_io (count, false, this);
592 r->set_remote_control_id (control_id);
598 /* prohibit auto-connect to master, because there isn't one */
599 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
603 add_routes (rl, false);
606 /* this allows the user to override settings with an environment variable.
609 if (no_auto_connect()) {
610 bus_profile->input_ac = AutoConnectOption (0);
611 bus_profile->output_ac = AutoConnectOption (0);
614 Config->set_input_auto_connect (bus_profile->input_ac);
615 Config->set_output_auto_connect (bus_profile->output_ac);
624 Session::maybe_write_autosave()
626 if (dirty() && record_status() != Recording) {
627 save_state("", true);
632 Session::remove_pending_capture_state ()
634 sys::path pending_state_file_path(_session_dir->root_path());
636 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
640 sys::remove (pending_state_file_path);
642 catch(sys::filesystem_error& ex)
644 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
645 pending_state_file_path.to_string(), ex.what()) << endmsg;
649 /** Rename a state file.
650 * @param snapshot_name Snapshot name.
653 Session::rename_state (string old_name, string new_name)
655 if (old_name == _current_snapshot_name || old_name == _name) {
656 /* refuse to rename the current snapshot or the "main" one */
660 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
661 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
663 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
664 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
668 sys::rename (old_xml_path, new_xml_path);
670 catch (const sys::filesystem_error& err)
672 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
673 old_name, new_name, err.what()) << endmsg;
677 /** Remove a state file.
678 * @param snapshot_name Snapshot name.
681 Session::remove_state (string snapshot_name)
683 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
684 // refuse to remove the current snapshot or the "main" one
688 sys::path xml_path(_session_dir->root_path());
690 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
692 if (!create_backup_file (xml_path)) {
693 // don't remove it if a backup can't be made
694 // create_backup_file will log the error.
699 sys::remove (xml_path);
702 #ifdef HAVE_JACK_SESSION
704 Session::jack_session_event (jack_session_event_t * event)
708 struct tm local_time;
711 localtime_r (&n, &local_time);
712 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
714 if (event->type == JackSessionSaveTemplate)
716 if (save_template( timebuf )) {
717 event->flags = JackSessionSaveError;
719 string cmd ("ardour3 -P -U ");
720 cmd += event->client_uuid;
724 event->command_line = strdup (cmd.c_str());
729 if (save_state (timebuf)) {
730 event->flags = JackSessionSaveError;
732 sys::path xml_path (_session_dir->root_path());
733 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
735 string cmd ("ardour3 -P -U ");
736 cmd += event->client_uuid;
738 cmd += xml_path.to_string();
741 event->command_line = strdup (cmd.c_str());
745 jack_session_reply (_engine.jack(), event);
747 if (event->type == JackSessionSaveAndQuit) {
748 // TODO: make ardour quit.
751 jack_session_event_free( event );
756 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
759 sys::path xml_path(_session_dir->root_path());
761 if (!_writable || (_state_of_the_state & CannotSave)) {
765 if (!_engine.connected ()) {
766 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
772 /* tell sources we're saving first, in case they write out to a new file
773 * which should be saved with the state rather than the old one */
774 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
775 i->second->session_saved();
778 tree.set_root (&get_state());
780 if (snapshot_name.empty()) {
781 snapshot_name = _current_snapshot_name;
782 } else if (switch_to_snapshot) {
783 _current_snapshot_name = snapshot_name;
788 /* proper save: use statefile_suffix (.ardour in English) */
790 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
792 /* make a backup copy of the old file */
794 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
795 // create_backup_file will log the error
801 /* pending save: use pending_suffix (.pending in English) */
802 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
805 sys::path tmp_path(_session_dir->root_path());
807 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
809 // cerr << "actually writing state to " << xml_path.to_string() << endl;
811 if (!tree.write (tmp_path.to_string())) {
812 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
813 sys::remove (tmp_path);
818 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
819 error << string_compose (_("could not rename temporary session file %1 to %2"),
820 tmp_path.to_string(), xml_path.to_string()) << endmsg;
821 sys::remove (tmp_path);
828 save_history (snapshot_name);
830 bool was_dirty = dirty();
832 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
835 DirtyChanged (); /* EMIT SIGNAL */
838 StateSaved (snapshot_name); /* EMIT SIGNAL */
845 Session::restore_state (string snapshot_name)
847 if (load_state (snapshot_name) == 0) {
848 set_state (*state_tree->root(), Stateful::loading_state_version);
855 Session::load_state (string snapshot_name)
860 state_was_pending = false;
862 /* check for leftover pending state from a crashed capture attempt */
864 sys::path xmlpath(_session_dir->root_path());
865 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
867 if (sys::exists (xmlpath)) {
869 /* there is pending state from a crashed capture attempt */
871 boost::optional<int> r = AskAboutPendingState();
872 if (r.get_value_or (1)) {
873 state_was_pending = true;
877 if (!state_was_pending) {
878 xmlpath = _session_dir->root_path();
879 xmlpath /= snapshot_name;
882 if (!sys::exists (xmlpath)) {
883 xmlpath = _session_dir->root_path();
884 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
885 if (!sys::exists (xmlpath)) {
886 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
891 state_tree = new XMLTree;
895 /* writable() really reflects the whole folder, but if for any
896 reason the session state file can't be written to, still
900 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
904 if (!state_tree->read (xmlpath.to_string())) {
905 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
911 XMLNode& root (*state_tree->root());
913 if (root.name() != X_("Session")) {
914 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
920 const XMLProperty* prop;
922 if ((prop = root.property ("version")) == 0) {
923 /* no version implies very old version of Ardour */
924 Stateful::loading_state_version = 1000;
930 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
931 Stateful::loading_state_version = (major * 1000) + minor;
934 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
936 sys::path backup_path(_session_dir->root_path());
938 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
940 // only create a backup once
941 if (sys::exists (backup_path)) {
945 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
946 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
951 sys::copy_file (xmlpath, backup_path);
953 catch(sys::filesystem_error& ex)
955 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
956 xmlpath.to_string(), ex.what())
966 Session::load_options (const XMLNode& node)
968 LocaleGuard lg (X_("POSIX"));
969 config.set_variables (node);
980 Session::get_template()
982 /* if we don't disable rec-enable, diskstreams
983 will believe they need to store their capture
984 sources in their state node.
987 disable_record (false);
993 Session::state(bool full_state)
995 XMLNode* node = new XMLNode("Session");
998 // store libardour version, just in case
1000 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
1001 node->add_property("version", string(buf));
1003 /* store configuration settings */
1007 node->add_property ("name", _name);
1008 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
1009 node->add_property ("sample-rate", buf);
1011 if (session_dirs.size() > 1) {
1015 vector<space_and_path>::iterator i = session_dirs.begin();
1016 vector<space_and_path>::iterator next;
1018 ++i; /* skip the first one */
1022 while (i != session_dirs.end()) {
1026 if (next != session_dirs.end()) {
1036 child = node->add_child ("Path");
1037 child->add_content (p);
1041 /* save the ID counter */
1043 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1044 node->add_property ("id-counter", buf);
1046 /* various options */
1048 node->add_child_nocopy (config.get_variables ());
1050 node->add_child_nocopy (_metadata->get_state());
1052 child = node->add_child ("Sources");
1055 Glib::Mutex::Lock sl (source_lock);
1057 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1059 /* Don't save information about non-destructive file sources that are empty
1060 and unused by any regions.
1063 boost::shared_ptr<FileSource> fs;
1064 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1065 if (!fs->destructive()) {
1066 if (fs->empty() && !fs->used()) {
1072 child->add_child_nocopy (siter->second->get_state());
1076 child = node->add_child ("Regions");
1079 Glib::Mutex::Lock rl (region_lock);
1080 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1081 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1082 boost::shared_ptr<Region> r = i->second;
1083 /* only store regions not attached to playlists */
1084 if (r->playlist() == 0) {
1085 child->add_child_nocopy (r->state (true));
1091 node->add_child_nocopy (_locations.get_state());
1093 // for a template, just create a new Locations, populate it
1094 // with the default start and end, and get the state for that.
1096 Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
1097 range->set (max_frames, 0);
1099 node->add_child_nocopy (loc.get_state());
1102 child = node->add_child ("Bundles");
1104 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1105 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1106 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1108 child->add_child_nocopy (b->get_state());
1113 child = node->add_child ("Routes");
1115 boost::shared_ptr<RouteList> r = routes.reader ();
1117 RoutePublicOrderSorter cmp;
1118 RouteList public_order (*r);
1119 public_order.sort (cmp);
1121 /* the sort should have put control outs first */
1124 assert (_monitor_out == public_order.front());
1127 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1128 if (!(*i)->is_hidden()) {
1130 child->add_child_nocopy ((*i)->get_state());
1132 child->add_child_nocopy ((*i)->get_template());
1138 playlists->add_state (node, full_state);
1140 child = node->add_child ("RouteGroups");
1141 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1142 child->add_child_nocopy ((*i)->get_state());
1146 child = node->add_child ("Click");
1147 child->add_child_nocopy (_click_io->state (full_state));
1151 child = node->add_child ("NamedSelections");
1152 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1154 child->add_child_nocopy ((*i)->get_state());
1159 node->add_child_nocopy (_tempo_map->get_state());
1161 node->add_child_nocopy (get_control_protocol_state());
1164 node->add_child_copy (*_extra_xml);
1171 Session::get_control_protocol_state ()
1173 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1174 return cpm.get_state();
1178 Session::set_state (const XMLNode& node, int version)
1182 const XMLProperty* prop;
1185 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1187 if (node.name() != X_("Session")){
1188 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1192 if ((prop = node.property ("version")) != 0) {
1193 version = atoi (prop->value ()) * 1000;
1196 if ((prop = node.property ("name")) != 0) {
1197 _name = prop->value ();
1200 if ((prop = node.property (X_("sample-rate"))) != 0) {
1202 _nominal_frame_rate = atoi (prop->value());
1204 if (_nominal_frame_rate != _current_frame_rate) {
1205 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1206 if (r.get_value_or (0)) {
1212 setup_raid_path(_session_dir->root_path().to_string());
1214 if ((prop = node.property (X_("id-counter"))) != 0) {
1216 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1217 ID::init_counter (x);
1219 /* old sessions used a timebased counter, so fake
1220 the startup ID counter based on a standard
1225 ID::init_counter (now);
1229 IO::disable_connecting ();
1231 /* Object loading order:
1236 MIDI Control // relies on data from Options/Config
1249 if ((child = find_named_node (node, "Extra")) != 0) {
1250 _extra_xml = new XMLNode (*child);
1253 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1254 load_options (*child);
1255 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1256 load_options (*child);
1258 error << _("Session: XML state has no options section") << endmsg;
1261 if (version >= 3000) {
1262 if ((child = find_named_node (node, "Metadata")) == 0) {
1263 warning << _("Session: XML state has no metadata section") << endmsg;
1264 } else if (_metadata->set_state (*child, version)) {
1269 if ((child = find_named_node (node, "Locations")) == 0) {
1270 error << _("Session: XML state has no locations section") << endmsg;
1272 } else if (_locations.set_state (*child, version)) {
1278 if ((location = _locations.auto_loop_location()) != 0) {
1279 set_auto_loop_location (location);
1282 if ((location = _locations.auto_punch_location()) != 0) {
1283 set_auto_punch_location (location);
1286 if ((location = _locations.session_range_location()) != 0) {
1287 delete _session_range_location;
1288 _session_range_location = location;
1291 if (_session_range_location) {
1292 AudioFileSource::set_header_position_offset (_session_range_location->start());
1295 if ((child = find_named_node (node, "Sources")) == 0) {
1296 error << _("Session: XML state has no sources section") << endmsg;
1298 } else if (load_sources (*child)) {
1302 if ((child = find_named_node (node, "Regions")) == 0) {
1303 error << _("Session: XML state has no Regions section") << endmsg;
1305 } else if (load_regions (*child)) {
1309 if ((child = find_named_node (node, "Playlists")) == 0) {
1310 error << _("Session: XML state has no playlists section") << endmsg;
1312 } else if (playlists->load (*this, *child)) {
1316 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1318 } else if (playlists->load_unused (*this, *child)) {
1322 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1323 if (load_named_selections (*child)) {
1328 if (version >= 3000) {
1329 if ((child = find_named_node (node, "Bundles")) == 0) {
1330 warning << _("Session: XML state has no bundles section") << endmsg;
1333 /* We can't load Bundles yet as they need to be able
1334 to convert from port names to Port objects, which can't happen until
1336 _bundle_xml_node = new XMLNode (*child);
1340 if ((child = find_named_node (node, "TempoMap")) == 0) {
1341 error << _("Session: XML state has no Tempo Map section") << endmsg;
1343 } else if (_tempo_map->set_state (*child, version)) {
1347 if (version < 3000) {
1348 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1349 error << _("Session: XML state has no diskstreams section") << endmsg;
1351 } else if (load_diskstreams_2X (*child, version)) {
1356 if ((child = find_named_node (node, "Routes")) == 0) {
1357 error << _("Session: XML state has no routes section") << endmsg;
1359 } else if (load_routes (*child, version)) {
1363 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1364 _diskstreams_2X.clear ();
1366 if (version >= 3000) {
1368 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1369 error << _("Session: XML state has no route groups section") << endmsg;
1371 } else if (load_route_groups (*child, version)) {
1375 } else if (version < 3000) {
1377 if ((child = find_named_node (node, "EditGroups")) == 0) {
1378 error << _("Session: XML state has no edit groups section") << endmsg;
1380 } else if (load_route_groups (*child, version)) {
1384 if ((child = find_named_node (node, "MixGroups")) == 0) {
1385 error << _("Session: XML state has no mix groups section") << endmsg;
1387 } else if (load_route_groups (*child, version)) {
1392 if ((child = find_named_node (node, "Click")) == 0) {
1393 warning << _("Session: XML state has no click section") << endmsg;
1394 } else if (_click_io) {
1395 _click_io->set_state (*child, version);
1398 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1399 ControlProtocolManager::instance().set_protocol_states (*child);
1402 /* here beginneth the second phase ... */
1404 StateReady (); /* EMIT SIGNAL */
1413 Session::load_routes (const XMLNode& node, int version)
1416 XMLNodeConstIterator niter;
1417 RouteList new_routes;
1419 nlist = node.children();
1423 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1425 boost::shared_ptr<Route> route;
1426 if (version < 3000) {
1427 route = XMLRouteFactory_2X (**niter, version);
1429 route = XMLRouteFactory (**niter, version);
1433 error << _("Session: cannot create Route from XML description.") << endmsg;
1437 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1439 new_routes.push_back (route);
1442 add_routes (new_routes, false);
1447 boost::shared_ptr<Route>
1448 Session::XMLRouteFactory (const XMLNode& node, int version)
1450 boost::shared_ptr<Route> ret;
1452 if (node.name() != "Route") {
1456 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1458 DataType type = DataType::AUDIO;
1459 const XMLProperty* prop = node.property("default-type");
1462 type = DataType (prop->value());
1465 assert (type != DataType::NIL);
1471 if (type == DataType::AUDIO) {
1472 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1475 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1478 if (track->init()) {
1483 if (track->set_state (node, version)) {
1488 boost_debug_shared_ptr_mark_interesting (track, "Track");
1492 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1494 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1495 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1505 boost::shared_ptr<Route>
1506 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1508 boost::shared_ptr<Route> ret;
1510 if (node.name() != "Route") {
1514 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1516 ds_prop = node.property (X_("diskstream"));
1519 DataType type = DataType::AUDIO;
1520 const XMLProperty* prop = node.property("default-type");
1523 type = DataType (prop->value());
1526 assert (type != DataType::NIL);
1530 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1531 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1535 if (i == _diskstreams_2X.end()) {
1536 error << _("Could not find diskstream for route") << endmsg;
1537 return boost::shared_ptr<Route> ();
1542 if (type == DataType::AUDIO) {
1543 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1546 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1549 if (track->init()) {
1554 if (track->set_state (node, version)) {
1559 track->set_diskstream (*i);
1561 boost_debug_shared_ptr_mark_interesting (track, "Track");
1565 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1567 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1568 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1579 Session::load_regions (const XMLNode& node)
1582 XMLNodeConstIterator niter;
1583 boost::shared_ptr<Region> region;
1585 nlist = node.children();
1589 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1590 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1591 error << _("Session: cannot create Region from XML description.");
1592 const XMLProperty *name = (**niter).property("name");
1595 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1605 boost::shared_ptr<Region>
1606 Session::XMLRegionFactory (const XMLNode& node, bool full)
1608 const XMLProperty* type = node.property("type");
1612 if (!type || type->value() == "audio") {
1613 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1614 } else if (type->value() == "midi") {
1615 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1618 } catch (failed_constructor& err) {
1619 return boost::shared_ptr<Region> ();
1622 return boost::shared_ptr<Region> ();
1625 boost::shared_ptr<AudioRegion>
1626 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1628 const XMLProperty* prop;
1629 boost::shared_ptr<Source> source;
1630 boost::shared_ptr<AudioSource> as;
1632 SourceList master_sources;
1633 uint32_t nchans = 1;
1636 if (node.name() != X_("Region")) {
1637 return boost::shared_ptr<AudioRegion>();
1640 if ((prop = node.property (X_("channels"))) != 0) {
1641 nchans = atoi (prop->value().c_str());
1644 if ((prop = node.property ("name")) == 0) {
1645 cerr << "no name for this region\n";
1649 if ((prop = node.property (X_("source-0"))) == 0) {
1650 if ((prop = node.property ("source")) == 0) {
1651 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1652 return boost::shared_ptr<AudioRegion>();
1656 PBD::ID s_id (prop->value());
1658 if ((source = source_by_id (s_id)) == 0) {
1659 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1660 return boost::shared_ptr<AudioRegion>();
1663 as = boost::dynamic_pointer_cast<AudioSource>(source);
1665 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1666 return boost::shared_ptr<AudioRegion>();
1669 sources.push_back (as);
1671 /* pickup other channels */
1673 for (uint32_t n=1; n < nchans; ++n) {
1674 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1675 if ((prop = node.property (buf)) != 0) {
1677 PBD::ID id2 (prop->value());
1679 if ((source = source_by_id (id2)) == 0) {
1680 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1681 return boost::shared_ptr<AudioRegion>();
1684 as = boost::dynamic_pointer_cast<AudioSource>(source);
1686 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1687 return boost::shared_ptr<AudioRegion>();
1689 sources.push_back (as);
1693 for (uint32_t n = 0; n < nchans; ++n) {
1694 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1695 if ((prop = node.property (buf)) != 0) {
1697 PBD::ID id2 (prop->value());
1699 if ((source = source_by_id (id2)) == 0) {
1700 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1701 return boost::shared_ptr<AudioRegion>();
1704 as = boost::dynamic_pointer_cast<AudioSource>(source);
1706 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1707 return boost::shared_ptr<AudioRegion>();
1709 master_sources.push_back (as);
1714 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1716 /* a final detail: this is the one and only place that we know how long missing files are */
1718 if (region->whole_file()) {
1719 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1720 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1722 sfp->set_length (region->length());
1727 if (!master_sources.empty()) {
1728 if (master_sources.size() != nchans) {
1729 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1731 region->set_master_sources (master_sources);
1739 catch (failed_constructor& err) {
1740 return boost::shared_ptr<AudioRegion>();
1744 boost::shared_ptr<MidiRegion>
1745 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1747 const XMLProperty* prop;
1748 boost::shared_ptr<Source> source;
1749 boost::shared_ptr<MidiSource> ms;
1752 if (node.name() != X_("Region")) {
1753 return boost::shared_ptr<MidiRegion>();
1756 if ((prop = node.property ("name")) == 0) {
1757 cerr << "no name for this region\n";
1761 if ((prop = node.property (X_("source-0"))) == 0) {
1762 if ((prop = node.property ("source")) == 0) {
1763 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1764 return boost::shared_ptr<MidiRegion>();
1768 PBD::ID s_id (prop->value());
1770 if ((source = source_by_id (s_id)) == 0) {
1771 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1772 return boost::shared_ptr<MidiRegion>();
1775 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1777 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1778 return boost::shared_ptr<MidiRegion>();
1781 sources.push_back (ms);
1784 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1785 /* a final detail: this is the one and only place that we know how long missing files are */
1787 if (region->whole_file()) {
1788 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1789 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1791 sfp->set_length (region->length());
1799 catch (failed_constructor& err) {
1800 return boost::shared_ptr<MidiRegion>();
1805 Session::get_sources_as_xml ()
1808 XMLNode* node = new XMLNode (X_("Sources"));
1809 Glib::Mutex::Lock lm (source_lock);
1811 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1812 node->add_child_nocopy (i->second->get_state());
1819 Session::path_from_region_name (DataType type, string name, string identifier)
1821 char buf[PATH_MAX+1];
1823 SessionDirectory sdir(get_best_session_directory_for_new_source());
1824 sys::path source_dir = ((type == DataType::AUDIO)
1825 ? sdir.sound_path() : sdir.midi_path());
1827 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1829 for (n = 0; n < 999999; ++n) {
1830 if (identifier.length()) {
1831 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1832 identifier.c_str(), n, ext.c_str());
1834 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1838 sys::path source_path = source_dir / buf;
1840 if (!sys::exists (source_path)) {
1841 return source_path.to_string();
1845 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1854 Session::load_sources (const XMLNode& node)
1857 XMLNodeConstIterator niter;
1858 boost::shared_ptr<Source> source;
1860 nlist = node.children();
1864 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1866 if ((source = XMLSourceFactory (**niter)) == 0) {
1867 error << _("Session: cannot create Source from XML description.") << endmsg;
1869 } catch (MissingSource& err) {
1870 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1871 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1878 boost::shared_ptr<Source>
1879 Session::XMLSourceFactory (const XMLNode& node)
1881 if (node.name() != "Source") {
1882 return boost::shared_ptr<Source>();
1886 /* note: do peak building in another thread when loading session state */
1887 return SourceFactory::create (*this, node, true);
1890 catch (failed_constructor& err) {
1891 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1892 return boost::shared_ptr<Source>();
1897 Session::save_template (string template_name)
1901 if (_state_of_the_state & CannotSave) {
1905 sys::path user_template_dir(user_template_directory());
1909 sys::create_directories (user_template_dir);
1911 catch(sys::filesystem_error& ex)
1913 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1914 user_template_dir.to_string(), ex.what()) << endmsg;
1918 tree.set_root (&get_template());
1920 sys::path template_file_path(user_template_dir);
1921 template_file_path /= template_name + template_suffix;
1923 if (sys::exists (template_file_path))
1925 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1926 template_file_path.to_string()) << endmsg;
1930 if (!tree.write (template_file_path.to_string())) {
1931 error << _("mix template not saved") << endmsg;
1939 Session::rename_template (string old_name, string new_name)
1941 sys::path old_path (user_template_directory());
1942 old_path /= old_name + template_suffix;
1944 sys::path new_path(user_template_directory());
1945 new_path /= new_name + template_suffix;
1947 if (sys::exists (new_path)) {
1948 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1949 new_path.to_string()) << endmsg;
1954 sys::rename (old_path, new_path);
1962 Session::delete_template (string name)
1964 sys::path path = user_template_directory();
1965 path /= name + template_suffix;
1976 Session::refresh_disk_space ()
1979 struct statfs statfsbuf;
1980 vector<space_and_path>::iterator i;
1981 Glib::Mutex::Lock lm (space_lock);
1984 /* get freespace on every FS that is part of the session path */
1986 _total_free_4k_blocks = 0;
1988 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1989 statfs ((*i).path.c_str(), &statfsbuf);
1991 scale = statfsbuf.f_bsize/4096.0;
1993 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1994 _total_free_4k_blocks += (*i).blocks;
2000 Session::get_best_session_directory_for_new_source ()
2002 vector<space_and_path>::iterator i;
2003 string result = _session_dir->root_path().to_string();
2005 /* handle common case without system calls */
2007 if (session_dirs.size() == 1) {
2011 /* OK, here's the algorithm we're following here:
2013 We want to select which directory to use for
2014 the next file source to be created. Ideally,
2015 we'd like to use a round-robin process so as to
2016 get maximum performance benefits from splitting
2017 the files across multiple disks.
2019 However, in situations without much diskspace, an
2020 RR approach may end up filling up a filesystem
2021 with new files while others still have space.
2022 Its therefore important to pay some attention to
2023 the freespace in the filesystem holding each
2024 directory as well. However, if we did that by
2025 itself, we'd keep creating new files in the file
2026 system with the most space until it was as full
2027 as all others, thus negating any performance
2028 benefits of this RAID-1 like approach.
2030 So, we use a user-configurable space threshold. If
2031 there are at least 2 filesystems with more than this
2032 much space available, we use RR selection between them.
2033 If not, then we pick the filesystem with the most space.
2035 This gets a good balance between the two
2039 refresh_disk_space ();
2041 int free_enough = 0;
2043 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2044 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2049 if (free_enough >= 2) {
2050 /* use RR selection process, ensuring that the one
2054 i = last_rr_session_dir;
2057 if (++i == session_dirs.end()) {
2058 i = session_dirs.begin();
2061 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2062 if (create_session_directory ((*i).path)) {
2064 last_rr_session_dir = i;
2069 } while (i != last_rr_session_dir);
2073 /* pick FS with the most freespace (and that
2074 seems to actually work ...)
2077 vector<space_and_path> sorted;
2078 space_and_path_ascending_cmp cmp;
2080 sorted = session_dirs;
2081 sort (sorted.begin(), sorted.end(), cmp);
2083 for (i = sorted.begin(); i != sorted.end(); ++i) {
2084 if (create_session_directory ((*i).path)) {
2086 last_rr_session_dir = i;
2096 Session::load_named_selections (const XMLNode& node)
2099 XMLNodeConstIterator niter;
2102 nlist = node.children();
2106 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2108 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2109 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2117 Session::XMLNamedSelectionFactory (const XMLNode& node)
2120 return new NamedSelection (*this, node);
2123 catch (failed_constructor& err) {
2129 Session::automation_dir () const
2131 return Glib::build_filename (_path, "automation");
2135 Session::analysis_dir () const
2137 return Glib::build_filename (_path, "analysis");
2141 Session::load_bundles (XMLNode const & node)
2143 XMLNodeList nlist = node.children();
2144 XMLNodeConstIterator niter;
2148 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2149 if ((*niter)->name() == "InputBundle") {
2150 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2151 } else if ((*niter)->name() == "OutputBundle") {
2152 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2154 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2163 Session::load_route_groups (const XMLNode& node, int version)
2165 XMLNodeList nlist = node.children();
2166 XMLNodeConstIterator niter;
2170 if (version >= 3000) {
2172 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2173 if ((*niter)->name() == "RouteGroup") {
2174 RouteGroup* rg = new RouteGroup (*this, "");
2175 add_route_group (rg);
2176 rg->set_state (**niter, version);
2180 } else if (version < 3000) {
2182 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2183 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2184 RouteGroup* rg = new RouteGroup (*this, "");
2185 add_route_group (rg);
2186 rg->set_state (**niter, version);
2195 Session::auto_save()
2197 save_state (_current_snapshot_name);
2201 state_file_filter (const string &str, void */*arg*/)
2203 return (str.length() > strlen(statefile_suffix) &&
2204 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2208 bool operator()(const string* a, const string* b) {
2214 remove_end(string* state)
2216 string statename(*state);
2218 string::size_type start,end;
2219 if ((start = statename.find_last_of ('/')) != string::npos) {
2220 statename = statename.substr (start+1);
2223 if ((end = statename.rfind(".ardour")) == string::npos) {
2224 end = statename.length();
2227 return new string(statename.substr (0, end));
2231 Session::possible_states (string path)
2233 PathScanner scanner;
2234 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2236 transform(states->begin(), states->end(), states->begin(), remove_end);
2239 sort (states->begin(), states->end(), cmp);
2245 Session::possible_states () const
2247 return possible_states(_path);
2251 Session::add_route_group (RouteGroup* g)
2253 _route_groups.push_back (g);
2254 route_group_added (g); /* EMIT SIGNAL */
2256 g->MembershipChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2257 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2263 Session::remove_route_group (RouteGroup& rg)
2265 list<RouteGroup*>::iterator i;
2267 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2268 _route_groups.erase (i);
2271 route_group_removed (); /* EMIT SIGNAL */
2277 Session::route_group_by_name (string name)
2279 list<RouteGroup *>::iterator i;
2281 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2282 if ((*i)->name() == name) {
2290 Session::start_reversible_command (const string& name)
2292 UndoTransaction* trans = new UndoTransaction();
2293 trans->set_name(name);
2298 Session::finish_reversible_command (UndoTransaction& ut)
2301 gettimeofday(&now, 0);
2302 ut.set_timestamp(now);
2307 Session::begin_reversible_command(const string& name)
2309 UndoTransaction* trans = new UndoTransaction();
2310 trans->set_name(name);
2312 if (!_current_trans.empty()) {
2313 _current_trans.top()->add_command (trans);
2315 _current_trans.push(trans);
2320 Session::commit_reversible_command(Command *cmd)
2322 assert(!_current_trans.empty());
2326 _current_trans.top()->add_command(cmd);
2329 if (_current_trans.top()->empty()) {
2330 _current_trans.pop();
2334 gettimeofday(&now, 0);
2335 _current_trans.top()->set_timestamp(now);
2337 _history.add(_current_trans.top());
2338 _current_trans.pop();
2342 accept_all_non_peak_files (const string& path, void */*arg*/)
2344 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2348 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2352 accept_all_state_files (const string& path, void */*arg*/)
2354 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2358 Session::find_all_sources (string path, set<string>& result)
2363 if (!tree.read (path)) {
2367 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2372 XMLNodeConstIterator niter;
2374 nlist = node->children();
2378 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2382 if ((prop = (*niter)->property (X_("type"))) == 0) {
2386 DataType type (prop->value());
2388 if ((prop = (*niter)->property (X_("name"))) == 0) {
2392 if (prop->value()[0] == '/') {
2393 /* external file, ignore */
2397 Glib::ustring found_path;
2401 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2402 result.insert (found_path);
2410 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2412 PathScanner scanner;
2413 vector<string*>* state_files;
2415 string this_snapshot_path;
2421 if (ripped[ripped.length()-1] == '/') {
2422 ripped = ripped.substr (0, ripped.length() - 1);
2425 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2427 if (state_files == 0) {
2432 this_snapshot_path = _path;
2433 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2434 this_snapshot_path += statefile_suffix;
2436 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2438 if (exclude_this_snapshot && **i == this_snapshot_path) {
2442 if (find_all_sources (**i, result) < 0) {
2450 struct RegionCounter {
2451 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2452 AudioSourceList::iterator iter;
2453 boost::shared_ptr<Region> region;
2456 RegionCounter() : count (0) {}
2460 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2462 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2463 return r.get_value_or (1);
2467 Session::cleanup_sources (CleanupReport& rep)
2469 // FIXME: needs adaptation to midi
2471 vector<boost::shared_ptr<Source> > dead_sources;
2472 PathScanner scanner;
2474 vector<space_and_path>::iterator i;
2475 vector<space_and_path>::iterator nexti;
2476 vector<string*>* soundfiles;
2477 vector<string> unused;
2478 set<string> all_sources;
2483 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2485 /* step 1: consider deleting all unused playlists */
2487 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
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->drop_references ();
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 if (realpath(spath.c_str(), tmppath1) == 0) {
2572 error << string_compose (_("Cannot expand path %1 (%2)"),
2573 spath, strerror (errno)) << endmsg;
2577 if (realpath((*i).c_str(), tmppath2) == 0) {
2578 error << string_compose (_("Cannot expand path %1 (%2)"),
2579 (*i), strerror (errno)) << endmsg;
2583 if (strcmp(tmppath1, tmppath2) == 0) {
2590 unused.push_back (spath);
2594 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2596 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2597 struct stat statbuf;
2599 rep.paths.push_back (*x);
2600 if (stat ((*x).c_str(), &statbuf) == 0) {
2601 rep.space += statbuf.st_size;
2606 /* don't move the file across filesystems, just
2607 stick it in the `dead_sound_dir_name' directory
2608 on whichever filesystem it was already on.
2611 if ((*x).find ("/sounds/") != string::npos) {
2613 /* old school, go up 1 level */
2615 newpath = Glib::path_get_dirname (*x); // "sounds"
2616 newpath = Glib::path_get_dirname (newpath); // "session-name"
2620 /* new school, go up 4 levels */
2622 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2623 newpath = Glib::path_get_dirname (newpath); // "session-name"
2624 newpath = Glib::path_get_dirname (newpath); // "interchange"
2625 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2629 newpath += dead_sound_dir_name;
2631 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2632 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2637 newpath += Glib::path_get_basename ((*x));
2639 if (access (newpath.c_str(), F_OK) == 0) {
2641 /* the new path already exists, try versioning */
2643 char buf[PATH_MAX+1];
2647 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2650 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2651 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2655 if (version == 999) {
2656 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2660 newpath = newpath_v;
2665 /* it doesn't exist, or we can't read it or something */
2669 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2670 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2671 (*x), newpath, strerror (errno))
2676 /* see if there an easy to find peakfile for this file, and remove it.
2679 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2680 peakpath += peakfile_suffix;
2682 if (access (peakpath.c_str(), W_OK) == 0) {
2683 if (::unlink (peakpath.c_str()) != 0) {
2684 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2685 peakpath, _path, strerror (errno))
2687 /* try to back out */
2688 rename (newpath.c_str(), _path.c_str());
2696 /* dump the history list */
2700 /* save state so we don't end up a session file
2701 referring to non-existent sources.
2707 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2713 Session::cleanup_trash_sources (CleanupReport& rep)
2715 // FIXME: needs adaptation for MIDI
2717 vector<space_and_path>::iterator i;
2718 string dead_sound_dir;
2723 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2725 dead_sound_dir = (*i).path;
2726 dead_sound_dir += dead_sound_dir_name;
2728 clear_directory (dead_sound_dir, &rep.space, &rep.paths);
2735 Session::cleanup_stubfiles ()
2737 vector<space_and_path>::iterator i;
2739 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2742 string lname = legalize_for_path (_name);
2746 /* XXX this is a hack caused by semantic conflicts
2747 between space_and_path and the SessionDirectory concept.
2750 v.push_back ((*i).path);
2751 v.push_back ("interchange");
2752 v.push_back (lname);
2753 v.push_back ("audiofiles");
2754 v.push_back (stub_dir_name);
2756 dir = Glib::build_filename (v);
2758 clear_directory (dir);
2761 v.push_back ((*i).path);
2762 v.push_back ("interchange");
2763 v.push_back (lname);
2764 v.push_back ("midifiles");
2765 v.push_back (stub_dir_name);
2767 dir = Glib::build_filename (v);
2769 clear_directory (dir);
2774 Session::set_dirty ()
2776 bool was_dirty = dirty();
2778 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2782 DirtyChanged(); /* EMIT SIGNAL */
2788 Session::set_clean ()
2790 bool was_dirty = dirty();
2792 _state_of_the_state = Clean;
2796 DirtyChanged(); /* EMIT SIGNAL */
2801 Session::set_deletion_in_progress ()
2803 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2807 Session::clear_deletion_in_progress ()
2809 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2813 Session::add_controllable (boost::shared_ptr<Controllable> c)
2815 /* this adds a controllable to the list managed by the Session.
2816 this is a subset of those managed by the Controllable class
2817 itself, and represents the only ones whose state will be saved
2818 as part of the session.
2821 Glib::Mutex::Lock lm (controllables_lock);
2822 controllables.insert (c);
2825 struct null_deleter { void operator()(void const *) const {} };
2828 Session::remove_controllable (Controllable* c)
2830 if (_state_of_the_state | Deletion) {
2834 Glib::Mutex::Lock lm (controllables_lock);
2836 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2838 if (x != controllables.end()) {
2839 controllables.erase (x);
2843 boost::shared_ptr<Controllable>
2844 Session::controllable_by_id (const PBD::ID& id)
2846 Glib::Mutex::Lock lm (controllables_lock);
2848 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2849 if ((*i)->id() == id) {
2854 return boost::shared_ptr<Controllable>();
2857 boost::shared_ptr<Controllable>
2858 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2860 boost::shared_ptr<Controllable> c;
2861 boost::shared_ptr<Route> r;
2863 switch (desc.top_level_type()) {
2864 case ControllableDescriptor::NamedRoute:
2866 std::string str = desc.top_level_name();
2867 if (str == "master") {
2869 } else if (str == "control" || str == "listen") {
2872 r = route_by_name (desc.top_level_name());
2877 case ControllableDescriptor::RemoteControlID:
2878 r = route_by_remote_id (desc.rid());
2886 switch (desc.subtype()) {
2887 case ControllableDescriptor::Gain:
2888 c = r->gain_control ();
2891 case ControllableDescriptor::Solo:
2892 c = r->solo_control();
2895 case ControllableDescriptor::Mute:
2896 c = r->mute_control();
2899 case ControllableDescriptor::Recenable:
2901 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2904 c = t->rec_enable_control ();
2909 case ControllableDescriptor::Pan:
2910 /* XXX pan control */
2913 case ControllableDescriptor::Balance:
2914 /* XXX simple pan control */
2917 case ControllableDescriptor::PluginParameter:
2919 uint32_t plugin = desc.target (0);
2920 uint32_t parameter_index = desc.target (1);
2922 /* revert to zero based counting */
2928 if (parameter_index > 0) {
2932 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
2935 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
2936 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
2941 case ControllableDescriptor::SendGain:
2943 uint32_t send = desc.target (0);
2945 /* revert to zero-based counting */
2951 boost::shared_ptr<Processor> p = r->nth_send (send);
2954 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
2955 boost::shared_ptr<Amp> a = s->amp();
2958 c = s->amp()->gain_control();
2965 /* relax and return a null pointer */
2973 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2976 Stateful::add_instant_xml (node, _path);
2979 if (write_to_config) {
2980 Config->add_instant_xml (node);
2985 Session::instant_xml (const string& node_name)
2987 return Stateful::instant_xml (node_name, _path);
2991 Session::save_history (string snapshot_name)
2999 if (snapshot_name.empty()) {
3000 snapshot_name = _current_snapshot_name;
3003 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3004 const string backup_filename = history_filename + backup_suffix;
3005 const sys::path xml_path = _session_dir->root_path() / history_filename;
3006 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3008 if (sys::exists (xml_path)) {
3011 sys::rename (xml_path, backup_path);
3013 catch (const sys::filesystem_error& err)
3015 error << _("could not backup old history file, current history not saved") << endmsg;
3020 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3024 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3026 if (!tree.write (xml_path.to_string()))
3028 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3032 sys::remove (xml_path);
3033 sys::rename (backup_path, xml_path);
3035 catch (const sys::filesystem_error& err)
3037 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3038 backup_path.to_string(), err.what()) << endmsg;
3048 Session::restore_history (string snapshot_name)
3052 if (snapshot_name.empty()) {
3053 snapshot_name = _current_snapshot_name;
3056 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3057 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3059 info << "Loading history from " << xml_path.to_string() << endmsg;
3061 if (!sys::exists (xml_path)) {
3062 info << string_compose (_("%1: no history file \"%2\" for this session."),
3063 _name, xml_path.to_string()) << endmsg;
3067 if (!tree.read (xml_path.to_string())) {
3068 error << string_compose (_("Could not understand session history file \"%1\""),
3069 xml_path.to_string()) << endmsg;
3076 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3079 UndoTransaction* ut = new UndoTransaction ();
3082 ut->set_name(t->property("name")->value());
3083 stringstream ss(t->property("tv-sec")->value());
3085 ss.str(t->property("tv-usec")->value());
3087 ut->set_timestamp(tv);
3089 for (XMLNodeConstIterator child_it = t->children().begin();
3090 child_it != t->children().end(); child_it++)
3092 XMLNode *n = *child_it;
3095 if (n->name() == "MementoCommand" ||
3096 n->name() == "MementoUndoCommand" ||
3097 n->name() == "MementoRedoCommand") {
3099 if ((c = memento_command_factory(n))) {
3103 } else if (n->name() == "DiffCommand") {
3104 PBD::ID id(n->property("midi-source")->value());
3105 boost::shared_ptr<MidiSource> midi_source =
3106 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3108 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
3110 error << _("Failed to downcast MidiSource for DiffCommand") << endmsg;
3113 } else if (n->name() == "StatefulDiffCommand") {
3114 if ((c = stateful_diff_command_factory (n))) {
3115 ut->add_command (c);
3118 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3129 Session::config_changed (std::string p, bool ours)
3135 if (p == "seamless-loop") {
3137 } else if (p == "rf-speed") {
3139 } else if (p == "auto-loop") {
3141 } else if (p == "auto-input") {
3143 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3144 /* auto-input only makes a difference if we're rolling */
3146 boost::shared_ptr<RouteList> rl = routes.reader ();
3147 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3148 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3149 if (tr && tr->record_enabled ()) {
3150 tr->monitor_input (!config.get_auto_input());
3155 } else if (p == "punch-in") {
3159 if ((location = _locations.auto_punch_location()) != 0) {
3161 if (config.get_punch_in ()) {
3162 replace_event (SessionEvent::PunchIn, location->start());
3164 remove_event (location->start(), SessionEvent::PunchIn);
3168 } else if (p == "punch-out") {
3172 if ((location = _locations.auto_punch_location()) != 0) {
3174 if (config.get_punch_out()) {
3175 replace_event (SessionEvent::PunchOut, location->end());
3177 clear_events (SessionEvent::PunchOut);
3181 } else if (p == "edit-mode") {
3183 Glib::Mutex::Lock lm (playlists->lock);
3185 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3186 (*i)->set_edit_mode (Config->get_edit_mode ());
3189 } else if (p == "use-video-sync") {
3191 waiting_for_sync_offset = config.get_use_video_sync();
3193 } else if (p == "mmc-control") {
3195 //poke_midi_thread ();
3197 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3199 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3201 } else if (p == "mmc-send-id") {
3203 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3205 } else if (p == "midi-control") {
3207 //poke_midi_thread ();
3209 } else if (p == "raid-path") {
3211 setup_raid_path (config.get_raid_path());
3213 } else if (p == "timecode-format") {
3217 } else if (p == "video-pullup") {
3221 } else if (p == "seamless-loop") {
3223 if (play_loop && transport_rolling()) {
3224 // to reset diskstreams etc
3225 request_play_loop (true);
3228 } else if (p == "rf-speed") {
3230 cumulative_rf_motion = 0;
3233 } else if (p == "click-sound") {
3235 setup_click_sounds (1);
3237 } else if (p == "click-emphasis-sound") {
3239 setup_click_sounds (-1);
3241 } else if (p == "clicking") {
3243 if (Config->get_clicking()) {
3244 if (_click_io && click_data) { // don't require emphasis data
3251 } else if (p == "send-mtc") {
3253 session_send_mtc = Config->get_send_mtc();
3254 if (session_send_mtc) {
3255 /* mark us ready to send */
3256 next_quarter_frame_to_send = 0;
3259 } else if (p == "send-mmc") {
3261 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3263 } else if (p == "midi-feedback") {
3265 session_midi_feedback = Config->get_midi_feedback();
3267 } else if (p == "jack-time-master") {
3269 engine().reset_timebase ();
3271 } else if (p == "native-file-header-format") {
3273 if (!first_file_header_format_reset) {
3274 reset_native_file_format ();
3277 first_file_header_format_reset = false;
3279 } else if (p == "native-file-data-format") {
3281 if (!first_file_data_format_reset) {
3282 reset_native_file_format ();
3285 first_file_data_format_reset = false;
3287 } else if (p == "external-sync") {
3288 if (!config.get_external_sync()) {
3289 drop_sync_source ();
3291 switch_to_sync_source (config.get_sync_source());
3293 } else if (p == "remote-model") {
3294 set_remote_control_ids ();
3295 } else if (p == "denormal-model") {
3297 } else if (p == "history-depth") {
3298 set_history_depth (Config->get_history_depth());
3299 } else if (p == "sync-all-route-ordering") {
3300 sync_order_keys ("session");
3301 } else if (p == "initial-program-change") {
3303 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3306 buf[0] = MIDI::program; // channel zero by default
3307 buf[1] = (Config->get_initial_program_change() & 0x7f);
3309 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3311 } else if (p == "solo-mute-override") {
3312 // catch_up_on_solo_mute_override ();
3313 } else if (p == "listen-position") {
3314 listen_position_changed ();
3315 } else if (p == "solo-control-is-listen-control") {
3316 solo_control_mode_changed ();
3324 Session::set_history_depth (uint32_t d)
3326 _history.set_depth (d);
3330 Session::load_diskstreams_2X (XMLNode const & node, int)
3333 XMLNodeConstIterator citer;
3335 clist = node.children();
3337 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3340 /* diskstreams added automatically by DiskstreamCreated handler */
3341 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3342 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3343 _diskstreams_2X.push_back (dsp);
3345 error << _("Session: unknown diskstream type in XML") << endmsg;
3349 catch (failed_constructor& err) {
3350 error << _("Session: could not load diskstream via XML state") << endmsg;
3358 /** Connect things to the MMC object */
3360 Session::setup_midi_machine_control ()
3362 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3364 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3365 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3366 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3367 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3368 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3369 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3370 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3371 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3372 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3373 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3374 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3375 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3376 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3378 /* also handle MIDI SPP because its so common */
3380 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3381 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3382 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));