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"
33 #include <cstdio> /* snprintf(3) ... grrr */
47 #include <sys/param.h>
48 #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/basename.h"
62 #include "pbd/controllable_descriptor.h"
63 #include "pbd/enumwriter.h"
64 #include "pbd/error.h"
65 #include "pbd/pathscanner.h"
66 #include "pbd/pthread_utils.h"
67 #include "pbd/search_path.h"
68 #include "pbd/stacktrace.h"
69 #include "pbd/convert.h"
70 #include "pbd/clear_dir.h"
72 #include "ardour/amp.h"
73 #include "ardour/audio_diskstream.h"
74 #include "ardour/audio_playlist_source.h"
75 #include "ardour/audio_track.h"
76 #include "ardour/audioengine.h"
77 #include "ardour/audiofilesource.h"
78 #include "ardour/audioplaylist.h"
79 #include "ardour/audioregion.h"
80 #include "ardour/auditioner.h"
81 #include "ardour/automation_control.h"
82 #include "ardour/buffer.h"
83 #include "ardour/butler.h"
84 #include "ardour/configuration.h"
85 #include "ardour/control_protocol_manager.h"
86 #include "ardour/crossfade.h"
87 #include "ardour/cycle_timer.h"
88 #include "ardour/directory_names.h"
89 #include "ardour/filename_extensions.h"
90 #include "ardour/io_processor.h"
91 #include "ardour/location.h"
92 #include "ardour/midi_diskstream.h"
93 #include "ardour/midi_patch_manager.h"
94 #include "ardour/midi_playlist.h"
95 #include "ardour/midi_region.h"
96 #include "ardour/midi_source.h"
97 #include "ardour/midi_track.h"
98 #include "ardour/named_selection.h"
99 #include "ardour/pannable.h"
100 #include "ardour/processor.h"
101 #include "ardour/port.h"
102 #include "ardour/proxy_controllable.h"
103 #include "ardour/region_factory.h"
104 #include "ardour/route_group.h"
105 #include "ardour/send.h"
106 #include "ardour/session.h"
107 #include "ardour/session_directory.h"
108 #include "ardour/session_metadata.h"
109 #include "ardour/session_state_utils.h"
110 #include "ardour/session_playlists.h"
111 #include "ardour/session_utils.h"
112 #include "ardour/silentfilesource.h"
113 #include "ardour/slave.h"
114 #include "ardour/smf_source.h"
115 #include "ardour/sndfile_helpers.h"
116 #include "ardour/sndfilesource.h"
117 #include "ardour/source_factory.h"
118 #include "ardour/template_utils.h"
119 #include "ardour/tempo.h"
120 #include "ardour/ticker.h"
121 #include "ardour/user_bundle.h"
122 #include "ardour/utils.h"
123 #include "ardour/utils.h"
124 #include "ardour/version.h"
125 #include "ardour/playlist_factory.h"
127 #include "control_protocol/control_protocol.h"
133 using namespace ARDOUR;
138 Session::first_stage_init (string fullpath, string snapshot_name)
140 if (fullpath.length() == 0) {
142 throw failed_constructor();
145 char buf[PATH_MAX+1];
146 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
147 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
149 throw failed_constructor();
154 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
155 _path += G_DIR_SEPARATOR;
158 /* these two are just provisional settings. set_state()
159 will likely override them.
162 _name = _current_snapshot_name = snapshot_name;
164 set_history_depth (Config->get_history_depth());
166 _current_frame_rate = _engine.frame_rate ();
167 _nominal_frame_rate = _current_frame_rate;
168 _base_frame_rate = _current_frame_rate;
170 _tempo_map = new TempoMap (_current_frame_rate);
171 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
174 _non_soloed_outs_muted = false;
176 _solo_isolated_cnt = 0;
177 g_atomic_int_set (&processing_prohibited, 0);
178 _transport_speed = 0;
179 _last_transport_speed = 0;
180 _target_transport_speed = 0;
181 auto_play_legal = false;
182 transport_sub_state = 0;
183 _transport_frame = 0;
184 _requested_return_frame = -1;
185 _session_range_location = 0;
186 g_atomic_int_set (&_record_status, Disabled);
187 loop_changing = false;
190 _last_roll_location = 0;
191 _last_roll_or_reversal_location = 0;
192 _last_record_location = 0;
193 pending_locate_frame = 0;
194 pending_locate_roll = false;
195 pending_locate_flush = false;
196 state_was_pending = false;
198 outbound_mtc_timecode_frame = 0;
199 next_quarter_frame_to_send = -1;
200 current_block_size = 0;
201 solo_update_disabled = false;
202 _have_captured = false;
203 _worst_output_latency = 0;
204 _worst_input_latency = 0;
205 _worst_track_latency = 0;
206 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
207 _was_seamless = Config->get_seamless_loop ();
209 _send_qf_mtc = false;
210 _pframes_since_last_mtc = 0;
211 g_atomic_int_set (&_playback_load, 100);
212 g_atomic_int_set (&_capture_load, 100);
215 pending_abort = false;
216 destructive_index = 0;
217 first_file_data_format_reset = true;
218 first_file_header_format_reset = true;
219 post_export_sync = false;
222 no_questions_about_missing_files = false;
223 _speakers.reset (new Speakers);
225 AudioDiskstream::allocate_working_buffers();
227 /* default short fade = 15ms */
229 Crossfade::set_short_xfade_length ((framecnt_t) floor (config.get_short_xfade_seconds() * frame_rate()));
230 SndFileSource::setup_standard_crossfades (*this, frame_rate());
232 last_mmc_step.tv_sec = 0;
233 last_mmc_step.tv_usec = 0;
236 /* click sounds are unset by default, which causes us to internal
237 waveforms for clicks.
241 click_emphasis_length = 0;
244 process_function = &Session::process_with_events;
246 if (config.get_use_video_sync()) {
247 waiting_for_sync_offset = true;
249 waiting_for_sync_offset = false;
252 last_timecode_when = 0;
253 last_timecode_valid = false;
257 last_rr_session_dir = session_dirs.begin();
258 refresh_disk_space ();
260 /* default: assume simple stereo speaker configuration */
262 _speakers->setup_default_speakers (2);
266 average_slave_delta = 1800; // !!! why 1800 ????
267 have_first_delta_accumulator = false;
268 delta_accumulator_cnt = 0;
269 _slave_state = Stopped;
271 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
272 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
273 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
274 add_controllable (_solo_cut_control);
276 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
278 /* These are all static "per-class" signals */
280 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
281 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
282 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
283 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
284 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
286 /* stop IO objects from doing stuff until we're ready for them */
288 Delivery::disable_panners ();
289 IO::disable_connecting ();
293 Session::second_stage_init ()
295 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
298 if (load_state (_current_snapshot_name)) {
303 if (_butler->start_thread()) {
307 if (start_midi_thread ()) {
311 setup_midi_machine_control ();
313 // set_state() will call setup_raid_path(), but if it's a new session we need
314 // to call setup_raid_path() here.
317 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
321 setup_raid_path(_path);
324 /* we can't save till after ::when_engine_running() is called,
325 because otherwise we save state with no connections made.
326 therefore, we reset _state_of_the_state because ::set_state()
327 will have cleared it.
329 we also have to include Loading so that any events that get
330 generated between here and the end of ::when_engine_running()
331 will be processed directly rather than queued.
334 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
336 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
337 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
338 setup_click_sounds (0);
339 setup_midi_control ();
341 /* Pay attention ... */
343 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
344 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
347 when_engine_running ();
350 /* handle this one in a different way than all others, so that its clear what happened */
352 catch (AudioEngine::PortRegistrationFailure& err) {
353 error << err.what() << endmsg;
361 BootMessage (_("Reset Remote Controls"));
363 send_full_time_code (0);
364 _engine.transport_locate (0);
366 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
367 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
369 MidiClockTicker::instance().set_session (this);
370 MIDI::Name::MidiPatchManager::instance().set_session (this);
372 /* initial program change will be delivered later; see ::config_changed() */
374 _state_of_the_state = Clean;
376 Port::set_connecting_blocked (false);
378 DirtyChanged (); /* EMIT SIGNAL */
380 if (state_was_pending) {
381 save_state (_current_snapshot_name);
382 remove_pending_capture_state ();
383 state_was_pending = false;
386 BootMessage (_("Session loading complete"));
392 Session::raid_path () const
394 SearchPath raid_search_path;
396 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
397 raid_search_path += sys::path((*i).path);
400 return raid_search_path.to_string ();
404 Session::setup_raid_path (string path)
413 session_dirs.clear ();
415 SearchPath search_path(path);
416 SearchPath sound_search_path;
417 SearchPath midi_search_path;
419 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
420 sp.path = (*i).to_string ();
421 sp.blocks = 0; // not needed
422 session_dirs.push_back (sp);
424 SessionDirectory sdir(sp.path);
426 sound_search_path += sdir.sound_path ();
427 midi_search_path += sdir.midi_path ();
430 // reset the round-robin soundfile path thingie
431 last_rr_session_dir = session_dirs.begin();
435 Session::path_is_within_session (const std::string& path)
437 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
438 if (path.find ((*i).path) == 0) {
446 Session::ensure_subdirs ()
450 dir = session_directory().peak_path().to_string();
452 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
453 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
457 dir = session_directory().sound_path().to_string();
459 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
460 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
464 dir = session_directory().midi_path().to_string();
466 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
467 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
471 dir = session_directory().dead_path().to_string();
473 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
474 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
478 dir = session_directory().export_path().to_string();
480 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
481 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
485 dir = analysis_dir ();
487 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
488 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
492 dir = plugins_dir ();
494 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
495 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
502 /** Caller must not hold process lock */
504 Session::create (const string& mix_template, BusProfile* bus_profile)
506 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
507 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
511 if (ensure_subdirs ()) {
515 _writable = exists_and_writable (sys::path (_path));
517 if (!mix_template.empty()) {
518 std::string in_path = mix_template;
520 ifstream in(in_path.c_str());
523 string out_path = _path;
525 out_path += statefile_suffix;
527 ofstream out(out_path.c_str());
535 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
541 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
548 /* Instantiate metadata */
550 _metadata = new SessionMetadata ();
552 /* set initial start + end point */
554 _state_of_the_state = Clean;
556 /* set up Master Out and Control Out if necessary */
562 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
564 if (bus_profile->master_out_channels) {
565 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
569 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
570 boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
573 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
574 r->input()->ensure_io (count, false, this);
575 r->output()->ensure_io (count, false, this);
577 r->set_remote_control_id (control_id++);
581 if (Config->get_use_monitor_bus()) {
582 boost::shared_ptr<Route> r (new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO));
586 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
587 boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
590 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
591 r->input()->ensure_io (count, false, this);
592 r->output()->ensure_io (count, false, this);
594 r->set_remote_control_id (control_id);
600 /* prohibit auto-connect to master, because there isn't one */
601 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
605 add_routes (rl, false, false);
608 /* this allows the user to override settings with an environment variable.
611 if (no_auto_connect()) {
612 bus_profile->input_ac = AutoConnectOption (0);
613 bus_profile->output_ac = AutoConnectOption (0);
616 Config->set_input_auto_connect (bus_profile->input_ac);
617 Config->set_output_auto_connect (bus_profile->output_ac);
626 Session::maybe_write_autosave()
628 if (dirty() && record_status() != Recording) {
629 save_state("", true);
634 Session::remove_pending_capture_state ()
636 sys::path pending_state_file_path(_session_dir->root_path());
638 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
642 sys::remove (pending_state_file_path);
644 catch(sys::filesystem_error& ex)
646 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
647 pending_state_file_path.to_string(), ex.what()) << endmsg;
651 /** Rename a state file.
652 * @param old_name Old snapshot name.
653 * @param new_name New snapshot name.
656 Session::rename_state (string old_name, string new_name)
658 if (old_name == _current_snapshot_name || old_name == _name) {
659 /* refuse to rename the current snapshot or the "main" one */
663 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
664 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
666 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
667 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
671 sys::rename (old_xml_path, new_xml_path);
673 catch (const sys::filesystem_error& err)
675 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
676 old_name, new_name, err.what()) << endmsg;
680 /** Remove a state file.
681 * @param snapshot_name Snapshot name.
684 Session::remove_state (string snapshot_name)
686 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
687 // refuse to remove the current snapshot or the "main" one
691 sys::path xml_path(_session_dir->root_path());
693 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
695 if (!create_backup_file (xml_path)) {
696 // don't remove it if a backup can't be made
697 // create_backup_file will log the error.
702 sys::remove (xml_path);
705 #ifdef HAVE_JACK_SESSION
707 Session::jack_session_event (jack_session_event_t * event)
711 struct tm local_time;
714 localtime_r (&n, &local_time);
715 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
717 if (event->type == JackSessionSaveTemplate)
719 if (save_template( timebuf )) {
720 event->flags = JackSessionSaveError;
722 string cmd ("ardour3 -P -U ");
723 cmd += event->client_uuid;
727 event->command_line = strdup (cmd.c_str());
732 if (save_state (timebuf)) {
733 event->flags = JackSessionSaveError;
735 sys::path xml_path (_session_dir->root_path());
736 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
738 string cmd ("ardour3 -P -U ");
739 cmd += event->client_uuid;
741 cmd += xml_path.to_string();
744 event->command_line = strdup (cmd.c_str());
748 jack_session_reply (_engine.jack(), event);
750 if (event->type == JackSessionSaveAndQuit) {
751 Quit (); /* EMIT SIGNAL */
754 jack_session_event_free( event );
758 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
760 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
763 sys::path xml_path(_session_dir->root_path());
765 if (!_writable || (_state_of_the_state & CannotSave)) {
769 if (!_engine.connected ()) {
770 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
776 /* tell sources we're saving first, in case they write out to a new file
777 * which should be saved with the state rather than the old one */
778 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
779 i->second->session_saved();
782 tree.set_root (&get_state());
784 if (snapshot_name.empty()) {
785 snapshot_name = _current_snapshot_name;
786 } else if (switch_to_snapshot) {
787 _current_snapshot_name = snapshot_name;
792 /* proper save: use statefile_suffix (.ardour in English) */
794 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
796 /* make a backup copy of the old file */
798 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
799 // create_backup_file will log the error
805 /* pending save: use pending_suffix (.pending in English) */
806 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
809 sys::path tmp_path(_session_dir->root_path());
811 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
813 // cerr << "actually writing state to " << xml_path.to_string() << endl;
815 if (!tree.write (tmp_path.to_string())) {
816 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
817 sys::remove (tmp_path);
822 if (::rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
823 error << string_compose (_("could not rename temporary session file %1 to %2"),
824 tmp_path.to_string(), xml_path.to_string()) << endmsg;
825 sys::remove (tmp_path);
832 save_history (snapshot_name);
834 bool was_dirty = dirty();
836 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
839 DirtyChanged (); /* EMIT SIGNAL */
842 StateSaved (snapshot_name); /* EMIT SIGNAL */
849 Session::restore_state (string snapshot_name)
851 if (load_state (snapshot_name) == 0) {
852 set_state (*state_tree->root(), Stateful::loading_state_version);
859 Session::load_state (string snapshot_name)
864 state_was_pending = false;
866 /* check for leftover pending state from a crashed capture attempt */
868 sys::path xmlpath(_session_dir->root_path());
869 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
871 if (sys::exists (xmlpath)) {
873 /* there is pending state from a crashed capture attempt */
875 boost::optional<int> r = AskAboutPendingState();
876 if (r.get_value_or (1)) {
877 state_was_pending = true;
881 if (!state_was_pending) {
882 xmlpath = _session_dir->root_path();
883 xmlpath /= snapshot_name;
886 if (!sys::exists (xmlpath)) {
887 xmlpath = _session_dir->root_path();
888 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
889 if (!sys::exists (xmlpath)) {
890 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
895 state_tree = new XMLTree;
899 _writable = exists_and_writable (xmlpath);
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), "%" PRId64, _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 /* save the event ID counter */
1045 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1046 node->add_property ("event-counter", buf);
1048 /* various options */
1050 node->add_child_nocopy (config.get_variables ());
1052 node->add_child_nocopy (_metadata->get_state());
1054 child = node->add_child ("Sources");
1057 Glib::Mutex::Lock sl (source_lock);
1059 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1061 /* Don't save information about non-file Sources, or
1062 * about non-destructive file sources that are empty
1063 * and unused by any regions.
1066 boost::shared_ptr<FileSource> fs;
1068 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1070 if (!fs->destructive()) {
1071 if (fs->empty() && !fs->used()) {
1076 child->add_child_nocopy (siter->second->get_state());
1081 child = node->add_child ("Regions");
1084 Glib::Mutex::Lock rl (region_lock);
1085 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1086 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1087 boost::shared_ptr<Region> r = i->second;
1088 /* only store regions not attached to playlists */
1089 if (r->playlist() == 0) {
1090 child->add_child_nocopy (r->state ());
1094 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1096 if (!cassocs.empty()) {
1097 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1099 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1101 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1102 i->first->id().print (buf, sizeof (buf));
1103 can->add_property (X_("copy"), buf);
1104 i->second->id().print (buf, sizeof (buf));
1105 can->add_property (X_("original"), buf);
1106 ca->add_child_nocopy (*can);
1112 node->add_child_nocopy (_locations->get_state());
1114 // for a template, just create a new Locations, populate it
1115 // with the default start and end, and get the state for that.
1116 Locations loc (*this);
1117 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1118 range->set (max_framepos, 0);
1120 node->add_child_nocopy (loc.get_state());
1123 child = node->add_child ("Bundles");
1125 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1126 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1127 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1129 child->add_child_nocopy (b->get_state());
1134 child = node->add_child ("Routes");
1136 boost::shared_ptr<RouteList> r = routes.reader ();
1138 RoutePublicOrderSorter cmp;
1139 RouteList public_order (*r);
1140 public_order.sort (cmp);
1142 /* the sort should have put control outs first */
1145 assert (_monitor_out == public_order.front());
1148 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1149 if (!(*i)->is_hidden()) {
1151 child->add_child_nocopy ((*i)->get_state());
1153 child->add_child_nocopy ((*i)->get_template());
1159 playlists->add_state (node, full_state);
1161 child = node->add_child ("RouteGroups");
1162 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1163 child->add_child_nocopy ((*i)->get_state());
1167 child = node->add_child ("Click");
1168 child->add_child_nocopy (_click_io->state (full_state));
1172 child = node->add_child ("NamedSelections");
1173 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1175 child->add_child_nocopy ((*i)->get_state());
1180 node->add_child_nocopy (_speakers->get_state());
1181 node->add_child_nocopy (_tempo_map->get_state());
1182 node->add_child_nocopy (get_control_protocol_state());
1185 node->add_child_copy (*_extra_xml);
1192 Session::get_control_protocol_state ()
1194 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1195 return cpm.get_state();
1199 Session::set_state (const XMLNode& node, int version)
1203 const XMLProperty* prop;
1206 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1208 if (node.name() != X_("Session")) {
1209 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1213 if ((prop = node.property ("version")) != 0) {
1214 version = atoi (prop->value ()) * 1000;
1217 if ((prop = node.property ("name")) != 0) {
1218 _name = prop->value ();
1221 if ((prop = node.property (X_("sample-rate"))) != 0) {
1223 _nominal_frame_rate = atoi (prop->value());
1225 if (_nominal_frame_rate != _current_frame_rate) {
1226 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1227 if (r.get_value_or (0)) {
1233 setup_raid_path(_session_dir->root_path().to_string());
1235 if ((prop = node.property (X_("id-counter"))) != 0) {
1237 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1238 ID::init_counter (x);
1240 /* old sessions used a timebased counter, so fake
1241 the startup ID counter based on a standard
1246 ID::init_counter (now);
1249 if ((prop = node.property (X_("event-counter"))) != 0) {
1250 Evoral::init_event_id_counter (atoi (prop->value()));
1253 IO::disable_connecting ();
1255 Stateful::save_extra_xml (node);
1257 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1258 load_options (*child);
1259 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1260 load_options (*child);
1262 error << _("Session: XML state has no options section") << endmsg;
1265 if (version >= 3000) {
1266 if ((child = find_named_node (node, "Metadata")) == 0) {
1267 warning << _("Session: XML state has no metadata section") << endmsg;
1268 } else if (_metadata->set_state (*child, version)) {
1273 if ((child = find_named_node (node, "Locations")) == 0) {
1274 error << _("Session: XML state has no locations section") << endmsg;
1276 } else if (_locations->set_state (*child, version)) {
1280 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1281 _speakers->set_state (*child, version);
1286 if ((location = _locations->auto_loop_location()) != 0) {
1287 set_auto_loop_location (location);
1290 if ((location = _locations->auto_punch_location()) != 0) {
1291 set_auto_punch_location (location);
1294 if ((location = _locations->session_range_location()) != 0) {
1295 delete _session_range_location;
1296 _session_range_location = location;
1299 if (_session_range_location) {
1300 AudioFileSource::set_header_position_offset (_session_range_location->start());
1303 if ((child = find_named_node (node, "Sources")) == 0) {
1304 error << _("Session: XML state has no sources section") << endmsg;
1306 } else if (load_sources (*child)) {
1310 if ((child = find_named_node (node, "TempoMap")) == 0) {
1311 error << _("Session: XML state has no Tempo Map section") << endmsg;
1313 } else if (_tempo_map->set_state (*child, version)) {
1317 if ((child = find_named_node (node, "Regions")) == 0) {
1318 error << _("Session: XML state has no Regions section") << endmsg;
1320 } else if (load_regions (*child)) {
1324 if ((child = find_named_node (node, "Playlists")) == 0) {
1325 error << _("Session: XML state has no playlists section") << endmsg;
1327 } else if (playlists->load (*this, *child)) {
1331 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1333 } else if (playlists->load_unused (*this, *child)) {
1337 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1338 if (load_compounds (*child)) {
1343 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1344 if (load_named_selections (*child)) {
1349 if (version >= 3000) {
1350 if ((child = find_named_node (node, "Bundles")) == 0) {
1351 warning << _("Session: XML state has no bundles section") << endmsg;
1354 /* We can't load Bundles yet as they need to be able
1355 to convert from port names to Port objects, which can't happen until
1357 _bundle_xml_node = new XMLNode (*child);
1361 if (version < 3000) {
1362 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1363 error << _("Session: XML state has no diskstreams section") << endmsg;
1365 } else if (load_diskstreams_2X (*child, version)) {
1370 if ((child = find_named_node (node, "Routes")) == 0) {
1371 error << _("Session: XML state has no routes section") << endmsg;
1373 } else if (load_routes (*child, version)) {
1377 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1378 _diskstreams_2X.clear ();
1380 if (version >= 3000) {
1382 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1383 error << _("Session: XML state has no route groups section") << endmsg;
1385 } else if (load_route_groups (*child, version)) {
1389 } else if (version < 3000) {
1391 if ((child = find_named_node (node, "EditGroups")) == 0) {
1392 error << _("Session: XML state has no edit groups section") << endmsg;
1394 } else if (load_route_groups (*child, version)) {
1398 if ((child = find_named_node (node, "MixGroups")) == 0) {
1399 error << _("Session: XML state has no mix groups section") << endmsg;
1401 } else if (load_route_groups (*child, version)) {
1406 if ((child = find_named_node (node, "Click")) == 0) {
1407 warning << _("Session: XML state has no click section") << endmsg;
1408 } else if (_click_io) {
1409 _click_io->set_state (*child, version);
1412 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1413 ControlProtocolManager::instance().set_protocol_states (*child);
1416 /* here beginneth the second phase ... */
1418 StateReady (); /* EMIT SIGNAL */
1427 Session::load_routes (const XMLNode& node, int version)
1430 XMLNodeConstIterator niter;
1431 RouteList new_routes;
1433 nlist = node.children();
1437 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1439 boost::shared_ptr<Route> route;
1440 if (version < 3000) {
1441 route = XMLRouteFactory_2X (**niter, version);
1443 route = XMLRouteFactory (**niter, version);
1447 error << _("Session: cannot create Route from XML description.") << endmsg;
1451 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1453 new_routes.push_back (route);
1456 add_routes (new_routes, false, false);
1461 boost::shared_ptr<Route>
1462 Session::XMLRouteFactory (const XMLNode& node, int version)
1464 boost::shared_ptr<Route> ret;
1466 if (node.name() != "Route") {
1470 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1472 DataType type = DataType::AUDIO;
1473 const XMLProperty* prop = node.property("default-type");
1476 type = DataType (prop->value());
1479 assert (type != DataType::NIL);
1483 boost::shared_ptr<Track> track;
1485 if (type == DataType::AUDIO) {
1486 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1488 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1491 if (track->init()) {
1495 if (track->set_state (node, version)) {
1499 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1500 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1505 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1507 if (r->init () == 0 && r->set_state (node, version) == 0) {
1508 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1509 boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1518 boost::shared_ptr<Route>
1519 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1521 boost::shared_ptr<Route> ret;
1523 if (node.name() != "Route") {
1527 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1529 ds_prop = node.property (X_("diskstream"));
1532 DataType type = DataType::AUDIO;
1533 const XMLProperty* prop = node.property("default-type");
1536 type = DataType (prop->value());
1539 assert (type != DataType::NIL);
1543 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1544 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1548 if (i == _diskstreams_2X.end()) {
1549 error << _("Could not find diskstream for route") << endmsg;
1550 return boost::shared_ptr<Route> ();
1553 boost::shared_ptr<Track> track;
1555 if (type == DataType::AUDIO) {
1556 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1558 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1561 if (track->init()) {
1565 if (track->set_state (node, version)) {
1569 track->set_diskstream (*i);
1571 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1572 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1577 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1579 if (r->init () == 0 && r->set_state (node, version) == 0) {
1580 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1581 boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1591 Session::load_regions (const XMLNode& node)
1594 XMLNodeConstIterator niter;
1595 boost::shared_ptr<Region> region;
1597 nlist = node.children();
1601 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1602 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1603 error << _("Session: cannot create Region from XML description.");
1604 const XMLProperty *name = (**niter).property("name");
1607 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1618 Session::load_compounds (const XMLNode& node)
1620 XMLNodeList calist = node.children();
1621 XMLNodeConstIterator caiter;
1622 XMLProperty *caprop;
1624 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1625 XMLNode* ca = *caiter;
1629 if ((caprop = ca->property (X_("original"))) == 0) {
1632 orig_id = caprop->value();
1634 if ((caprop = ca->property (X_("copy"))) == 0) {
1637 copy_id = caprop->value();
1639 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1640 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1642 if (!orig || !copy) {
1643 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1649 RegionFactory::add_compound_association (orig, copy);
1656 Session::load_nested_sources (const XMLNode& node)
1659 XMLNodeConstIterator niter;
1661 nlist = node.children();
1663 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1664 if ((*niter)->name() == "Source") {
1666 /* it may already exist, so don't recreate it unnecessarily
1669 XMLProperty* prop = (*niter)->property (X_("id"));
1671 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1675 ID source_id (prop->value());
1677 if (!source_by_id (source_id)) {
1680 SourceFactory::create (*this, **niter, true);
1682 catch (failed_constructor& err) {
1683 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1690 boost::shared_ptr<Region>
1691 Session::XMLRegionFactory (const XMLNode& node, bool full)
1693 const XMLProperty* type = node.property("type");
1697 const XMLNodeList& nlist = node.children();
1699 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1700 XMLNode *child = (*niter);
1701 if (child->name() == "NestedSource") {
1702 load_nested_sources (*child);
1706 if (!type || type->value() == "audio") {
1707 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1708 } else if (type->value() == "midi") {
1709 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1712 } catch (failed_constructor& err) {
1713 return boost::shared_ptr<Region> ();
1716 return boost::shared_ptr<Region> ();
1719 boost::shared_ptr<AudioRegion>
1720 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1722 const XMLProperty* prop;
1723 boost::shared_ptr<Source> source;
1724 boost::shared_ptr<AudioSource> as;
1726 SourceList master_sources;
1727 uint32_t nchans = 1;
1730 if (node.name() != X_("Region")) {
1731 return boost::shared_ptr<AudioRegion>();
1734 if ((prop = node.property (X_("channels"))) != 0) {
1735 nchans = atoi (prop->value().c_str());
1738 if ((prop = node.property ("name")) == 0) {
1739 cerr << "no name for this region\n";
1743 if ((prop = node.property (X_("source-0"))) == 0) {
1744 if ((prop = node.property ("source")) == 0) {
1745 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1746 return boost::shared_ptr<AudioRegion>();
1750 PBD::ID s_id (prop->value());
1752 if ((source = source_by_id (s_id)) == 0) {
1753 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1754 return boost::shared_ptr<AudioRegion>();
1757 as = boost::dynamic_pointer_cast<AudioSource>(source);
1759 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1760 return boost::shared_ptr<AudioRegion>();
1763 sources.push_back (as);
1765 /* pickup other channels */
1767 for (uint32_t n=1; n < nchans; ++n) {
1768 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1769 if ((prop = node.property (buf)) != 0) {
1771 PBD::ID id2 (prop->value());
1773 if ((source = source_by_id (id2)) == 0) {
1774 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1775 return boost::shared_ptr<AudioRegion>();
1778 as = boost::dynamic_pointer_cast<AudioSource>(source);
1780 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1781 return boost::shared_ptr<AudioRegion>();
1783 sources.push_back (as);
1787 for (uint32_t n = 0; n < nchans; ++n) {
1788 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1789 if ((prop = node.property (buf)) != 0) {
1791 PBD::ID id2 (prop->value());
1793 if ((source = source_by_id (id2)) == 0) {
1794 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1795 return boost::shared_ptr<AudioRegion>();
1798 as = boost::dynamic_pointer_cast<AudioSource>(source);
1800 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1801 return boost::shared_ptr<AudioRegion>();
1803 master_sources.push_back (as);
1808 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1810 /* a final detail: this is the one and only place that we know how long missing files are */
1812 if (region->whole_file()) {
1813 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1814 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1816 sfp->set_length (region->length());
1821 if (!master_sources.empty()) {
1822 if (master_sources.size() != nchans) {
1823 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1825 region->set_master_sources (master_sources);
1833 catch (failed_constructor& err) {
1834 return boost::shared_ptr<AudioRegion>();
1838 boost::shared_ptr<MidiRegion>
1839 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1841 const XMLProperty* prop;
1842 boost::shared_ptr<Source> source;
1843 boost::shared_ptr<MidiSource> ms;
1846 if (node.name() != X_("Region")) {
1847 return boost::shared_ptr<MidiRegion>();
1850 if ((prop = node.property ("name")) == 0) {
1851 cerr << "no name for this region\n";
1855 if ((prop = node.property (X_("source-0"))) == 0) {
1856 if ((prop = node.property ("source")) == 0) {
1857 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1858 return boost::shared_ptr<MidiRegion>();
1862 PBD::ID s_id (prop->value());
1864 if ((source = source_by_id (s_id)) == 0) {
1865 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1866 return boost::shared_ptr<MidiRegion>();
1869 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1871 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1872 return boost::shared_ptr<MidiRegion>();
1875 sources.push_back (ms);
1878 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1879 /* a final detail: this is the one and only place that we know how long missing files are */
1881 if (region->whole_file()) {
1882 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1883 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1885 sfp->set_length (region->length());
1893 catch (failed_constructor& err) {
1894 return boost::shared_ptr<MidiRegion>();
1899 Session::get_sources_as_xml ()
1902 XMLNode* node = new XMLNode (X_("Sources"));
1903 Glib::Mutex::Lock lm (source_lock);
1905 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1906 node->add_child_nocopy (i->second->get_state());
1913 Session::path_from_region_name (DataType type, string name, string identifier)
1915 char buf[PATH_MAX+1];
1917 SessionDirectory sdir(get_best_session_directory_for_new_source());
1918 sys::path source_dir = ((type == DataType::AUDIO)
1919 ? sdir.sound_path() : sdir.midi_path());
1921 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1923 for (n = 0; n < 999999; ++n) {
1924 if (identifier.length()) {
1925 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1926 identifier.c_str(), n, ext.c_str());
1928 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1932 sys::path source_path = source_dir / buf;
1934 if (!sys::exists (source_path)) {
1935 return source_path.to_string();
1939 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1948 Session::load_sources (const XMLNode& node)
1951 XMLNodeConstIterator niter;
1952 boost::shared_ptr<Source> source;
1954 nlist = node.children();
1958 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1961 if ((source = XMLSourceFactory (**niter)) == 0) {
1962 error << _("Session: cannot create Source from XML description.") << endmsg;
1965 } catch (MissingSource& err) {
1969 if (!no_questions_about_missing_files) {
1970 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1975 switch (user_choice) {
1977 /* user added a new search location, so try again */
1982 /* user asked to quit the entire session load
1987 no_questions_about_missing_files = true;
1991 no_questions_about_missing_files = true;
1996 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1997 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2006 boost::shared_ptr<Source>
2007 Session::XMLSourceFactory (const XMLNode& node)
2009 if (node.name() != "Source") {
2010 return boost::shared_ptr<Source>();
2014 /* note: do peak building in another thread when loading session state */
2015 return SourceFactory::create (*this, node, true);
2018 catch (failed_constructor& err) {
2019 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2020 return boost::shared_ptr<Source>();
2025 Session::save_template (string template_name)
2029 if (_state_of_the_state & CannotSave) {
2033 sys::path user_template_dir(user_template_directory());
2037 sys::create_directories (user_template_dir);
2039 catch(sys::filesystem_error& ex)
2041 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
2042 user_template_dir.to_string(), ex.what()) << endmsg;
2046 tree.set_root (&get_template());
2048 sys::path template_file_path(user_template_dir);
2049 template_file_path /= template_name + template_suffix;
2051 if (sys::exists (template_file_path))
2053 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2054 template_file_path.to_string()) << endmsg;
2058 if (!tree.write (template_file_path.to_string())) {
2059 error << _("template not saved") << endmsg;
2067 Session::rename_template (string old_name, string new_name)
2069 sys::path old_path (user_template_directory());
2070 old_path /= old_name + template_suffix;
2072 sys::path new_path(user_template_directory());
2073 new_path /= new_name + template_suffix;
2075 if (sys::exists (new_path)) {
2076 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
2077 new_path.to_string()) << endmsg;
2082 sys::rename (old_path, new_path);
2090 Session::delete_template (string name)
2092 sys::path path = user_template_directory();
2093 path /= name + template_suffix;
2104 Session::refresh_disk_space ()
2107 struct statfs statfsbuf;
2108 vector<space_and_path>::iterator i;
2109 Glib::Mutex::Lock lm (space_lock);
2112 /* get freespace on every FS that is part of the session path */
2114 _total_free_4k_blocks = 0;
2116 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2117 statfs ((*i).path.c_str(), &statfsbuf);
2119 scale = statfsbuf.f_bsize/4096.0;
2121 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2122 _total_free_4k_blocks += (*i).blocks;
2128 Session::get_best_session_directory_for_new_source ()
2130 vector<space_and_path>::iterator i;
2131 string result = _session_dir->root_path().to_string();
2133 /* handle common case without system calls */
2135 if (session_dirs.size() == 1) {
2139 /* OK, here's the algorithm we're following here:
2141 We want to select which directory to use for
2142 the next file source to be created. Ideally,
2143 we'd like to use a round-robin process so as to
2144 get maximum performance benefits from splitting
2145 the files across multiple disks.
2147 However, in situations without much diskspace, an
2148 RR approach may end up filling up a filesystem
2149 with new files while others still have space.
2150 Its therefore important to pay some attention to
2151 the freespace in the filesystem holding each
2152 directory as well. However, if we did that by
2153 itself, we'd keep creating new files in the file
2154 system with the most space until it was as full
2155 as all others, thus negating any performance
2156 benefits of this RAID-1 like approach.
2158 So, we use a user-configurable space threshold. If
2159 there are at least 2 filesystems with more than this
2160 much space available, we use RR selection between them.
2161 If not, then we pick the filesystem with the most space.
2163 This gets a good balance between the two
2167 refresh_disk_space ();
2169 int free_enough = 0;
2171 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2172 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2177 if (free_enough >= 2) {
2178 /* use RR selection process, ensuring that the one
2182 i = last_rr_session_dir;
2185 if (++i == session_dirs.end()) {
2186 i = session_dirs.begin();
2189 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2190 if (create_session_directory ((*i).path)) {
2192 last_rr_session_dir = i;
2197 } while (i != last_rr_session_dir);
2201 /* pick FS with the most freespace (and that
2202 seems to actually work ...)
2205 vector<space_and_path> sorted;
2206 space_and_path_ascending_cmp cmp;
2208 sorted = session_dirs;
2209 sort (sorted.begin(), sorted.end(), cmp);
2211 for (i = sorted.begin(); i != sorted.end(); ++i) {
2212 if (create_session_directory ((*i).path)) {
2214 last_rr_session_dir = i;
2224 Session::load_named_selections (const XMLNode& node)
2227 XMLNodeConstIterator niter;
2230 nlist = node.children();
2234 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2236 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2237 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2245 Session::XMLNamedSelectionFactory (const XMLNode& node)
2248 return new NamedSelection (*this, node);
2251 catch (failed_constructor& err) {
2257 Session::automation_dir () const
2259 return Glib::build_filename (_path, "automation");
2263 Session::analysis_dir () const
2265 return Glib::build_filename (_path, "analysis");
2269 Session::plugins_dir () const
2271 return Glib::build_filename (_path, "plugins");
2275 Session::load_bundles (XMLNode const & node)
2277 XMLNodeList nlist = node.children();
2278 XMLNodeConstIterator niter;
2282 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2283 if ((*niter)->name() == "InputBundle") {
2284 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2285 } else if ((*niter)->name() == "OutputBundle") {
2286 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2288 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2297 Session::load_route_groups (const XMLNode& node, int version)
2299 XMLNodeList nlist = node.children();
2300 XMLNodeConstIterator niter;
2304 if (version >= 3000) {
2306 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2307 if ((*niter)->name() == "RouteGroup") {
2308 RouteGroup* rg = new RouteGroup (*this, "");
2309 add_route_group (rg);
2310 rg->set_state (**niter, version);
2314 } else if (version < 3000) {
2316 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2317 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2318 RouteGroup* rg = new RouteGroup (*this, "");
2319 add_route_group (rg);
2320 rg->set_state (**niter, version);
2329 Session::auto_save()
2331 save_state (_current_snapshot_name);
2335 state_file_filter (const string &str, void */*arg*/)
2337 return (str.length() > strlen(statefile_suffix) &&
2338 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2342 bool operator()(const string* a, const string* b) {
2348 remove_end(string* state)
2350 string statename(*state);
2352 string::size_type start,end;
2353 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2354 statename = statename.substr (start+1);
2357 if ((end = statename.rfind(".ardour")) == string::npos) {
2358 end = statename.length();
2361 return new string(statename.substr (0, end));
2365 Session::possible_states (string path)
2367 PathScanner scanner;
2368 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2370 transform(states->begin(), states->end(), states->begin(), remove_end);
2373 sort (states->begin(), states->end(), cmp);
2379 Session::possible_states () const
2381 return possible_states(_path);
2385 Session::add_route_group (RouteGroup* g)
2387 _route_groups.push_back (g);
2388 route_group_added (g); /* EMIT SIGNAL */
2390 g->MembershipChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2391 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2397 Session::remove_route_group (RouteGroup& rg)
2399 list<RouteGroup*>::iterator i;
2401 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2402 _route_groups.erase (i);
2405 route_group_removed (); /* EMIT SIGNAL */
2409 /** Set a new order for our route groups, without adding or removing any.
2410 * @param groups Route group list in the new order.
2413 Session::reorder_route_groups (list<RouteGroup*> groups)
2415 _route_groups = groups;
2417 route_groups_reordered (); /* EMIT SIGNAL */
2423 Session::route_group_by_name (string name)
2425 list<RouteGroup *>::iterator i;
2427 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2428 if ((*i)->name() == name) {
2436 Session::all_route_group() const
2438 return *_all_route_group;
2442 Session::add_commands (vector<Command*> const & cmds)
2444 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2450 Session::begin_reversible_command (const string& name)
2452 begin_reversible_command (g_quark_from_string (name.c_str ()));
2455 /** Begin a reversible command using a GQuark to identify it.
2456 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2457 * but there must be as many begin...()s as there are commit...()s.
2460 Session::begin_reversible_command (GQuark q)
2462 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2463 to hold all the commands that are committed. This keeps the order of
2464 commands correct in the history.
2467 if (_current_trans == 0) {
2468 /* start a new transaction */
2469 assert (_current_trans_quarks.empty ());
2470 _current_trans = new UndoTransaction();
2471 _current_trans->set_name (g_quark_to_string (q));
2474 _current_trans_quarks.push_front (q);
2478 Session::commit_reversible_command (Command *cmd)
2480 assert (_current_trans);
2481 assert (!_current_trans_quarks.empty ());
2486 _current_trans->add_command (cmd);
2489 _current_trans_quarks.pop_front ();
2491 if (!_current_trans_quarks.empty ()) {
2492 /* the transaction we're committing is not the top-level one */
2496 if (_current_trans->empty()) {
2497 /* no commands were added to the transaction, so just get rid of it */
2498 delete _current_trans;
2503 gettimeofday (&now, 0);
2504 _current_trans->set_timestamp (now);
2506 _history.add (_current_trans);
2511 accept_all_audio_files (const string& path, void */*arg*/)
2513 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2517 if (!AudioFileSource::safe_audio_file_extension (path)) {
2525 accept_all_midi_files (const string& path, void */*arg*/)
2527 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2531 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2532 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2533 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2537 accept_all_state_files (const string& path, void */*arg*/)
2539 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2543 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2547 Session::find_all_sources (string path, set<string>& result)
2552 if (!tree.read (path)) {
2556 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2561 XMLNodeConstIterator niter;
2563 nlist = node->children();
2567 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2571 if ((prop = (*niter)->property (X_("type"))) == 0) {
2575 DataType type (prop->value());
2577 if ((prop = (*niter)->property (X_("name"))) == 0) {
2581 if (Glib::path_is_absolute (prop->value())) {
2582 /* external file, ignore */
2590 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2591 result.insert (found_path);
2599 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2601 PathScanner scanner;
2602 vector<string*>* state_files;
2604 string this_snapshot_path;
2610 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2611 ripped = ripped.substr (0, ripped.length() - 1);
2614 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2616 if (state_files == 0) {
2621 this_snapshot_path = _path;
2622 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2623 this_snapshot_path += statefile_suffix;
2625 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2627 if (exclude_this_snapshot && **i == this_snapshot_path) {
2631 if (find_all_sources (**i, result) < 0) {
2639 struct RegionCounter {
2640 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2641 AudioSourceList::iterator iter;
2642 boost::shared_ptr<Region> region;
2645 RegionCounter() : count (0) {}
2649 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2651 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2652 return r.get_value_or (1);
2656 Session::cleanup_regions ()
2658 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2660 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2662 boost::shared_ptr<AudioRegion> audio_region = boost::dynamic_pointer_cast<AudioRegion>( i->second);
2664 if (!audio_region) {
2668 uint32_t used = playlists->region_use_count (audio_region);
2670 if (used == 0 && !audio_region->automatic()) {
2671 RegionFactory::map_remove(i->second);
2675 /* dump the history list */
2682 Session::cleanup_sources (CleanupReport& rep)
2684 // FIXME: needs adaptation to midi
2686 vector<boost::shared_ptr<Source> > dead_sources;
2687 PathScanner scanner;
2690 vector<space_and_path>::iterator i;
2691 vector<space_and_path>::iterator nexti;
2692 vector<string*>* candidates;
2693 vector<string*>* candidates2;
2694 vector<string> unused;
2695 set<string> all_sources;
2700 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2702 /* consider deleting all unused playlists */
2704 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2709 /* sync the "all regions" property of each playlist with its current state
2712 playlists->sync_all_regions_with_regions ();
2714 /* find all un-used sources */
2719 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2721 SourceMap::iterator tmp;
2726 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2730 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2731 dead_sources.push_back (i->second);
2732 i->second->drop_references ();
2738 /* build a list of all the possible audio directories for the session */
2740 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2745 SessionDirectory sdir ((*i).path);
2746 audio_path += sdir.sound_path().to_string();
2748 if (nexti != session_dirs.end()) {
2756 /* build a list of all the possible midi directories for the session */
2758 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2763 SessionDirectory sdir ((*i).path);
2764 midi_path += sdir.midi_path().to_string();
2766 if (nexti != session_dirs.end()) {
2773 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2774 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2780 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2781 candidates->push_back (*i);
2786 candidates = candidates2; // might still be null
2789 /* find all sources, but don't use this snapshot because the
2790 state file on disk still references sources we may have already
2794 find_all_sources_across_snapshots (all_sources, true);
2796 /* add our current source list
2799 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2800 boost::shared_ptr<FileSource> fs;
2801 SourceMap::iterator tmp = i;
2804 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2805 if (playlists->source_use_count (fs) != 0) {
2806 all_sources.insert (fs->path());
2809 /* we might not remove this source from disk, because it may be used
2810 by other snapshots, but its not being used in this version
2811 so lets get rid of it now, along with any representative regions
2815 RegionFactory::remove_regions_using_source (i->second);
2823 char tmppath1[PATH_MAX+1];
2824 char tmppath2[PATH_MAX+1];
2827 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2832 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2834 if (realpath(spath.c_str(), tmppath1) == 0) {
2835 error << string_compose (_("Cannot expand path %1 (%2)"),
2836 spath, strerror (errno)) << endmsg;
2840 if (realpath((*i).c_str(), tmppath2) == 0) {
2841 error << string_compose (_("Cannot expand path %1 (%2)"),
2842 (*i), strerror (errno)) << endmsg;
2846 if (strcmp(tmppath1, tmppath2) == 0) {
2853 unused.push_back (spath);
2862 /* now try to move all unused files into the "dead" directory(ies) */
2864 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2865 struct stat statbuf;
2869 /* don't move the file across filesystems, just
2870 stick it in the `dead_dir_name' directory
2871 on whichever filesystem it was already on.
2874 if ((*x).find ("/sounds/") != string::npos) {
2876 /* old school, go up 1 level */
2878 newpath = Glib::path_get_dirname (*x); // "sounds"
2879 newpath = Glib::path_get_dirname (newpath); // "session-name"
2883 /* new school, go up 4 levels */
2885 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2886 newpath = Glib::path_get_dirname (newpath); // "session-name"
2887 newpath = Glib::path_get_dirname (newpath); // "interchange"
2888 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2891 newpath = Glib::build_filename (newpath, dead_dir_name);
2893 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2894 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2898 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2900 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2902 /* the new path already exists, try versioning */
2904 char buf[PATH_MAX+1];
2908 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2911 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2912 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2916 if (version == 999) {
2917 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2921 newpath = newpath_v;
2926 /* it doesn't exist, or we can't read it or something */
2930 stat ((*x).c_str(), &statbuf);
2932 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2933 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2934 (*x), newpath, strerror (errno))
2939 /* see if there an easy to find peakfile for this file, and remove it.
2942 string base = basename_nosuffix (*x);
2943 base += "%A"; /* this is what we add for the channel suffix of all native files,
2944 or for the first channel of embedded files. it will miss
2945 some peakfiles for other channels
2947 string peakpath = peak_path (base);
2949 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2950 if (::unlink (peakpath.c_str()) != 0) {
2951 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2952 peakpath, _path, strerror (errno))
2954 /* try to back out */
2955 ::rename (newpath.c_str(), _path.c_str());
2960 rep.paths.push_back (*x);
2961 rep.space += statbuf.st_size;
2964 /* dump the history list */
2968 /* save state so we don't end up a session file
2969 referring to non-existent sources.
2976 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2982 Session::cleanup_trash_sources (CleanupReport& rep)
2984 // FIXME: needs adaptation for MIDI
2986 vector<space_and_path>::iterator i;
2992 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2994 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2996 clear_directory (dead_dir, &rep.space, &rep.paths);
3003 Session::set_dirty ()
3005 bool was_dirty = dirty();
3007 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3011 DirtyChanged(); /* EMIT SIGNAL */
3017 Session::set_clean ()
3019 bool was_dirty = dirty();
3021 _state_of_the_state = Clean;
3025 DirtyChanged(); /* EMIT SIGNAL */
3030 Session::set_deletion_in_progress ()
3032 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3036 Session::clear_deletion_in_progress ()
3038 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3042 Session::add_controllable (boost::shared_ptr<Controllable> c)
3044 /* this adds a controllable to the list managed by the Session.
3045 this is a subset of those managed by the Controllable class
3046 itself, and represents the only ones whose state will be saved
3047 as part of the session.
3050 Glib::Mutex::Lock lm (controllables_lock);
3051 controllables.insert (c);
3054 struct null_deleter { void operator()(void const *) const {} };
3057 Session::remove_controllable (Controllable* c)
3059 if (_state_of_the_state | Deletion) {
3063 Glib::Mutex::Lock lm (controllables_lock);
3065 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3067 if (x != controllables.end()) {
3068 controllables.erase (x);
3072 boost::shared_ptr<Controllable>
3073 Session::controllable_by_id (const PBD::ID& id)
3075 Glib::Mutex::Lock lm (controllables_lock);
3077 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3078 if ((*i)->id() == id) {
3083 return boost::shared_ptr<Controllable>();
3086 boost::shared_ptr<Controllable>
3087 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3089 boost::shared_ptr<Controllable> c;
3090 boost::shared_ptr<Route> r;
3092 switch (desc.top_level_type()) {
3093 case ControllableDescriptor::NamedRoute:
3095 std::string str = desc.top_level_name();
3096 if (str == "master") {
3098 } else if (str == "control" || str == "listen") {
3101 r = route_by_name (desc.top_level_name());
3106 case ControllableDescriptor::RemoteControlID:
3107 r = route_by_remote_id (desc.rid());
3115 switch (desc.subtype()) {
3116 case ControllableDescriptor::Gain:
3117 c = r->gain_control ();
3120 case ControllableDescriptor::Solo:
3121 c = r->solo_control();
3124 case ControllableDescriptor::Mute:
3125 c = r->mute_control();
3128 case ControllableDescriptor::Recenable:
3130 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3133 c = t->rec_enable_control ();
3138 case ControllableDescriptor::PanDirection:
3140 c = r->pannable()->pan_azimuth_control;
3144 case ControllableDescriptor::PanWidth:
3146 c = r->pannable()->pan_width_control;
3150 case ControllableDescriptor::PanElevation:
3152 c = r->pannable()->pan_elevation_control;
3156 case ControllableDescriptor::Balance:
3157 /* XXX simple pan control */
3160 case ControllableDescriptor::PluginParameter:
3162 uint32_t plugin = desc.target (0);
3163 uint32_t parameter_index = desc.target (1);
3165 /* revert to zero based counting */
3171 if (parameter_index > 0) {
3175 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3178 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3179 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3184 case ControllableDescriptor::SendGain:
3186 uint32_t send = desc.target (0);
3188 /* revert to zero-based counting */
3194 boost::shared_ptr<Processor> p = r->nth_send (send);
3197 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3198 boost::shared_ptr<Amp> a = s->amp();
3201 c = s->amp()->gain_control();
3208 /* relax and return a null pointer */
3216 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3219 Stateful::add_instant_xml (node, _path);
3222 if (write_to_config) {
3223 Config->add_instant_xml (node);
3228 Session::instant_xml (const string& node_name)
3230 return Stateful::instant_xml (node_name, _path);
3234 Session::save_history (string snapshot_name)
3242 if (snapshot_name.empty()) {
3243 snapshot_name = _current_snapshot_name;
3246 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3247 const string backup_filename = history_filename + backup_suffix;
3248 const sys::path xml_path = _session_dir->root_path() / history_filename;
3249 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3251 if (sys::exists (xml_path)) {
3254 sys::rename (xml_path, backup_path);
3256 catch (const sys::filesystem_error& err)
3258 error << _("could not backup old history file, current history not saved") << endmsg;
3263 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3267 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3269 if (!tree.write (xml_path.to_string()))
3271 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3275 sys::remove (xml_path);
3276 sys::rename (backup_path, xml_path);
3278 catch (const sys::filesystem_error& err)
3280 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3281 backup_path.to_string(), err.what()) << endmsg;
3291 Session::restore_history (string snapshot_name)
3295 if (snapshot_name.empty()) {
3296 snapshot_name = _current_snapshot_name;
3299 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3300 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3302 info << "Loading history from " << xml_path.to_string() << endmsg;
3304 if (!sys::exists (xml_path)) {
3305 info << string_compose (_("%1: no history file \"%2\" for this session."),
3306 _name, xml_path.to_string()) << endmsg;
3310 if (!tree.read (xml_path.to_string())) {
3311 error << string_compose (_("Could not understand session history file \"%1\""),
3312 xml_path.to_string()) << endmsg;
3319 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3322 UndoTransaction* ut = new UndoTransaction ();
3325 ut->set_name(t->property("name")->value());
3326 stringstream ss(t->property("tv-sec")->value());
3328 ss.str(t->property("tv-usec")->value());
3330 ut->set_timestamp(tv);
3332 for (XMLNodeConstIterator child_it = t->children().begin();
3333 child_it != t->children().end(); child_it++)
3335 XMLNode *n = *child_it;
3338 if (n->name() == "MementoCommand" ||
3339 n->name() == "MementoUndoCommand" ||
3340 n->name() == "MementoRedoCommand") {
3342 if ((c = memento_command_factory(n))) {
3346 } else if (n->name() == "NoteDiffCommand") {
3347 PBD::ID id (n->property("midi-source")->value());
3348 boost::shared_ptr<MidiSource> midi_source =
3349 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3351 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3353 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3356 } else if (n->name() == "SysExDiffCommand") {
3358 PBD::ID id (n->property("midi-source")->value());
3359 boost::shared_ptr<MidiSource> midi_source =
3360 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3362 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3364 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3367 } else if (n->name() == "PatchChangeDiffCommand") {
3369 PBD::ID id (n->property("midi-source")->value());
3370 boost::shared_ptr<MidiSource> midi_source =
3371 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3373 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3375 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3378 } else if (n->name() == "StatefulDiffCommand") {
3379 if ((c = stateful_diff_command_factory (n))) {
3380 ut->add_command (c);
3383 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3394 Session::config_changed (std::string p, bool ours)
3400 if (p == "seamless-loop") {
3402 } else if (p == "rf-speed") {
3404 } else if (p == "auto-loop") {
3406 } else if (p == "auto-input") {
3408 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3409 /* auto-input only makes a difference if we're rolling */
3410 set_track_monitor_input_status (!config.get_auto_input());
3413 } else if (p == "punch-in") {
3417 if ((location = _locations->auto_punch_location()) != 0) {
3419 if (config.get_punch_in ()) {
3420 replace_event (SessionEvent::PunchIn, location->start());
3422 remove_event (location->start(), SessionEvent::PunchIn);
3426 } else if (p == "punch-out") {
3430 if ((location = _locations->auto_punch_location()) != 0) {
3432 if (config.get_punch_out()) {
3433 replace_event (SessionEvent::PunchOut, location->end());
3435 clear_events (SessionEvent::PunchOut);
3439 } else if (p == "edit-mode") {
3441 Glib::Mutex::Lock lm (playlists->lock);
3443 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3444 (*i)->set_edit_mode (Config->get_edit_mode ());
3447 } else if (p == "use-video-sync") {
3449 waiting_for_sync_offset = config.get_use_video_sync();
3451 } else if (p == "mmc-control") {
3453 //poke_midi_thread ();
3455 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3457 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3459 } else if (p == "mmc-send-id") {
3461 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3463 } else if (p == "midi-control") {
3465 //poke_midi_thread ();
3467 } else if (p == "raid-path") {
3469 setup_raid_path (config.get_raid_path());
3471 } else if (p == "timecode-format") {
3475 } else if (p == "video-pullup") {
3479 } else if (p == "seamless-loop") {
3481 if (play_loop && transport_rolling()) {
3482 // to reset diskstreams etc
3483 request_play_loop (true);
3486 } else if (p == "rf-speed") {
3488 cumulative_rf_motion = 0;
3491 } else if (p == "click-sound") {
3493 setup_click_sounds (1);
3495 } else if (p == "click-emphasis-sound") {
3497 setup_click_sounds (-1);
3499 } else if (p == "clicking") {
3501 if (Config->get_clicking()) {
3502 if (_click_io && click_data) { // don't require emphasis data
3509 } else if (p == "send-mtc") {
3511 if (Config->get_send_mtc ()) {
3512 /* mark us ready to send */
3513 next_quarter_frame_to_send = 0;
3516 } else if (p == "send-mmc") {
3518 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3520 } else if (p == "midi-feedback") {
3522 session_midi_feedback = Config->get_midi_feedback();
3524 } else if (p == "jack-time-master") {
3526 engine().reset_timebase ();
3528 } else if (p == "native-file-header-format") {
3530 if (!first_file_header_format_reset) {
3531 reset_native_file_format ();
3534 first_file_header_format_reset = false;
3536 } else if (p == "native-file-data-format") {
3538 if (!first_file_data_format_reset) {
3539 reset_native_file_format ();
3542 first_file_data_format_reset = false;
3544 } else if (p == "external-sync") {
3545 if (!config.get_external_sync()) {
3546 drop_sync_source ();
3548 switch_to_sync_source (config.get_sync_source());
3550 } else if (p == "remote-model") {
3551 set_remote_control_ids ();
3552 } else if (p == "denormal-model") {
3554 } else if (p == "history-depth") {
3555 set_history_depth (Config->get_history_depth());
3556 } else if (p == "sync-all-route-ordering") {
3557 sync_order_keys ("session");
3558 } else if (p == "initial-program-change") {
3560 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3563 buf[0] = MIDI::program; // channel zero by default
3564 buf[1] = (Config->get_initial_program_change() & 0x7f);
3566 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3568 } else if (p == "solo-mute-override") {
3569 // catch_up_on_solo_mute_override ();
3570 } else if (p == "listen-position" || p == "pfl-position") {
3571 listen_position_changed ();
3572 } else if (p == "solo-control-is-listen-control") {
3573 solo_control_mode_changed ();
3574 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3575 last_timecode_valid = false;
3576 } else if (p == "playback-buffer-seconds") {
3577 AudioSource::allocate_working_buffers (frame_rate());
3584 Session::set_history_depth (uint32_t d)
3586 _history.set_depth (d);
3590 Session::load_diskstreams_2X (XMLNode const & node, int)
3593 XMLNodeConstIterator citer;
3595 clist = node.children();
3597 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3600 /* diskstreams added automatically by DiskstreamCreated handler */
3601 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3602 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3603 _diskstreams_2X.push_back (dsp);
3605 error << _("Session: unknown diskstream type in XML") << endmsg;
3609 catch (failed_constructor& err) {
3610 error << _("Session: could not load diskstream via XML state") << endmsg;
3618 /** Connect things to the MMC object */
3620 Session::setup_midi_machine_control ()
3622 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3624 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3625 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3626 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3627 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3628 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3629 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3630 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3631 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3632 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3633 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3634 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3635 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3636 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3638 /* also handle MIDI SPP because its so common */
3640 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3641 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3642 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));
3645 boost::shared_ptr<Controllable>
3646 Session::solo_cut_control() const
3648 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3649 controls in Ardour that currently get presented to the user in the GUI that require
3650 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3652 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3653 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3657 return _solo_cut_control;
3661 Session::rename (const std::string& new_name)
3663 string legal_name = legalize_for_path (new_name);
3669 #define RENAME ::rename
3674 * interchange subdirectory
3678 * Backup files are left unchanged and not renamed.
3681 /* pass one: not 100% safe check that the new directory names don't
3685 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3690 /* this is a stupid hack because Glib::path_get_dirname() is
3691 * lexical-only, and so passing it /a/b/c/ gives a different
3692 * result than passing it /a/b/c ...
3695 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3696 oldstr = oldstr.substr (0, oldstr.length() - 1);
3699 string base = Glib::path_get_dirname (oldstr);
3700 string p = Glib::path_get_basename (oldstr);
3702 newstr = Glib::build_filename (base, legal_name);
3704 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3711 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3716 /* this is a stupid hack because Glib::path_get_dirname() is
3717 * lexical-only, and so passing it /a/b/c/ gives a different
3718 * result than passing it /a/b/c ...
3721 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3722 oldstr = oldstr.substr (0, oldstr.length() - 1);
3725 string base = Glib::path_get_dirname (oldstr);
3726 string p = Glib::path_get_basename (oldstr);
3728 newstr = Glib::build_filename (base, legal_name);
3730 cerr << "Rename " << oldstr << " => " << newstr << endl;
3732 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3737 (*_session_dir) = newstr;
3742 /* directory below interchange */
3744 v.push_back (newstr);
3745 v.push_back (interchange_dir_name);
3748 oldstr = Glib::build_filename (v);
3751 v.push_back (newstr);
3752 v.push_back (interchange_dir_name);
3753 v.push_back (legal_name);
3755 newstr = Glib::build_filename (v);
3757 cerr << "Rename " << oldstr << " => " << newstr << endl;
3759 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3766 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3767 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3769 cerr << "Rename " << oldstr << " => " << newstr << endl;
3771 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3777 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3778 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3780 cerr << "Rename " << oldstr << " => " << newstr << endl;
3782 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3787 _current_snapshot_name = new_name;
3792 /* save state again to get everything just right */
3794 save_state (_current_snapshot_name);