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"
58 #include "midi++/manager.h"
60 #include "pbd/boost_debug.h"
61 #include "pbd/controllable_descriptor.h"
62 #include "pbd/enumwriter.h"
63 #include "pbd/error.h"
64 #include "pbd/pathscanner.h"
65 #include "pbd/pthread_utils.h"
66 #include "pbd/search_path.h"
67 #include "pbd/stacktrace.h"
68 #include "pbd/convert.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 ();
281 /* Create MIDI control ports */
283 MIDI::Manager* m = MIDI::Manager::instance ();
285 _mtc_input_port = m->add_port (new MIDI::Port ("MTC", O_RDONLY, _engine.jack()));
286 _mtc_output_port = m->add_port (new MIDI::Port ("MTC", O_WRONLY, _engine.jack()));
287 _midi_input_port = m->add_port (new MIDI::Port ("MIDI control", O_RDONLY, _engine.jack()));
288 _midi_output_port = m->add_port (new MIDI::Port ("MIDI control", O_WRONLY, _engine.jack()));
289 _midi_clock_input_port = m->add_port (new MIDI::Port ("MIDI clock", O_RDONLY, _engine.jack()));
290 _midi_clock_output_port = m->add_port (new MIDI::Port ("MIDI clock", O_WRONLY, _engine.jack()));
294 Session::second_stage_init ()
296 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
299 if (load_state (_current_snapshot_name)) {
302 remove_empty_sounds ();
305 if (_butler->start_thread()) {
309 if (start_midi_thread ()) {
313 setup_midi_machine_control ();
315 // set_state() will call setup_raid_path(), but if it's a new session we need
316 // to call setup_raid_path() here.
319 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
323 setup_raid_path(_path);
326 /* we can't save till after ::when_engine_running() is called,
327 because otherwise we save state with no connections made.
328 therefore, we reset _state_of_the_state because ::set_state()
329 will have cleared it.
331 we also have to include Loading so that any events that get
332 generated between here and the end of ::when_engine_running()
333 will be processed directly rather than queued.
336 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
338 _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
339 _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
340 setup_click_sounds (0);
341 setup_midi_control ();
343 /* Pay attention ... */
345 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
346 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
349 when_engine_running ();
352 /* handle this one in a different way than all others, so that its clear what happened */
354 catch (AudioEngine::PortRegistrationFailure& err) {
355 error << err.what() << endmsg;
363 BootMessage (_("Reset Remote Controls"));
365 send_full_time_code (0);
366 _engine.transport_locate (0);
368 _mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
369 _mmc->send (MIDI::MachineControlCommand (Timecode::Time ()));
371 MidiClockTicker::instance().set_session (this);
372 MIDI::Name::MidiPatchManager::instance().set_session (this);
374 /* initial program change will be delivered later; see ::config_changed() */
376 BootMessage (_("Reset Control Protocols"));
378 ControlProtocolManager::instance().set_session (this);
380 _state_of_the_state = Clean;
382 Port::set_connecting_blocked (false);
384 DirtyChanged (); /* EMIT SIGNAL */
386 if (state_was_pending) {
387 save_state (_current_snapshot_name);
388 remove_pending_capture_state ();
389 state_was_pending = false;
392 BootMessage (_("Session loading complete"));
398 Session::raid_path () const
400 SearchPath raid_search_path;
402 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
403 raid_search_path += sys::path((*i).path);
406 return raid_search_path.to_string ();
410 Session::setup_raid_path (string path)
419 session_dirs.clear ();
421 SearchPath search_path(path);
422 SearchPath sound_search_path;
423 SearchPath midi_search_path;
425 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
426 sp.path = (*i).to_string ();
427 sp.blocks = 0; // not needed
428 session_dirs.push_back (sp);
430 SessionDirectory sdir(sp.path);
432 sound_search_path += sdir.sound_path ();
433 midi_search_path += sdir.midi_path ();
436 // set the search path for each data type
437 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
438 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
440 // reset the round-robin soundfile path thingie
441 last_rr_session_dir = session_dirs.begin();
445 Session::path_is_within_session (const std::string& path)
447 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
448 if (path.find ((*i).path) == 0) {
456 Session::ensure_subdirs ()
460 dir = session_directory().peak_path().to_string();
462 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
463 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
467 dir = session_directory().sound_path().to_string();
469 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
470 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
474 dir = session_directory().midi_path().to_string();
476 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
477 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
481 dir = session_directory().dead_sound_path().to_string();
483 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
484 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
488 dir = session_directory().export_path().to_string();
490 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
491 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
495 dir = analysis_dir ();
497 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
498 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
506 Session::create (const string& mix_template, BusProfile* bus_profile)
509 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
510 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
514 if (ensure_subdirs ()) {
518 if (!mix_template.empty()) {
519 std::string in_path = mix_template;
521 ifstream in(in_path.c_str());
524 string out_path = _path;
526 out_path += statefile_suffix;
528 ofstream out(out_path.c_str());
536 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
542 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
549 /* Instantiate metadata */
551 _metadata = new SessionMetadata ();
553 /* set initial start + end point */
555 _state_of_the_state = Clean;
557 /* set up Master Out and Control Out if necessary */
563 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
565 if (bus_profile->master_out_channels) {
566 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
571 boost_debug_shared_ptr_mark_interesting (rt, "Route");
572 boost::shared_ptr<Route> r (rt);
573 r->input()->ensure_io (count, false, this);
574 r->output()->ensure_io (count, false, this);
575 r->set_remote_control_id (control_id++);
579 if (Config->get_use_monitor_bus()) {
580 Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO);
585 boost_debug_shared_ptr_mark_interesting (rt, "Route");
586 boost::shared_ptr<Route> r (rt);
587 r->input()->ensure_io (count, false, this);
588 r->output()->ensure_io (count, false, this);
589 r->set_remote_control_id (control_id);
595 /* prohibit auto-connect to master, because there isn't one */
596 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
600 add_routes (rl, false);
603 /* this allows the user to override settings with an environment variable.
606 if (no_auto_connect()) {
607 bus_profile->input_ac = AutoConnectOption (0);
608 bus_profile->output_ac = AutoConnectOption (0);
611 Config->set_input_auto_connect (bus_profile->input_ac);
612 Config->set_output_auto_connect (bus_profile->output_ac);
621 Session::maybe_write_autosave()
623 if (dirty() && record_status() != Recording) {
624 save_state("", true);
629 Session::remove_pending_capture_state ()
631 sys::path pending_state_file_path(_session_dir->root_path());
633 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
637 sys::remove (pending_state_file_path);
639 catch(sys::filesystem_error& ex)
641 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
642 pending_state_file_path.to_string(), ex.what()) << endmsg;
646 /** Rename a state file.
647 * @param snapshot_name Snapshot name.
650 Session::rename_state (string old_name, string new_name)
652 if (old_name == _current_snapshot_name || old_name == _name) {
653 /* refuse to rename the current snapshot or the "main" one */
657 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
658 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
660 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
661 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
665 sys::rename (old_xml_path, new_xml_path);
667 catch (const sys::filesystem_error& err)
669 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
670 old_name, new_name, err.what()) << endmsg;
674 /** Remove a state file.
675 * @param snapshot_name Snapshot name.
678 Session::remove_state (string snapshot_name)
680 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
681 // refuse to remove the current snapshot or the "main" one
685 sys::path xml_path(_session_dir->root_path());
687 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
689 if (!create_backup_file (xml_path)) {
690 // don't remove it if a backup can't be made
691 // create_backup_file will log the error.
696 sys::remove (xml_path);
699 #ifdef HAVE_JACK_SESSION
701 Session::jack_session_event (jack_session_event_t * event)
705 struct tm local_time;
708 localtime_r (&n, &local_time);
709 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
711 if (event->type == JackSessionSaveTemplate)
713 if (save_template( timebuf )) {
714 event->flags = JackSessionSaveError;
716 string cmd ("ardour3 -P -U ");
717 cmd += event->client_uuid;
721 event->command_line = strdup (cmd.c_str());
726 if (save_state (timebuf)) {
727 event->flags = JackSessionSaveError;
729 sys::path xml_path (_session_dir->root_path());
730 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
732 string cmd ("ardour3 -P -U ");
733 cmd += event->client_uuid;
735 cmd += xml_path.to_string();
738 event->command_line = strdup (cmd.c_str());
742 jack_session_reply (_engine.jack(), event);
744 if (event->type == JackSessionSaveAndQuit) {
745 // TODO: make ardour quit.
748 jack_session_event_free( event );
753 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
756 sys::path xml_path(_session_dir->root_path());
758 if (!_writable || (_state_of_the_state & CannotSave)) {
762 if (!_engine.connected ()) {
763 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
769 /* tell sources we're saving first, in case they write out to a new file
770 * which should be saved with the state rather than the old one */
771 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
772 i->second->session_saved();
775 tree.set_root (&get_state());
777 if (snapshot_name.empty()) {
778 snapshot_name = _current_snapshot_name;
779 } else if (switch_to_snapshot) {
780 _current_snapshot_name = snapshot_name;
785 /* proper save: use statefile_suffix (.ardour in English) */
787 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
789 /* make a backup copy of the old file */
791 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
792 // create_backup_file will log the error
798 /* pending save: use pending_suffix (.pending in English) */
799 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
802 sys::path tmp_path(_session_dir->root_path());
804 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
806 // cerr << "actually writing state to " << xml_path.to_string() << endl;
808 if (!tree.write (tmp_path.to_string())) {
809 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
810 sys::remove (tmp_path);
815 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
816 error << string_compose (_("could not rename temporary session file %1 to %2"),
817 tmp_path.to_string(), xml_path.to_string()) << endmsg;
818 sys::remove (tmp_path);
825 save_history (snapshot_name);
827 bool was_dirty = dirty();
829 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
832 DirtyChanged (); /* EMIT SIGNAL */
835 StateSaved (snapshot_name); /* EMIT SIGNAL */
842 Session::restore_state (string snapshot_name)
844 if (load_state (snapshot_name) == 0) {
845 set_state (*state_tree->root(), Stateful::loading_state_version);
852 Session::load_state (string snapshot_name)
857 state_was_pending = false;
859 /* check for leftover pending state from a crashed capture attempt */
861 sys::path xmlpath(_session_dir->root_path());
862 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
864 if (sys::exists (xmlpath)) {
866 /* there is pending state from a crashed capture attempt */
868 boost::optional<int> r = AskAboutPendingState();
869 if (r.get_value_or (1)) {
870 state_was_pending = true;
874 if (!state_was_pending) {
875 xmlpath = _session_dir->root_path();
876 xmlpath /= snapshot_name;
879 if (!sys::exists (xmlpath)) {
880 xmlpath = _session_dir->root_path();
881 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
882 if (!sys::exists (xmlpath)) {
883 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
888 state_tree = new XMLTree;
892 /* writable() really reflects the whole folder, but if for any
893 reason the session state file can't be written to, still
897 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
901 if (!state_tree->read (xmlpath.to_string())) {
902 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
908 XMLNode& root (*state_tree->root());
910 if (root.name() != X_("Session")) {
911 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
917 const XMLProperty* prop;
919 if ((prop = root.property ("version")) == 0) {
920 /* no version implies very old version of Ardour */
921 Stateful::loading_state_version = 1000;
927 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
928 Stateful::loading_state_version = (major * 1000) + minor;
931 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
933 sys::path backup_path(_session_dir->root_path());
935 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
937 // only create a backup once
938 if (sys::exists (backup_path)) {
942 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
943 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
948 sys::copy_file (xmlpath, backup_path);
950 catch(sys::filesystem_error& ex)
952 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
953 xmlpath.to_string(), ex.what())
963 Session::load_options (const XMLNode& node)
965 LocaleGuard lg (X_("POSIX"));
966 config.set_variables (node);
977 Session::get_template()
979 /* if we don't disable rec-enable, diskstreams
980 will believe they need to store their capture
981 sources in their state node.
984 disable_record (false);
990 Session::state(bool full_state)
992 XMLNode* node = new XMLNode("Session");
995 // store libardour version, just in case
997 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
998 node->add_property("version", string(buf));
1000 /* store configuration settings */
1004 node->add_property ("name", _name);
1005 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
1006 node->add_property ("sample-rate", buf);
1008 if (session_dirs.size() > 1) {
1012 vector<space_and_path>::iterator i = session_dirs.begin();
1013 vector<space_and_path>::iterator next;
1015 ++i; /* skip the first one */
1019 while (i != session_dirs.end()) {
1023 if (next != session_dirs.end()) {
1033 child = node->add_child ("Path");
1034 child->add_content (p);
1038 /* save the ID counter */
1040 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1041 node->add_property ("id-counter", buf);
1043 /* various options */
1045 node->add_child_nocopy (config.get_variables ());
1047 node->add_child_nocopy (_metadata->get_state());
1049 child = node->add_child ("Sources");
1052 Glib::Mutex::Lock sl (source_lock);
1054 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1056 /* Don't save information about non-destructive file sources that are empty
1057 and unused by any regions.
1060 boost::shared_ptr<FileSource> fs;
1061 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1062 if (!fs->destructive()) {
1063 if (fs->empty() && !fs->used()) {
1069 child->add_child_nocopy (siter->second->get_state());
1073 child = node->add_child ("Regions");
1076 Glib::Mutex::Lock rl (region_lock);
1077 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1078 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1079 boost::shared_ptr<Region> r = i->second;
1080 /* only store regions not attached to playlists */
1081 if (r->playlist() == 0) {
1082 child->add_child_nocopy (r->state (true));
1088 node->add_child_nocopy (_locations.get_state());
1090 // for a template, just create a new Locations, populate it
1091 // with the default start and end, and get the state for that.
1093 Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
1094 range->set (max_frames, 0);
1096 node->add_child_nocopy (loc.get_state());
1099 child = node->add_child ("Bundles");
1101 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1102 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1103 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1105 child->add_child_nocopy (b->get_state());
1110 child = node->add_child ("Routes");
1112 boost::shared_ptr<RouteList> r = routes.reader ();
1114 RoutePublicOrderSorter cmp;
1115 RouteList public_order (*r);
1116 public_order.sort (cmp);
1118 /* the sort should have put control outs first */
1121 assert (_monitor_out == public_order.front());
1124 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1125 if (!(*i)->is_hidden()) {
1127 child->add_child_nocopy ((*i)->get_state());
1129 child->add_child_nocopy ((*i)->get_template());
1135 playlists->add_state (node, full_state);
1137 child = node->add_child ("RouteGroups");
1138 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1139 child->add_child_nocopy ((*i)->get_state());
1143 child = node->add_child ("Click");
1144 child->add_child_nocopy (_click_io->state (full_state));
1148 child = node->add_child ("NamedSelections");
1149 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1151 child->add_child_nocopy ((*i)->get_state());
1156 node->add_child_nocopy (_tempo_map->get_state());
1158 node->add_child_nocopy (get_control_protocol_state());
1161 node->add_child_copy (*_extra_xml);
1168 Session::get_control_protocol_state ()
1170 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1171 return cpm.get_state();
1175 Session::set_state (const XMLNode& node, int version)
1179 const XMLProperty* prop;
1182 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1184 if (node.name() != X_("Session")){
1185 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1189 if ((prop = node.property ("version")) != 0) {
1190 version = atoi (prop->value ()) * 1000;
1193 if ((prop = node.property ("name")) != 0) {
1194 _name = prop->value ();
1197 if ((prop = node.property (X_("sample-rate"))) != 0) {
1199 _nominal_frame_rate = atoi (prop->value());
1201 if (_nominal_frame_rate != _current_frame_rate) {
1202 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1203 if (r.get_value_or (0)) {
1209 setup_raid_path(_session_dir->root_path().to_string());
1211 if ((prop = node.property (X_("id-counter"))) != 0) {
1213 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1214 ID::init_counter (x);
1216 /* old sessions used a timebased counter, so fake
1217 the startup ID counter based on a standard
1222 ID::init_counter (now);
1226 IO::disable_connecting ();
1228 /* Object loading order:
1233 MIDI Control // relies on data from Options/Config
1246 if ((child = find_named_node (node, "Extra")) != 0) {
1247 _extra_xml = new XMLNode (*child);
1250 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1251 load_options (*child);
1252 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1253 load_options (*child);
1255 error << _("Session: XML state has no options section") << endmsg;
1258 if (version >= 3000) {
1259 if ((child = find_named_node (node, "Metadata")) == 0) {
1260 warning << _("Session: XML state has no metadata section") << endmsg;
1261 } else if (_metadata->set_state (*child, version)) {
1266 if ((child = find_named_node (node, "Locations")) == 0) {
1267 error << _("Session: XML state has no locations section") << endmsg;
1269 } else if (_locations.set_state (*child, version)) {
1275 if ((location = _locations.auto_loop_location()) != 0) {
1276 set_auto_loop_location (location);
1279 if ((location = _locations.auto_punch_location()) != 0) {
1280 set_auto_punch_location (location);
1283 if ((location = _locations.session_range_location()) != 0) {
1284 delete _session_range_location;
1285 _session_range_location = location;
1288 if (_session_range_location) {
1289 AudioFileSource::set_header_position_offset (_session_range_location->start());
1292 if ((child = find_named_node (node, "Sources")) == 0) {
1293 error << _("Session: XML state has no sources section") << endmsg;
1295 } else if (load_sources (*child)) {
1299 if ((child = find_named_node (node, "Regions")) == 0) {
1300 error << _("Session: XML state has no Regions section") << endmsg;
1302 } else if (load_regions (*child)) {
1306 if ((child = find_named_node (node, "Playlists")) == 0) {
1307 error << _("Session: XML state has no playlists section") << endmsg;
1309 } else if (playlists->load (*this, *child)) {
1313 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1315 } else if (playlists->load_unused (*this, *child)) {
1319 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1320 if (load_named_selections (*child)) {
1325 if (version >= 3000) {
1326 if ((child = find_named_node (node, "Bundles")) == 0) {
1327 warning << _("Session: XML state has no bundles section") << endmsg;
1330 /* We can't load Bundles yet as they need to be able
1331 to convert from port names to Port objects, which can't happen until
1333 _bundle_xml_node = new XMLNode (*child);
1337 if ((child = find_named_node (node, "TempoMap")) == 0) {
1338 error << _("Session: XML state has no Tempo Map section") << endmsg;
1340 } else if (_tempo_map->set_state (*child, version)) {
1344 if (version < 3000) {
1345 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1346 error << _("Session: XML state has no diskstreams section") << endmsg;
1348 } else if (load_diskstreams_2X (*child, version)) {
1353 if ((child = find_named_node (node, "Routes")) == 0) {
1354 error << _("Session: XML state has no routes section") << endmsg;
1356 } else if (load_routes (*child, version)) {
1360 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1361 _diskstreams_2X.clear ();
1363 if (version >= 3000) {
1365 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1366 error << _("Session: XML state has no route groups section") << endmsg;
1368 } else if (load_route_groups (*child, version)) {
1372 } else if (version < 3000) {
1374 if ((child = find_named_node (node, "EditGroups")) == 0) {
1375 error << _("Session: XML state has no edit groups section") << endmsg;
1377 } else if (load_route_groups (*child, version)) {
1381 if ((child = find_named_node (node, "MixGroups")) == 0) {
1382 error << _("Session: XML state has no mix groups section") << endmsg;
1384 } else if (load_route_groups (*child, version)) {
1389 if ((child = find_named_node (node, "Click")) == 0) {
1390 warning << _("Session: XML state has no click section") << endmsg;
1391 } else if (_click_io) {
1392 _click_io->set_state (*child, version);
1395 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1396 ControlProtocolManager::instance().set_protocol_states (*child);
1399 /* here beginneth the second phase ... */
1401 StateReady (); /* EMIT SIGNAL */
1410 Session::load_routes (const XMLNode& node, int version)
1413 XMLNodeConstIterator niter;
1414 RouteList new_routes;
1416 nlist = node.children();
1420 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1422 boost::shared_ptr<Route> route;
1423 if (version < 3000) {
1424 route = XMLRouteFactory_2X (**niter, version);
1426 route = XMLRouteFactory (**niter, version);
1430 error << _("Session: cannot create Route from XML description.") << endmsg;
1434 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1436 new_routes.push_back (route);
1439 add_routes (new_routes, false);
1444 boost::shared_ptr<Route>
1445 Session::XMLRouteFactory (const XMLNode& node, int version)
1447 boost::shared_ptr<Route> ret;
1449 if (node.name() != "Route") {
1453 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1455 DataType type = DataType::AUDIO;
1456 const XMLProperty* prop = node.property("default-type");
1459 type = DataType (prop->value());
1462 assert (type != DataType::NIL);
1468 if (type == DataType::AUDIO) {
1469 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1472 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1475 if (track->init()) {
1480 if (track->set_state (node, version)) {
1485 boost_debug_shared_ptr_mark_interesting (track, "Track");
1489 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1491 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1492 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1502 boost::shared_ptr<Route>
1503 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1505 boost::shared_ptr<Route> ret;
1507 if (node.name() != "Route") {
1511 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1513 ds_prop = node.property (X_("diskstream"));
1516 DataType type = DataType::AUDIO;
1517 const XMLProperty* prop = node.property("default-type");
1520 type = DataType (prop->value());
1523 assert (type != DataType::NIL);
1527 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1528 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1532 if (i == _diskstreams_2X.end()) {
1533 error << _("Could not find diskstream for route") << endmsg;
1534 return boost::shared_ptr<Route> ();
1539 if (type == DataType::AUDIO) {
1540 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1543 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1546 if (track->init()) {
1551 if (track->set_state (node, version)) {
1556 track->set_diskstream (*i);
1558 boost_debug_shared_ptr_mark_interesting (track, "Track");
1562 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1564 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1565 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1576 Session::load_regions (const XMLNode& node)
1579 XMLNodeConstIterator niter;
1580 boost::shared_ptr<Region> region;
1582 nlist = node.children();
1586 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1587 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1588 error << _("Session: cannot create Region from XML description.");
1589 const XMLProperty *name = (**niter).property("name");
1592 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1602 boost::shared_ptr<Region>
1603 Session::XMLRegionFactory (const XMLNode& node, bool full)
1605 const XMLProperty* type = node.property("type");
1609 if ( !type || type->value() == "audio" ) {
1611 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1613 } else if (type->value() == "midi") {
1615 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1619 } catch (failed_constructor& err) {
1620 return boost::shared_ptr<Region> ();
1623 return boost::shared_ptr<Region> ();
1626 boost::shared_ptr<AudioRegion>
1627 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1629 const XMLProperty* prop;
1630 boost::shared_ptr<Source> source;
1631 boost::shared_ptr<AudioSource> as;
1633 SourceList master_sources;
1634 uint32_t nchans = 1;
1637 if (node.name() != X_("Region")) {
1638 return boost::shared_ptr<AudioRegion>();
1641 if ((prop = node.property (X_("channels"))) != 0) {
1642 nchans = atoi (prop->value().c_str());
1645 if ((prop = node.property ("name")) == 0) {
1646 cerr << "no name for this region\n";
1650 if ((prop = node.property (X_("source-0"))) == 0) {
1651 if ((prop = node.property ("source")) == 0) {
1652 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1653 return boost::shared_ptr<AudioRegion>();
1657 PBD::ID s_id (prop->value());
1659 if ((source = source_by_id (s_id)) == 0) {
1660 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1661 return boost::shared_ptr<AudioRegion>();
1664 as = boost::dynamic_pointer_cast<AudioSource>(source);
1666 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1667 return boost::shared_ptr<AudioRegion>();
1670 sources.push_back (as);
1672 /* pickup other channels */
1674 for (uint32_t n=1; n < nchans; ++n) {
1675 snprintf (buf, sizeof(buf), X_("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 sources.push_back (as);
1694 for (uint32_t n = 0; n < nchans; ++n) {
1695 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1696 if ((prop = node.property (buf)) != 0) {
1698 PBD::ID id2 (prop->value());
1700 if ((source = source_by_id (id2)) == 0) {
1701 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1702 return boost::shared_ptr<AudioRegion>();
1705 as = boost::dynamic_pointer_cast<AudioSource>(source);
1707 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1708 return boost::shared_ptr<AudioRegion>();
1710 master_sources.push_back (as);
1715 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1717 /* a final detail: this is the one and only place that we know how long missing files are */
1719 if (region->whole_file()) {
1720 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1721 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1723 sfp->set_length (region->length());
1728 if (!master_sources.empty()) {
1729 if (master_sources.size() != nchans) {
1730 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1732 region->set_master_sources (master_sources);
1740 catch (failed_constructor& err) {
1741 return boost::shared_ptr<AudioRegion>();
1745 boost::shared_ptr<MidiRegion>
1746 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1748 const XMLProperty* prop;
1749 boost::shared_ptr<Source> source;
1750 boost::shared_ptr<MidiSource> ms;
1752 uint32_t nchans = 1;
1754 if (node.name() != X_("Region")) {
1755 return boost::shared_ptr<MidiRegion>();
1758 if ((prop = node.property (X_("channels"))) != 0) {
1759 nchans = atoi (prop->value().c_str());
1762 if ((prop = node.property ("name")) == 0) {
1763 cerr << "no name for this region\n";
1767 // Multiple midi channels? that's just crazy talk
1768 assert(nchans == 1);
1770 if ((prop = node.property (X_("source-0"))) == 0) {
1771 if ((prop = node.property ("source")) == 0) {
1772 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1773 return boost::shared_ptr<MidiRegion>();
1777 PBD::ID s_id (prop->value());
1779 if ((source = source_by_id (s_id)) == 0) {
1780 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1781 return boost::shared_ptr<MidiRegion>();
1784 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1786 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1787 return boost::shared_ptr<MidiRegion>();
1790 sources.push_back (ms);
1793 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1794 /* a final detail: this is the one and only place that we know how long missing files are */
1796 if (region->whole_file()) {
1797 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1798 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1800 sfp->set_length (region->length());
1808 catch (failed_constructor& err) {
1809 return boost::shared_ptr<MidiRegion>();
1814 Session::get_sources_as_xml ()
1817 XMLNode* node = new XMLNode (X_("Sources"));
1818 Glib::Mutex::Lock lm (source_lock);
1820 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1821 node->add_child_nocopy (i->second->get_state());
1828 Session::path_from_region_name (DataType type, string name, string identifier)
1830 char buf[PATH_MAX+1];
1832 SessionDirectory sdir(get_best_session_directory_for_new_source());
1833 sys::path source_dir = ((type == DataType::AUDIO)
1834 ? sdir.sound_path() : sdir.midi_path());
1836 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1838 for (n = 0; n < 999999; ++n) {
1839 if (identifier.length()) {
1840 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1841 identifier.c_str(), n, ext.c_str());
1843 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1847 sys::path source_path = source_dir / buf;
1849 if (!sys::exists (source_path)) {
1850 return source_path.to_string();
1854 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1863 Session::load_sources (const XMLNode& node)
1866 XMLNodeConstIterator niter;
1867 boost::shared_ptr<Source> source;
1869 nlist = node.children();
1873 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1875 if ((source = XMLSourceFactory (**niter)) == 0) {
1876 error << _("Session: cannot create Source from XML description.") << endmsg;
1878 } catch (MissingSource& err) {
1879 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1880 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1887 boost::shared_ptr<Source>
1888 Session::XMLSourceFactory (const XMLNode& node)
1890 if (node.name() != "Source") {
1891 return boost::shared_ptr<Source>();
1895 /* note: do peak building in another thread when loading session state */
1896 return SourceFactory::create (*this, node, true);
1899 catch (failed_constructor& err) {
1900 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1901 return boost::shared_ptr<Source>();
1906 Session::save_template (string template_name)
1910 if (_state_of_the_state & CannotSave) {
1914 sys::path user_template_dir(user_template_directory());
1918 sys::create_directories (user_template_dir);
1920 catch(sys::filesystem_error& ex)
1922 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1923 user_template_dir.to_string(), ex.what()) << endmsg;
1927 tree.set_root (&get_template());
1929 sys::path template_file_path(user_template_dir);
1930 template_file_path /= template_name + template_suffix;
1932 if (sys::exists (template_file_path))
1934 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1935 template_file_path.to_string()) << endmsg;
1939 if (!tree.write (template_file_path.to_string())) {
1940 error << _("mix template not saved") << endmsg;
1948 Session::rename_template (string old_name, string new_name)
1950 sys::path old_path (user_template_directory());
1951 old_path /= old_name + template_suffix;
1953 sys::path new_path(user_template_directory());
1954 new_path /= new_name + template_suffix;
1956 if (sys::exists (new_path)) {
1957 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1958 new_path.to_string()) << endmsg;
1963 sys::rename (old_path, new_path);
1971 Session::delete_template (string name)
1973 sys::path path = user_template_directory();
1974 path /= name + template_suffix;
1985 Session::refresh_disk_space ()
1988 struct statfs statfsbuf;
1989 vector<space_and_path>::iterator i;
1990 Glib::Mutex::Lock lm (space_lock);
1993 /* get freespace on every FS that is part of the session path */
1995 _total_free_4k_blocks = 0;
1997 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1998 statfs ((*i).path.c_str(), &statfsbuf);
2000 scale = statfsbuf.f_bsize/4096.0;
2002 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2003 _total_free_4k_blocks += (*i).blocks;
2009 Session::get_best_session_directory_for_new_source ()
2011 vector<space_and_path>::iterator i;
2012 string result = _session_dir->root_path().to_string();
2014 /* handle common case without system calls */
2016 if (session_dirs.size() == 1) {
2020 /* OK, here's the algorithm we're following here:
2022 We want to select which directory to use for
2023 the next file source to be created. Ideally,
2024 we'd like to use a round-robin process so as to
2025 get maximum performance benefits from splitting
2026 the files across multiple disks.
2028 However, in situations without much diskspace, an
2029 RR approach may end up filling up a filesystem
2030 with new files while others still have space.
2031 Its therefore important to pay some attention to
2032 the freespace in the filesystem holding each
2033 directory as well. However, if we did that by
2034 itself, we'd keep creating new files in the file
2035 system with the most space until it was as full
2036 as all others, thus negating any performance
2037 benefits of this RAID-1 like approach.
2039 So, we use a user-configurable space threshold. If
2040 there are at least 2 filesystems with more than this
2041 much space available, we use RR selection between them.
2042 If not, then we pick the filesystem with the most space.
2044 This gets a good balance between the two
2048 refresh_disk_space ();
2050 int free_enough = 0;
2052 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2053 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2058 if (free_enough >= 2) {
2059 /* use RR selection process, ensuring that the one
2063 i = last_rr_session_dir;
2066 if (++i == session_dirs.end()) {
2067 i = session_dirs.begin();
2070 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2071 if (create_session_directory ((*i).path)) {
2073 last_rr_session_dir = i;
2078 } while (i != last_rr_session_dir);
2082 /* pick FS with the most freespace (and that
2083 seems to actually work ...)
2086 vector<space_and_path> sorted;
2087 space_and_path_ascending_cmp cmp;
2089 sorted = session_dirs;
2090 sort (sorted.begin(), sorted.end(), cmp);
2092 for (i = sorted.begin(); i != sorted.end(); ++i) {
2093 if (create_session_directory ((*i).path)) {
2095 last_rr_session_dir = i;
2105 Session::load_named_selections (const XMLNode& node)
2108 XMLNodeConstIterator niter;
2111 nlist = node.children();
2115 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2117 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2118 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2126 Session::XMLNamedSelectionFactory (const XMLNode& node)
2129 return new NamedSelection (*this, node);
2132 catch (failed_constructor& err) {
2138 Session::automation_dir () const
2140 return Glib::build_filename (_path, "automation");
2144 Session::analysis_dir () const
2146 return Glib::build_filename (_path, "analysis");
2150 Session::load_bundles (XMLNode const & node)
2152 XMLNodeList nlist = node.children();
2153 XMLNodeConstIterator niter;
2157 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2158 if ((*niter)->name() == "InputBundle") {
2159 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2160 } else if ((*niter)->name() == "OutputBundle") {
2161 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2163 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2172 Session::load_route_groups (const XMLNode& node, int version)
2174 XMLNodeList nlist = node.children();
2175 XMLNodeConstIterator niter;
2179 if (version >= 3000) {
2181 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2182 if ((*niter)->name() == "RouteGroup") {
2183 RouteGroup* rg = new RouteGroup (*this, "");
2184 add_route_group (rg);
2185 rg->set_state (**niter, version);
2189 } else if (version < 3000) {
2191 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2192 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2193 RouteGroup* rg = new RouteGroup (*this, "");
2194 add_route_group (rg);
2195 rg->set_state (**niter, version);
2204 Session::auto_save()
2206 save_state (_current_snapshot_name);
2210 state_file_filter (const string &str, void */*arg*/)
2212 return (str.length() > strlen(statefile_suffix) &&
2213 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2217 bool operator()(const string* a, const string* b) {
2223 remove_end(string* state)
2225 string statename(*state);
2227 string::size_type start,end;
2228 if ((start = statename.find_last_of ('/')) != string::npos) {
2229 statename = statename.substr (start+1);
2232 if ((end = statename.rfind(".ardour")) == string::npos) {
2233 end = statename.length();
2236 return new string(statename.substr (0, end));
2240 Session::possible_states (string path)
2242 PathScanner scanner;
2243 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2245 transform(states->begin(), states->end(), states->begin(), remove_end);
2248 sort (states->begin(), states->end(), cmp);
2254 Session::possible_states () const
2256 return possible_states(_path);
2260 Session::add_route_group (RouteGroup* g)
2262 _route_groups.push_back (g);
2263 route_group_added (g); /* EMIT SIGNAL */
2265 g->MembershipChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2266 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2272 Session::remove_route_group (RouteGroup& rg)
2274 list<RouteGroup*>::iterator i;
2276 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2277 _route_groups.erase (i);
2280 route_group_removed (); /* EMIT SIGNAL */
2286 Session::route_group_by_name (string name)
2288 list<RouteGroup *>::iterator i;
2290 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2291 if ((*i)->name() == name) {
2299 Session::start_reversible_command (const string& name)
2301 UndoTransaction* trans = new UndoTransaction();
2302 trans->set_name(name);
2307 Session::finish_reversible_command (UndoTransaction& ut)
2310 gettimeofday(&now, 0);
2311 ut.set_timestamp(now);
2316 Session::begin_reversible_command(const string& name)
2318 UndoTransaction* trans = new UndoTransaction();
2319 trans->set_name(name);
2321 if (!_current_trans.empty()) {
2322 _current_trans.top()->add_command (trans);
2324 _current_trans.push(trans);
2329 Session::commit_reversible_command(Command *cmd)
2331 assert(!_current_trans.empty());
2335 _current_trans.top()->add_command(cmd);
2338 if (_current_trans.top()->empty()) {
2339 _current_trans.pop();
2343 gettimeofday(&now, 0);
2344 _current_trans.top()->set_timestamp(now);
2346 _history.add(_current_trans.top());
2347 _current_trans.pop();
2351 accept_all_non_peak_files (const string& path, void */*arg*/)
2353 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2357 accept_all_state_files (const string& path, void */*arg*/)
2359 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2363 Session::find_all_sources (string path, set<string>& result)
2368 if (!tree.read (path)) {
2372 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2377 XMLNodeConstIterator niter;
2379 nlist = node->children();
2383 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2387 if ((prop = (*niter)->property (X_("type"))) == 0) {
2391 DataType type (prop->value());
2393 if ((prop = (*niter)->property (X_("name"))) == 0) {
2397 if (prop->value()[0] == '/') {
2398 /* external file, ignore */
2402 Glib::ustring found_path;
2406 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2407 result.insert (found_path);
2415 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2417 PathScanner scanner;
2418 vector<string*>* state_files;
2420 string this_snapshot_path;
2426 if (ripped[ripped.length()-1] == '/') {
2427 ripped = ripped.substr (0, ripped.length() - 1);
2430 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2432 if (state_files == 0) {
2437 this_snapshot_path = _path;
2438 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2439 this_snapshot_path += statefile_suffix;
2441 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2443 if (exclude_this_snapshot && **i == this_snapshot_path) {
2447 if (find_all_sources (**i, result) < 0) {
2455 struct RegionCounter {
2456 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2457 AudioSourceList::iterator iter;
2458 boost::shared_ptr<Region> region;
2461 RegionCounter() : count (0) {}
2465 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2467 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2468 return r.get_value_or (1);
2472 Session::cleanup_sources (CleanupReport& rep)
2474 // FIXME: needs adaptation to midi
2476 vector<boost::shared_ptr<Source> > dead_sources;
2477 PathScanner scanner;
2479 vector<space_and_path>::iterator i;
2480 vector<space_and_path>::iterator nexti;
2481 vector<string*>* soundfiles;
2482 vector<string> unused;
2483 set<string> all_sources;
2488 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2490 /* step 1: consider deleting all unused playlists */
2492 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2497 /* step 2: find all un-used sources */
2502 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2504 SourceMap::iterator tmp;
2509 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2513 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2514 dead_sources.push_back (i->second);
2515 i->second->drop_references ();
2521 /* build a list of all the possible sound directories for the session */
2523 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2528 SessionDirectory sdir ((*i).path);
2529 sound_path += sdir.sound_path().to_string();
2531 if (nexti != session_dirs.end()) {
2538 /* now do the same thing for the files that ended up in the sounds dir(s)
2539 but are not referenced as sources in any snapshot.
2542 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2544 if (soundfiles == 0) {
2548 /* find all sources, but don't use this snapshot because the
2549 state file on disk still references sources we may have already
2553 find_all_sources_across_snapshots (all_sources, true);
2555 /* add our current source list
2558 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2559 boost::shared_ptr<FileSource> fs;
2561 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2562 all_sources.insert (fs->path());
2566 char tmppath1[PATH_MAX+1];
2567 char tmppath2[PATH_MAX+1];
2569 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2574 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2576 if (realpath(spath.c_str(), tmppath1) == 0) {
2577 error << string_compose (_("Cannot expand path %1 (%2)"),
2578 spath, strerror (errno)) << endmsg;
2582 if (realpath((*i).c_str(), tmppath2) == 0) {
2583 error << string_compose (_("Cannot expand path %1 (%2)"),
2584 (*i), strerror (errno)) << endmsg;
2588 if (strcmp(tmppath1, tmppath2) == 0) {
2595 unused.push_back (spath);
2599 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2601 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2602 struct stat statbuf;
2604 rep.paths.push_back (*x);
2605 if (stat ((*x).c_str(), &statbuf) == 0) {
2606 rep.space += statbuf.st_size;
2611 /* don't move the file across filesystems, just
2612 stick it in the `dead_sound_dir_name' directory
2613 on whichever filesystem it was already on.
2616 if ((*x).find ("/sounds/") != string::npos) {
2618 /* old school, go up 1 level */
2620 newpath = Glib::path_get_dirname (*x); // "sounds"
2621 newpath = Glib::path_get_dirname (newpath); // "session-name"
2625 /* new school, go up 4 levels */
2627 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2628 newpath = Glib::path_get_dirname (newpath); // "session-name"
2629 newpath = Glib::path_get_dirname (newpath); // "interchange"
2630 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2634 newpath += dead_sound_dir_name;
2636 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2637 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2642 newpath += Glib::path_get_basename ((*x));
2644 if (access (newpath.c_str(), F_OK) == 0) {
2646 /* the new path already exists, try versioning */
2648 char buf[PATH_MAX+1];
2652 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2655 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2656 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2660 if (version == 999) {
2661 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2665 newpath = newpath_v;
2670 /* it doesn't exist, or we can't read it or something */
2674 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2675 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2676 (*x), newpath, strerror (errno))
2681 /* see if there an easy to find peakfile for this file, and remove it.
2684 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2685 peakpath += peakfile_suffix;
2687 if (access (peakpath.c_str(), W_OK) == 0) {
2688 if (::unlink (peakpath.c_str()) != 0) {
2689 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2690 peakpath, _path, strerror (errno))
2692 /* try to back out */
2693 rename (newpath.c_str(), _path.c_str());
2701 /* dump the history list */
2705 /* save state so we don't end up a session file
2706 referring to non-existent sources.
2712 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2718 Session::cleanup_trash_sources (CleanupReport& rep)
2720 // FIXME: needs adaptation for MIDI
2722 vector<space_and_path>::iterator i;
2723 string dead_sound_dir;
2724 struct dirent* dentry;
2725 struct stat statbuf;
2731 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2733 dead_sound_dir = (*i).path;
2734 dead_sound_dir += dead_sound_dir_name;
2736 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2740 while ((dentry = readdir (dead)) != 0) {
2742 /* avoid '.' and '..' */
2744 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2745 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2751 fullpath = dead_sound_dir;
2753 fullpath += dentry->d_name;
2755 if (stat (fullpath.c_str(), &statbuf)) {
2759 if (!S_ISREG (statbuf.st_mode)) {
2763 if (unlink (fullpath.c_str())) {
2764 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2765 fullpath, strerror (errno))
2769 rep.paths.push_back (dentry->d_name);
2770 rep.space += statbuf.st_size;
2781 Session::set_dirty ()
2783 bool was_dirty = dirty();
2785 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2789 DirtyChanged(); /* EMIT SIGNAL */
2795 Session::set_clean ()
2797 bool was_dirty = dirty();
2799 _state_of_the_state = Clean;
2803 DirtyChanged(); /* EMIT SIGNAL */
2808 Session::set_deletion_in_progress ()
2810 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2814 Session::clear_deletion_in_progress ()
2816 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2820 Session::add_controllable (boost::shared_ptr<Controllable> c)
2822 /* this adds a controllable to the list managed by the Session.
2823 this is a subset of those managed by the Controllable class
2824 itself, and represents the only ones whose state will be saved
2825 as part of the session.
2828 Glib::Mutex::Lock lm (controllables_lock);
2829 controllables.insert (c);
2832 struct null_deleter { void operator()(void const *) const {} };
2835 Session::remove_controllable (Controllable* c)
2837 if (_state_of_the_state | Deletion) {
2841 Glib::Mutex::Lock lm (controllables_lock);
2843 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2845 if (x != controllables.end()) {
2846 controllables.erase (x);
2850 boost::shared_ptr<Controllable>
2851 Session::controllable_by_id (const PBD::ID& id)
2853 Glib::Mutex::Lock lm (controllables_lock);
2855 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2856 if ((*i)->id() == id) {
2861 return boost::shared_ptr<Controllable>();
2864 boost::shared_ptr<Controllable>
2865 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2867 boost::shared_ptr<Controllable> c;
2868 boost::shared_ptr<Route> r;
2870 switch (desc.top_level_type()) {
2871 case ControllableDescriptor::NamedRoute:
2873 std::string str = desc.top_level_name();
2874 if (str == "master") {
2876 } else if (str == "control" || str == "listen") {
2879 r = route_by_name (desc.top_level_name());
2884 case ControllableDescriptor::RemoteControlID:
2885 r = route_by_remote_id (desc.rid());
2893 switch (desc.subtype()) {
2894 case ControllableDescriptor::Gain:
2895 c = r->gain_control ();
2898 case ControllableDescriptor::Solo:
2899 c = r->solo_control();
2902 case ControllableDescriptor::Mute:
2903 c = r->mute_control();
2906 case ControllableDescriptor::Recenable:
2908 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2911 c = t->rec_enable_control ();
2916 case ControllableDescriptor::Pan:
2917 /* XXX pan control */
2920 case ControllableDescriptor::Balance:
2921 /* XXX simple pan control */
2924 case ControllableDescriptor::PluginParameter:
2926 uint32_t plugin = desc.target (0);
2927 uint32_t parameter_index = desc.target (1);
2929 /* revert to zero based counting */
2935 if (parameter_index > 0) {
2939 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
2942 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
2943 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
2948 case ControllableDescriptor::SendGain:
2950 uint32_t send = desc.target (0);
2952 /* revert to zero-based counting */
2958 boost::shared_ptr<Processor> p = r->nth_send (send);
2961 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
2962 boost::shared_ptr<Amp> a = s->amp();
2965 c = s->amp()->gain_control();
2972 /* relax and return a null pointer */
2980 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2983 Stateful::add_instant_xml (node, _path);
2986 if (write_to_config) {
2987 Config->add_instant_xml (node);
2992 Session::instant_xml (const string& node_name)
2994 return Stateful::instant_xml (node_name, _path);
2998 Session::save_history (string snapshot_name)
3006 if (snapshot_name.empty()) {
3007 snapshot_name = _current_snapshot_name;
3010 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3011 const string backup_filename = history_filename + backup_suffix;
3012 const sys::path xml_path = _session_dir->root_path() / history_filename;
3013 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3015 if (sys::exists (xml_path)) {
3018 sys::rename (xml_path, backup_path);
3020 catch (const sys::filesystem_error& err)
3022 error << _("could not backup old history file, current history not saved") << endmsg;
3027 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3031 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3033 if (!tree.write (xml_path.to_string()))
3035 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3039 sys::remove (xml_path);
3040 sys::rename (backup_path, xml_path);
3042 catch (const sys::filesystem_error& err)
3044 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3045 backup_path.to_string(), err.what()) << endmsg;
3055 Session::restore_history (string snapshot_name)
3059 if (snapshot_name.empty()) {
3060 snapshot_name = _current_snapshot_name;
3063 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3064 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3066 info << "Loading history from " << xml_path.to_string() << endmsg;
3068 if (!sys::exists (xml_path)) {
3069 info << string_compose (_("%1: no history file \"%2\" for this session."),
3070 _name, xml_path.to_string()) << endmsg;
3074 if (!tree.read (xml_path.to_string())) {
3075 error << string_compose (_("Could not understand session history file \"%1\""),
3076 xml_path.to_string()) << endmsg;
3083 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3086 UndoTransaction* ut = new UndoTransaction ();
3089 ut->set_name(t->property("name")->value());
3090 stringstream ss(t->property("tv-sec")->value());
3092 ss.str(t->property("tv-usec")->value());
3094 ut->set_timestamp(tv);
3096 for (XMLNodeConstIterator child_it = t->children().begin();
3097 child_it != t->children().end(); child_it++)
3099 XMLNode *n = *child_it;
3102 if (n->name() == "MementoCommand" ||
3103 n->name() == "MementoUndoCommand" ||
3104 n->name() == "MementoRedoCommand") {
3106 if ((c = memento_command_factory(n))) {
3110 } else if (n->name() == "DiffCommand") {
3111 PBD::ID id(n->property("midi-source")->value());
3112 boost::shared_ptr<MidiSource> midi_source =
3113 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3115 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
3117 error << _("Failed to downcast MidiSource for DiffCommand") << endmsg;
3120 } else if (n->name() == "StatefulDiffCommand") {
3121 if ((c = stateful_diff_command_factory (n))) {
3122 ut->add_command (c);
3125 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3136 Session::config_changed (std::string p, bool ours)
3142 if (p == "seamless-loop") {
3144 } else if (p == "rf-speed") {
3146 } else if (p == "auto-loop") {
3148 } else if (p == "auto-input") {
3150 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3151 /* auto-input only makes a difference if we're rolling */
3153 boost::shared_ptr<RouteList> rl = routes.reader ();
3154 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3155 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3156 if (tr && tr->record_enabled ()) {
3157 tr->monitor_input (!config.get_auto_input());
3162 } else if (p == "punch-in") {
3166 if ((location = _locations.auto_punch_location()) != 0) {
3168 if (config.get_punch_in ()) {
3169 replace_event (SessionEvent::PunchIn, location->start());
3171 remove_event (location->start(), SessionEvent::PunchIn);
3175 } else if (p == "punch-out") {
3179 if ((location = _locations.auto_punch_location()) != 0) {
3181 if (config.get_punch_out()) {
3182 replace_event (SessionEvent::PunchOut, location->end());
3184 clear_events (SessionEvent::PunchOut);
3188 } else if (p == "edit-mode") {
3190 Glib::Mutex::Lock lm (playlists->lock);
3192 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3193 (*i)->set_edit_mode (Config->get_edit_mode ());
3196 } else if (p == "use-video-sync") {
3198 waiting_for_sync_offset = config.get_use_video_sync();
3200 } else if (p == "mmc-control") {
3202 //poke_midi_thread ();
3204 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3206 _mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3208 } else if (p == "mmc-send-id") {
3210 _mmc->set_send_device_id (Config->get_mmc_send_device_id());
3212 } else if (p == "midi-control") {
3214 //poke_midi_thread ();
3216 } else if (p == "raid-path") {
3218 setup_raid_path (config.get_raid_path());
3220 } else if (p == "timecode-format") {
3224 } else if (p == "video-pullup") {
3228 } else if (p == "seamless-loop") {
3230 if (play_loop && transport_rolling()) {
3231 // to reset diskstreams etc
3232 request_play_loop (true);
3235 } else if (p == "rf-speed") {
3237 cumulative_rf_motion = 0;
3240 } else if (p == "click-sound") {
3242 setup_click_sounds (1);
3244 } else if (p == "click-emphasis-sound") {
3246 setup_click_sounds (-1);
3248 } else if (p == "clicking") {
3250 if (Config->get_clicking()) {
3251 if (_click_io && click_data) { // don't require emphasis data
3258 } else if (p == "send-mtc") {
3260 session_send_mtc = Config->get_send_mtc();
3261 if (session_send_mtc) {
3262 /* mark us ready to send */
3263 next_quarter_frame_to_send = 0;
3266 } else if (p == "send-mmc") {
3268 _mmc->enable_send (Config->get_send_mmc ());
3270 } else if (p == "midi-feedback") {
3272 session_midi_feedback = Config->get_midi_feedback();
3274 } else if (p == "jack-time-master") {
3276 engine().reset_timebase ();
3278 } else if (p == "native-file-header-format") {
3280 if (!first_file_header_format_reset) {
3281 reset_native_file_format ();
3284 first_file_header_format_reset = false;
3286 } else if (p == "native-file-data-format") {
3288 if (!first_file_data_format_reset) {
3289 reset_native_file_format ();
3292 first_file_data_format_reset = false;
3294 } else if (p == "external-sync") {
3295 if (!config.get_external_sync()) {
3296 drop_sync_source ();
3298 switch_to_sync_source (config.get_sync_source());
3300 } else if (p == "remote-model") {
3301 set_remote_control_ids ();
3302 } else if (p == "denormal-model") {
3304 } else if (p == "history-depth") {
3305 set_history_depth (Config->get_history_depth());
3306 } else if (p == "sync-all-route-ordering") {
3307 sync_order_keys ("session");
3308 } else if (p == "initial-program-change") {
3310 if (_mmc->output_port() && Config->get_initial_program_change() >= 0) {
3313 buf[0] = MIDI::program; // channel zero by default
3314 buf[1] = (Config->get_initial_program_change() & 0x7f);
3316 _mmc->output_port()->midimsg (buf, sizeof (buf), 0);
3318 } else if (p == "solo-mute-override") {
3319 // catch_up_on_solo_mute_override ();
3320 } else if (p == "listen-position") {
3321 listen_position_changed ();
3322 } else if (p == "solo-control-is-listen-control") {
3323 solo_control_mode_changed ();
3331 Session::set_history_depth (uint32_t d)
3333 _history.set_depth (d);
3337 Session::load_diskstreams_2X (XMLNode const & node, int)
3340 XMLNodeConstIterator citer;
3342 clist = node.children();
3344 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3347 /* diskstreams added automatically by DiskstreamCreated handler */
3348 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3349 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3350 _diskstreams_2X.push_back (dsp);
3352 error << _("Session: unknown diskstream type in XML") << endmsg;
3356 catch (failed_constructor& err) {
3357 error << _("Session: could not load diskstream via XML state") << endmsg;
3365 /** Create our MachineControl object and connect things to it */
3367 Session::setup_midi_machine_control ()
3369 _mmc = new MIDI::MachineControl (_engine.jack());
3371 _mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3372 _mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3373 _mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3374 _mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3375 _mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3376 _mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3377 _mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3378 _mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3379 _mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3380 _mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3381 _mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3382 _mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3383 _mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3385 /* also handle MIDI SPP because its so common */
3387 _mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3388 _mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3389 _mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));