2 Copyright (C) 1999-2013 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"
31 #include <cstdio> /* snprintf(3) ... grrr */
44 #include <sys/param.h>
45 #include <sys/mount.h>
48 #ifdef HAVE_SYS_STATVFS_H
49 #include <sys/statvfs.h>
53 #include <glib/gstdio.h>
56 #include <glibmm/threads.h>
58 #include <boost/algorithm/string.hpp>
60 #include "midi++/mmc.h"
61 #include "midi++/port.h"
63 #include "evoral/SMF.hpp"
65 #include "pbd/boost_debug.h"
66 #include "pbd/basename.h"
67 #include "pbd/controllable_descriptor.h"
68 #include "pbd/enumwriter.h"
69 #include "pbd/error.h"
70 #include "pbd/file_utils.h"
71 #include "pbd/pathexpand.h"
72 #include "pbd/pathscanner.h"
73 #include "pbd/pthread_utils.h"
74 #include "pbd/stacktrace.h"
75 #include "pbd/convert.h"
76 #include "pbd/clear_dir.h"
77 #include "pbd/localtime_r.h"
79 #include "ardour/amp.h"
80 #include "ardour/audio_diskstream.h"
81 #include "ardour/audio_track.h"
82 #include "ardour/audioengine.h"
83 #include "ardour/audiofilesource.h"
84 #include "ardour/audioregion.h"
85 #include "ardour/automation_control.h"
86 #include "ardour/butler.h"
87 #include "ardour/control_protocol_manager.h"
88 #include "ardour/directory_names.h"
89 #include "ardour/filename_extensions.h"
90 #include "ardour/graph.h"
91 #include "ardour/location.h"
92 #include "ardour/midi_model.h"
93 #include "ardour/midi_patch_manager.h"
94 #include "ardour/midi_region.h"
95 #include "ardour/midi_source.h"
96 #include "ardour/midi_track.h"
97 #include "ardour/pannable.h"
98 #include "ardour/playlist_factory.h"
99 #include "ardour/port.h"
100 #include "ardour/processor.h"
101 #include "ardour/proxy_controllable.h"
102 #include "ardour/recent_sessions.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_playlists.h"
110 #include "ardour/session_state_utils.h"
111 #include "ardour/silentfilesource.h"
112 #include "ardour/sndfilesource.h"
113 #include "ardour/source_factory.h"
114 #include "ardour/speakers.h"
115 #include "ardour/template_utils.h"
116 #include "ardour/tempo.h"
117 #include "ardour/ticker.h"
118 #include "ardour/user_bundle.h"
120 #include "control_protocol/control_protocol.h"
126 using namespace ARDOUR;
130 Session::pre_engine_init (string fullpath)
132 if (fullpath.empty()) {
134 throw failed_constructor();
137 /* discover canonical fullpath */
139 _path = canonical_path(fullpath);
141 /* we require _path to end with a dir separator */
143 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
144 _path += G_DIR_SEPARATOR;
149 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
151 /* finish initialization that can't be done in a normal C++ constructor
155 timerclear (&last_mmc_step);
156 g_atomic_int_set (&processing_prohibited, 0);
157 g_atomic_int_set (&_record_status, Disabled);
158 g_atomic_int_set (&_playback_load, 100);
159 g_atomic_int_set (&_capture_load, 100);
161 _all_route_group->set_active (true, this);
162 interpolation.add_channel_to (0, 0);
164 if (config.get_use_video_sync()) {
165 waiting_for_sync_offset = true;
167 waiting_for_sync_offset = false;
170 last_rr_session_dir = session_dirs.begin();
172 set_history_depth (Config->get_history_depth());
174 /* default: assume simple stereo speaker configuration */
176 _speakers->setup_default_speakers (2);
178 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
179 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
180 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
181 add_controllable (_solo_cut_control);
183 /* These are all static "per-class" signals */
185 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
186 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
187 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
188 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
189 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
191 /* stop IO objects from doing stuff until we're ready for them */
193 Delivery::disable_panners ();
194 IO::disable_connecting ();
196 AudioFileSource::set_peak_dir (_session_dir->peak_path());
200 Session::post_engine_init ()
202 BootMessage (_("Set block size and sample rate"));
204 set_block_size (_engine.samples_per_cycle());
205 set_frame_rate (_engine.sample_rate());
207 BootMessage (_("Using configuration"));
209 _midi_ports = new MidiPortManager;
210 setup_midi_machine_control ();
212 if (_butler->start_thread()) {
216 if (start_midi_thread ()) {
220 setup_click_sounds (0);
221 setup_midi_control ();
223 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
224 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
227 /* tempo map requires sample rate knowledge */
229 _tempo_map = new TempoMap (_current_frame_rate);
230 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
232 /* MidiClock requires a tempo map */
234 midi_clock = new MidiClockTicker ();
235 midi_clock->set_session (this);
237 /* crossfades require sample rate knowledge */
239 SndFileSource::setup_standard_crossfades (*this, frame_rate());
240 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
242 AudioDiskstream::allocate_working_buffers();
243 refresh_disk_space ();
245 /* we're finally ready to call set_state() ... all objects have
246 * been created, the engine is running.
250 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
254 // set_state() will call setup_raid_path(), but if it's a new session we need
255 // to call setup_raid_path() here.
256 setup_raid_path (_path);
261 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
262 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
264 Config->map_parameters (ff);
265 config.map_parameters (ft);
267 /* Reset all panners */
269 Delivery::reset_panners ();
271 /* this will cause the CPM to instantiate any protocols that are in use
272 * (or mandatory), which will pass it this Session, and then call
273 * set_state() on each instantiated protocol to match stored state.
276 ControlProtocolManager::instance().set_session (this);
278 /* This must be done after the ControlProtocolManager set_session above,
279 as it will set states for ports which the ControlProtocolManager creates.
282 // XXX set state of MIDI::Port's
283 // MidiPortManager::instance()->set_port_states (Config->midi_port_states ());
285 /* And this must be done after the MIDI::Manager::set_port_states as
286 * it will try to make connections whose details are loaded by set_port_states.
291 /* Let control protocols know that we are now all connected, so they
292 * could start talking to surfaces if they want to.
295 ControlProtocolManager::instance().midi_connectivity_established ();
297 if (_is_new && !no_auto_connect()) {
298 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock());
299 auto_connect_master_bus ();
302 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
304 /* update latencies */
306 initialize_latencies ();
308 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
309 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
311 } catch (AudioEngine::PortRegistrationFailure& err) {
312 /* handle this one in a different way than all others, so that its clear what happened */
313 error << err.what() << endmsg;
319 BootMessage (_("Reset Remote Controls"));
321 // send_full_time_code (0);
322 _engine.transport_locate (0);
324 _mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
325 _mmc->send (MIDI::MachineControlCommand (Timecode::Time ()));
327 MIDI::Name::MidiPatchManager::instance().set_session (this);
330 /* initial program change will be delivered later; see ::config_changed() */
332 _state_of_the_state = Clean;
334 Port::set_connecting_blocked (false);
336 DirtyChanged (); /* EMIT SIGNAL */
340 } else if (state_was_pending) {
342 remove_pending_capture_state ();
343 state_was_pending = false;
350 Session::raid_path () const
352 Searchpath raid_search_path;
354 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
355 raid_search_path += (*i).path;
358 return raid_search_path.to_string ();
362 Session::setup_raid_path (string path)
371 session_dirs.clear ();
373 Searchpath search_path(path);
374 Searchpath sound_search_path;
375 Searchpath midi_search_path;
377 for (Searchpath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
379 sp.blocks = 0; // not needed
380 session_dirs.push_back (sp);
382 SessionDirectory sdir(sp.path);
384 sound_search_path += sdir.sound_path ();
385 midi_search_path += sdir.midi_path ();
388 // reset the round-robin soundfile path thingie
389 last_rr_session_dir = session_dirs.begin();
393 Session::path_is_within_session (const std::string& path)
395 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
396 if (PBD::path_is_within (i->path, path)) {
404 Session::ensure_subdirs ()
408 dir = session_directory().peak_path();
410 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
411 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
415 dir = session_directory().sound_path();
417 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
418 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
422 dir = session_directory().midi_path();
424 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
425 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
429 dir = session_directory().dead_path();
431 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
432 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
436 dir = session_directory().export_path();
438 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
439 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
443 dir = analysis_dir ();
445 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
446 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
450 dir = plugins_dir ();
452 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
453 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
457 dir = externals_dir ();
459 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
460 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
467 /** @param session_template directory containing session template, or empty.
468 * Caller must not hold process lock.
471 Session::create (const string& session_template, BusProfile* bus_profile)
473 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
474 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
478 if (ensure_subdirs ()) {
482 _writable = exists_and_writable (_path);
484 if (!session_template.empty()) {
485 std::string in_path = session_template_dir_to_file (session_template);
487 ifstream in(in_path.c_str());
490 /* no need to call legalize_for_path() since the string
491 * in session_template is already a legal path name
493 string out_path = Glib::build_filename (_session_dir->root_path(), _name + statefile_suffix);
495 ofstream out(out_path.c_str());
501 /* Copy plugin state files from template to new session */
502 std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
503 copy_files (template_plugins, plugins_dir ());
508 error << string_compose (_("Could not open %1 for writing session template"), out_path)
514 error << string_compose (_("Could not open session template %1 for reading"), in_path)
521 /* set initial start + end point */
523 _state_of_the_state = Clean;
525 /* set up Master Out and Control Out if necessary */
530 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
532 if (bus_profile->master_out_channels) {
533 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
537 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
538 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
541 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
542 r->input()->ensure_io (count, false, this);
543 r->output()->ensure_io (count, false, this);
549 /* prohibit auto-connect to master, because there isn't one */
550 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
554 add_routes (rl, false, false, false);
557 /* this allows the user to override settings with an environment variable.
560 if (no_auto_connect()) {
561 bus_profile->input_ac = AutoConnectOption (0);
562 bus_profile->output_ac = AutoConnectOption (0);
565 Config->set_input_auto_connect (bus_profile->input_ac);
566 Config->set_output_auto_connect (bus_profile->output_ac);
569 if (Config->get_use_monitor_bus() && bus_profile) {
570 add_monitor_section ();
577 Session::maybe_write_autosave()
579 if (dirty() && record_status() != Recording) {
580 save_state("", true);
585 Session::remove_pending_capture_state ()
587 std::string pending_state_file_path(_session_dir->root_path());
589 pending_state_file_path = Glib::build_filename (pending_state_file_path, legalize_for_path (_current_snapshot_name) + pending_suffix);
591 if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS)) return;
593 if (g_remove (pending_state_file_path.c_str()) != 0) {
594 error << string_compose(_("Could not remove pending capture state at path \"%1\" (%2)"),
595 pending_state_file_path, g_strerror (errno)) << endmsg;
599 /** Rename a state file.
600 * @param old_name Old snapshot name.
601 * @param new_name New snapshot name.
604 Session::rename_state (string old_name, string new_name)
606 if (old_name == _current_snapshot_name || old_name == _name) {
607 /* refuse to rename the current snapshot or the "main" one */
611 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
612 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
614 const std::string old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
615 const std::string new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
617 if (::g_rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
618 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
619 old_name, new_name, g_strerror(errno)) << endmsg;
623 /** Remove a state file.
624 * @param snapshot_name Snapshot name.
627 Session::remove_state (string snapshot_name)
629 if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
630 // refuse to remove the current snapshot or the "main" one
634 std::string xml_path(_session_dir->root_path());
636 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
638 if (!create_backup_file (xml_path)) {
639 // don't remove it if a backup can't be made
640 // create_backup_file will log the error.
645 if (g_remove (xml_path.c_str()) != 0) {
646 error << string_compose(_("Could not remove session file at path \"%1\" (%2)"),
647 xml_path, g_strerror (errno)) << endmsg;
651 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
653 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
656 std::string xml_path(_session_dir->root_path());
658 if (!_writable || (_state_of_the_state & CannotSave)) {
662 if (!_engine.connected ()) {
663 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
669 /* tell sources we're saving first, in case they write out to a new file
670 * which should be saved with the state rather than the old one */
671 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
673 i->second->session_saved();
674 } catch (Evoral::SMF::FileError& e) {
675 error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
679 SaveSession (); /* EMIT SIGNAL */
681 tree.set_root (&get_state());
683 if (snapshot_name.empty()) {
684 snapshot_name = _current_snapshot_name;
685 } else if (switch_to_snapshot) {
686 _current_snapshot_name = snapshot_name;
691 /* proper save: use statefile_suffix (.ardour in English) */
693 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
695 /* make a backup copy of the old file */
697 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) {
698 // create_backup_file will log the error
704 /* pending save: use pending_suffix (.pending in English) */
705 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
708 std::string tmp_path(_session_dir->root_path());
709 tmp_path = Glib::build_filename (tmp_path, legalize_for_path (snapshot_name) + temp_suffix);
711 // cerr << "actually writing state to " << xml_path << endl;
713 if (!tree.write (tmp_path)) {
714 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
715 if (g_remove (tmp_path.c_str()) != 0) {
716 error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
717 tmp_path, g_strerror (errno)) << endmsg;
723 if (::g_rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
724 error << string_compose (_("could not rename temporary session file %1 to %2 (%3)"),
725 tmp_path, xml_path, g_strerror(errno)) << endmsg;
726 if (g_remove (tmp_path.c_str()) != 0) {
727 error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
728 tmp_path, g_strerror (errno)) << endmsg;
736 save_history (snapshot_name);
738 bool was_dirty = dirty();
740 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
743 DirtyChanged (); /* EMIT SIGNAL */
746 StateSaved (snapshot_name); /* EMIT SIGNAL */
753 Session::restore_state (string snapshot_name)
755 if (load_state (snapshot_name) == 0) {
756 set_state (*state_tree->root(), Stateful::loading_state_version);
763 Session::load_state (string snapshot_name)
768 state_was_pending = false;
770 /* check for leftover pending state from a crashed capture attempt */
772 std::string xmlpath(_session_dir->root_path());
773 xmlpath = Glib::build_filename (xmlpath, legalize_for_path (snapshot_name) + pending_suffix);
775 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
777 /* there is pending state from a crashed capture attempt */
779 boost::optional<int> r = AskAboutPendingState();
780 if (r.get_value_or (1)) {
781 state_was_pending = true;
785 if (!state_was_pending) {
786 xmlpath = Glib::build_filename (_session_dir->root_path(), snapshot_name);
789 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
790 xmlpath = Glib::build_filename (_session_dir->root_path(), legalize_for_path (snapshot_name) + statefile_suffix);
791 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
792 error << string_compose(_("%1: session file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
797 state_tree = new XMLTree;
801 _writable = exists_and_writable (xmlpath);
803 if (!state_tree->read (xmlpath)) {
804 error << string_compose(_("Could not understand session file %1"), xmlpath) << endmsg;
810 XMLNode& root (*state_tree->root());
812 if (root.name() != X_("Session")) {
813 error << string_compose (_("Session file %1 is not a session"), xmlpath) << endmsg;
819 const XMLProperty* prop;
821 if ((prop = root.property ("version")) == 0) {
822 /* no version implies very old version of Ardour */
823 Stateful::loading_state_version = 1000;
825 if (prop->value().find ('.') != string::npos) {
826 /* old school version format */
827 if (prop->value()[0] == '2') {
828 Stateful::loading_state_version = 2000;
830 Stateful::loading_state_version = 3000;
833 Stateful::loading_state_version = atoi (prop->value());
837 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
839 std::string backup_path(_session_dir->root_path());
840 std::string backup_filename = string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
841 backup_path = Glib::build_filename (backup_path, backup_filename);
843 // only create a backup for a given statefile version once
845 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
847 VersionMismatch (xmlpath, backup_path);
849 if (!copy_file (xmlpath, backup_path)) {;
859 Session::load_options (const XMLNode& node)
861 LocaleGuard lg (X_("POSIX"));
862 config.set_variables (node);
873 Session::get_template()
875 /* if we don't disable rec-enable, diskstreams
876 will believe they need to store their capture
877 sources in their state node.
880 disable_record (false);
886 Session::state (bool full_state)
888 XMLNode* node = new XMLNode("Session");
892 snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
893 node->add_property("version", buf);
895 /* store configuration settings */
899 node->add_property ("name", _name);
900 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
901 node->add_property ("sample-rate", buf);
903 if (session_dirs.size() > 1) {
907 vector<space_and_path>::iterator i = session_dirs.begin();
908 vector<space_and_path>::iterator next;
910 ++i; /* skip the first one */
914 while (i != session_dirs.end()) {
918 if (next != session_dirs.end()) {
928 child = node->add_child ("Path");
929 child->add_content (p);
933 /* save the ID counter */
935 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
936 node->add_property ("id-counter", buf);
938 /* save the event ID counter */
940 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
941 node->add_property ("event-counter", buf);
943 /* various options */
945 list<XMLNode*> midi_port_nodes = _midi_ports->get_midi_port_states();
946 if (!midi_port_nodes.empty()) {
947 XMLNode* midi_port_stuff = new XMLNode ("MIDIPorts");
948 for (list<XMLNode*>::const_iterator n = midi_port_nodes.begin(); n != midi_port_nodes.end(); ++n) {
949 midi_port_stuff->add_child_nocopy (**n);
951 node->add_child_nocopy (*midi_port_stuff);
954 node->add_child_nocopy (config.get_variables ());
956 node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
958 child = node->add_child ("Sources");
961 Glib::Threads::Mutex::Lock sl (source_lock);
963 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
965 /* Don't save information about non-file Sources, or
966 * about non-destructive file sources that are empty
967 * and unused by any regions.
970 boost::shared_ptr<FileSource> fs;
972 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
974 if (!fs->destructive()) {
975 if (fs->empty() && !fs->used()) {
980 child->add_child_nocopy (siter->second->get_state());
985 child = node->add_child ("Regions");
988 Glib::Threads::Mutex::Lock rl (region_lock);
989 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
990 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
991 boost::shared_ptr<Region> r = i->second;
992 /* only store regions not attached to playlists */
993 if (r->playlist() == 0) {
994 if (boost::dynamic_pointer_cast<AudioRegion>(r)) {
995 child->add_child_nocopy ((boost::dynamic_pointer_cast<AudioRegion>(r))->get_basic_state ());
997 child->add_child_nocopy (r->get_state ());
1002 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1004 if (!cassocs.empty()) {
1005 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1007 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1009 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1010 i->first->id().print (buf, sizeof (buf));
1011 can->add_property (X_("copy"), buf);
1012 i->second->id().print (buf, sizeof (buf));
1013 can->add_property (X_("original"), buf);
1014 ca->add_child_nocopy (*can);
1020 node->add_child_nocopy (_locations->get_state());
1022 // for a template, just create a new Locations, populate it
1023 // with the default start and end, and get the state for that.
1024 Locations loc (*this);
1025 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1026 range->set (max_framepos, 0);
1028 node->add_child_nocopy (loc.get_state());
1031 child = node->add_child ("Bundles");
1033 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1034 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1035 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1037 child->add_child_nocopy (b->get_state());
1042 child = node->add_child ("Routes");
1044 boost::shared_ptr<RouteList> r = routes.reader ();
1046 RoutePublicOrderSorter cmp;
1047 RouteList public_order (*r);
1048 public_order.sort (cmp);
1050 /* the sort should have put control outs first */
1053 assert (_monitor_out == public_order.front());
1056 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1057 if (!(*i)->is_auditioner()) {
1059 child->add_child_nocopy ((*i)->get_state());
1061 child->add_child_nocopy ((*i)->get_template());
1067 playlists->add_state (node, full_state);
1069 child = node->add_child ("RouteGroups");
1070 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1071 child->add_child_nocopy ((*i)->get_state());
1075 XMLNode* gain_child = node->add_child ("Click");
1076 gain_child->add_child_nocopy (_click_io->state (full_state));
1077 gain_child->add_child_nocopy (_click_gain->state (full_state));
1081 XMLNode* ltc_input_child = node->add_child ("LTC-In");
1082 ltc_input_child->add_child_nocopy (_ltc_input->state (full_state));
1086 XMLNode* ltc_output_child = node->add_child ("LTC-Out");
1087 ltc_output_child->add_child_nocopy (_ltc_output->state (full_state));
1090 node->add_child_nocopy (_speakers->get_state());
1091 node->add_child_nocopy (_tempo_map->get_state());
1092 node->add_child_nocopy (get_control_protocol_state());
1095 node->add_child_copy (*_extra_xml);
1102 Session::get_control_protocol_state ()
1104 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1105 return cpm.get_state();
1109 Session::set_state (const XMLNode& node, int version)
1113 const XMLProperty* prop;
1116 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1118 if (node.name() != X_("Session")) {
1119 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1123 if ((prop = node.property ("name")) != 0) {
1124 _name = prop->value ();
1127 if ((prop = node.property (X_("sample-rate"))) != 0) {
1129 _nominal_frame_rate = atoi (prop->value());
1131 if (_nominal_frame_rate != _current_frame_rate) {
1132 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1133 if (r.get_value_or (0)) {
1139 setup_raid_path(_session_dir->root_path());
1141 if ((prop = node.property (X_("id-counter"))) != 0) {
1143 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1144 ID::init_counter (x);
1146 /* old sessions used a timebased counter, so fake
1147 the startup ID counter based on a standard
1152 ID::init_counter (now);
1155 if ((prop = node.property (X_("event-counter"))) != 0) {
1156 Evoral::init_event_id_counter (atoi (prop->value()));
1160 if ((child = find_named_node (node, "MIDIPorts")) != 0) {
1161 _midi_ports->set_midi_port_states (child->children());
1164 IO::disable_connecting ();
1166 Stateful::save_extra_xml (node);
1168 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1169 load_options (*child);
1170 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1171 load_options (*child);
1173 error << _("Session: XML state has no options section") << endmsg;
1176 if (version >= 3000) {
1177 if ((child = find_named_node (node, "Metadata")) == 0) {
1178 warning << _("Session: XML state has no metadata section") << endmsg;
1179 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1184 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1185 _speakers->set_state (*child, version);
1188 if ((child = find_named_node (node, "Sources")) == 0) {
1189 error << _("Session: XML state has no sources section") << endmsg;
1191 } else if (load_sources (*child)) {
1195 if ((child = find_named_node (node, "TempoMap")) == 0) {
1196 error << _("Session: XML state has no Tempo Map section") << endmsg;
1198 } else if (_tempo_map->set_state (*child, version)) {
1202 if ((child = find_named_node (node, "Locations")) == 0) {
1203 error << _("Session: XML state has no locations section") << endmsg;
1205 } else if (_locations->set_state (*child, version)) {
1211 if ((location = _locations->auto_loop_location()) != 0) {
1212 set_auto_loop_location (location);
1215 if ((location = _locations->auto_punch_location()) != 0) {
1216 set_auto_punch_location (location);
1219 if ((location = _locations->session_range_location()) != 0) {
1220 delete _session_range_location;
1221 _session_range_location = location;
1224 if (_session_range_location) {
1225 AudioFileSource::set_header_position_offset (_session_range_location->start());
1228 if ((child = find_named_node (node, "Regions")) == 0) {
1229 error << _("Session: XML state has no Regions section") << endmsg;
1231 } else if (load_regions (*child)) {
1235 if ((child = find_named_node (node, "Playlists")) == 0) {
1236 error << _("Session: XML state has no playlists section") << endmsg;
1238 } else if (playlists->load (*this, *child)) {
1242 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1244 } else if (playlists->load_unused (*this, *child)) {
1248 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1249 if (load_compounds (*child)) {
1254 if (version >= 3000) {
1255 if ((child = find_named_node (node, "Bundles")) == 0) {
1256 warning << _("Session: XML state has no bundles section") << endmsg;
1259 /* We can't load Bundles yet as they need to be able
1260 to convert from port names to Port objects, which can't happen until
1262 _bundle_xml_node = new XMLNode (*child);
1266 if (version < 3000) {
1267 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1268 error << _("Session: XML state has no diskstreams section") << endmsg;
1270 } else if (load_diskstreams_2X (*child, version)) {
1275 if ((child = find_named_node (node, "Routes")) == 0) {
1276 error << _("Session: XML state has no routes section") << endmsg;
1278 } else if (load_routes (*child, version)) {
1282 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1283 _diskstreams_2X.clear ();
1285 if (version >= 3000) {
1287 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1288 error << _("Session: XML state has no route groups section") << endmsg;
1290 } else if (load_route_groups (*child, version)) {
1294 } else if (version < 3000) {
1296 if ((child = find_named_node (node, "EditGroups")) == 0) {
1297 error << _("Session: XML state has no edit groups section") << endmsg;
1299 } else if (load_route_groups (*child, version)) {
1303 if ((child = find_named_node (node, "MixGroups")) == 0) {
1304 error << _("Session: XML state has no mix groups section") << endmsg;
1306 } else if (load_route_groups (*child, version)) {
1311 if ((child = find_named_node (node, "Click")) == 0) {
1312 warning << _("Session: XML state has no click section") << endmsg;
1313 } else if (_click_io) {
1314 setup_click_state (&node);
1317 if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
1318 ControlProtocolManager::instance().set_state (*child, version);
1321 update_have_rec_enabled_track ();
1323 /* here beginneth the second phase ... */
1325 StateReady (); /* EMIT SIGNAL */
1334 Session::load_routes (const XMLNode& node, int version)
1337 XMLNodeConstIterator niter;
1338 RouteList new_routes;
1340 nlist = node.children();
1344 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1346 boost::shared_ptr<Route> route;
1347 if (version < 3000) {
1348 route = XMLRouteFactory_2X (**niter, version);
1350 route = XMLRouteFactory (**niter, version);
1354 error << _("Session: cannot create Route from XML description.") << endmsg;
1358 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1360 new_routes.push_back (route);
1363 add_routes (new_routes, false, false, false);
1368 boost::shared_ptr<Route>
1369 Session::XMLRouteFactory (const XMLNode& node, int version)
1371 boost::shared_ptr<Route> ret;
1373 if (node.name() != "Route") {
1377 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1379 DataType type = DataType::AUDIO;
1380 const XMLProperty* prop = node.property("default-type");
1383 type = DataType (prop->value());
1386 assert (type != DataType::NIL);
1390 boost::shared_ptr<Track> track;
1392 if (type == DataType::AUDIO) {
1393 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1395 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1398 if (track->init()) {
1402 if (track->set_state (node, version)) {
1406 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1407 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1412 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1414 if (r->init () == 0 && r->set_state (node, version) == 0) {
1415 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1416 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1425 boost::shared_ptr<Route>
1426 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1428 boost::shared_ptr<Route> ret;
1430 if (node.name() != "Route") {
1434 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1436 ds_prop = node.property (X_("diskstream"));
1439 DataType type = DataType::AUDIO;
1440 const XMLProperty* prop = node.property("default-type");
1443 type = DataType (prop->value());
1446 assert (type != DataType::NIL);
1450 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1451 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1455 if (i == _diskstreams_2X.end()) {
1456 error << _("Could not find diskstream for route") << endmsg;
1457 return boost::shared_ptr<Route> ();
1460 boost::shared_ptr<Track> track;
1462 if (type == DataType::AUDIO) {
1463 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1465 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1468 if (track->init()) {
1472 if (track->set_state (node, version)) {
1476 track->set_diskstream (*i);
1478 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1479 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1484 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1486 if (r->init () == 0 && r->set_state (node, version) == 0) {
1487 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1488 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1498 Session::load_regions (const XMLNode& node)
1501 XMLNodeConstIterator niter;
1502 boost::shared_ptr<Region> region;
1504 nlist = node.children();
1508 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1509 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1510 error << _("Session: cannot create Region from XML description.");
1511 const XMLProperty *name = (**niter).property("name");
1514 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1525 Session::load_compounds (const XMLNode& node)
1527 XMLNodeList calist = node.children();
1528 XMLNodeConstIterator caiter;
1529 XMLProperty *caprop;
1531 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1532 XMLNode* ca = *caiter;
1536 if ((caprop = ca->property (X_("original"))) == 0) {
1539 orig_id = caprop->value();
1541 if ((caprop = ca->property (X_("copy"))) == 0) {
1544 copy_id = caprop->value();
1546 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1547 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1549 if (!orig || !copy) {
1550 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1556 RegionFactory::add_compound_association (orig, copy);
1563 Session::load_nested_sources (const XMLNode& node)
1566 XMLNodeConstIterator niter;
1568 nlist = node.children();
1570 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1571 if ((*niter)->name() == "Source") {
1573 /* it may already exist, so don't recreate it unnecessarily
1576 XMLProperty* prop = (*niter)->property (X_("id"));
1578 error << _("Nested source has no ID info in session file! (ignored)") << endmsg;
1582 ID source_id (prop->value());
1584 if (!source_by_id (source_id)) {
1587 SourceFactory::create (*this, **niter, true);
1589 catch (failed_constructor& err) {
1590 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1597 boost::shared_ptr<Region>
1598 Session::XMLRegionFactory (const XMLNode& node, bool full)
1600 const XMLProperty* type = node.property("type");
1604 const XMLNodeList& nlist = node.children();
1606 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1607 XMLNode *child = (*niter);
1608 if (child->name() == "NestedSource") {
1609 load_nested_sources (*child);
1613 if (!type || type->value() == "audio") {
1614 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1615 } else if (type->value() == "midi") {
1616 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;
1753 if (node.name() != X_("Region")) {
1754 return boost::shared_ptr<MidiRegion>();
1757 if ((prop = node.property ("name")) == 0) {
1758 cerr << "no name for this region\n";
1762 if ((prop = node.property (X_("source-0"))) == 0) {
1763 if ((prop = node.property ("source")) == 0) {
1764 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1765 return boost::shared_ptr<MidiRegion>();
1769 PBD::ID s_id (prop->value());
1771 if ((source = source_by_id (s_id)) == 0) {
1772 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1773 return boost::shared_ptr<MidiRegion>();
1776 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1778 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1779 return boost::shared_ptr<MidiRegion>();
1782 sources.push_back (ms);
1785 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1786 /* a final detail: this is the one and only place that we know how long missing files are */
1788 if (region->whole_file()) {
1789 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1790 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1792 sfp->set_length (region->length());
1800 catch (failed_constructor& err) {
1801 return boost::shared_ptr<MidiRegion>();
1806 Session::get_sources_as_xml ()
1809 XMLNode* node = new XMLNode (X_("Sources"));
1810 Glib::Threads::Mutex::Lock lm (source_lock);
1812 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1813 node->add_child_nocopy (i->second->get_state());
1820 Session::path_from_region_name (DataType type, string name, string identifier)
1822 char buf[PATH_MAX+1];
1824 SessionDirectory sdir(get_best_session_directory_for_new_source());
1825 std::string source_dir = ((type == DataType::AUDIO)
1826 ? sdir.sound_path() : sdir.midi_path());
1828 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1830 for (n = 0; n < 999999; ++n) {
1831 if (identifier.length()) {
1832 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1833 identifier.c_str(), n, ext.c_str());
1835 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1839 std::string source_path = Glib::build_filename (source_dir, buf);
1841 if (!Glib::file_test (source_path, Glib::FILE_TEST_EXISTS)) {
1846 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1855 Session::load_sources (const XMLNode& node)
1858 XMLNodeConstIterator niter;
1859 boost::shared_ptr<Source> source;
1861 nlist = node.children();
1865 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1868 if ((source = XMLSourceFactory (**niter)) == 0) {
1869 error << _("Session: cannot create Source from XML description.") << endmsg;
1872 } catch (MissingSource& err) {
1876 if (!no_questions_about_missing_files) {
1877 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1882 switch (user_choice) {
1884 /* user added a new search location, so try again */
1889 /* user asked to quit the entire session load
1894 no_questions_about_missing_files = true;
1898 no_questions_about_missing_files = true;
1903 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1904 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1913 boost::shared_ptr<Source>
1914 Session::XMLSourceFactory (const XMLNode& node)
1916 if (node.name() != "Source") {
1917 return boost::shared_ptr<Source>();
1921 /* note: do peak building in another thread when loading session state */
1922 return SourceFactory::create (*this, node, true);
1925 catch (failed_constructor& err) {
1926 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1927 return boost::shared_ptr<Source>();
1932 Session::save_template (string template_name)
1936 if (_state_of_the_state & CannotSave) {
1940 std::string user_template_dir(user_template_directory());
1942 if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
1943 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
1944 user_template_dir, g_strerror (errno)) << endmsg;
1948 tree.set_root (&get_template());
1950 std::string template_dir_path(user_template_dir);
1952 /* directory to put the template in */
1953 template_dir_path = Glib::build_filename (template_dir_path, template_name);
1955 if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
1956 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1957 template_dir_path) << endmsg;
1961 if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
1962 error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
1963 template_dir_path, g_strerror (errno)) << endmsg;
1968 std::string template_file_path(template_dir_path);
1969 template_file_path = Glib::build_filename (template_file_path, template_name + template_suffix);
1971 if (!tree.write (template_file_path)) {
1972 error << _("template not saved") << endmsg;
1976 /* copy plugin state directory */
1978 std::string template_plugin_state_path(template_dir_path);
1979 template_plugin_state_path = Glib::build_filename (template_plugin_state_path, X_("plugins"));
1981 if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
1982 error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
1983 template_plugin_state_path, g_strerror (errno)) << endmsg;
1987 copy_files (plugins_dir(), template_plugin_state_path);
1993 Session::refresh_disk_space ()
1995 #if __APPLE__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
1997 Glib::Threads::Mutex::Lock lm (space_lock);
1999 /* get freespace on every FS that is part of the session path */
2001 _total_free_4k_blocks = 0;
2002 _total_free_4k_blocks_uncertain = false;
2004 for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2006 struct statfs statfsbuf;
2007 statfs (i->path.c_str(), &statfsbuf);
2009 double const scale = statfsbuf.f_bsize / 4096.0;
2011 /* See if this filesystem is read-only */
2012 struct statvfs statvfsbuf;
2013 statvfs (i->path.c_str(), &statvfsbuf);
2015 /* f_bavail can be 0 if it is undefined for whatever
2016 filesystem we are looking at; Samba shares mounted
2017 via GVFS are an example of this.
2019 if (statfsbuf.f_bavail == 0) {
2020 /* block count unknown */
2022 i->blocks_unknown = true;
2023 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2024 /* read-only filesystem */
2026 i->blocks_unknown = false;
2028 /* read/write filesystem with known space */
2029 i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2030 i->blocks_unknown = false;
2033 _total_free_4k_blocks += i->blocks;
2034 if (i->blocks_unknown) {
2035 _total_free_4k_blocks_uncertain = true;
2038 #elif defined (COMPILER_MSVC)
2039 vector<string> scanned_volumes;
2040 vector<string>::iterator j;
2041 vector<space_and_path>::iterator i;
2042 DWORD nSectorsPerCluster, nBytesPerSector,
2043 nFreeClusters, nTotalClusters;
2047 _total_free_4k_blocks = 0;
2049 for (i = session_dirs.begin(); i != session_dirs.end(); i++) {
2050 strncpy (disk_drive, (*i).path.c_str(), 3);
2054 volume_found = false;
2055 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2057 int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2058 int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2059 i->blocks = (uint32_t)(nFreeBytes / 4096);
2061 for (j = scanned_volumes.begin(); j != scanned_volumes.end(); j++) {
2062 if (0 == j->compare(disk_drive)) {
2063 volume_found = true;
2068 if (!volume_found) {
2069 scanned_volumes.push_back(disk_drive);
2070 _total_free_4k_blocks += i->blocks;
2075 if (0 == _total_free_4k_blocks) {
2076 strncpy (disk_drive, path().c_str(), 3);
2079 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2081 int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2082 int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2083 _total_free_4k_blocks = (uint32_t)(nFreeBytes / 4096);
2090 Session::get_best_session_directory_for_new_source ()
2092 vector<space_and_path>::iterator i;
2093 string result = _session_dir->root_path();
2095 /* handle common case without system calls */
2097 if (session_dirs.size() == 1) {
2101 /* OK, here's the algorithm we're following here:
2103 We want to select which directory to use for
2104 the next file source to be created. Ideally,
2105 we'd like to use a round-robin process so as to
2106 get maximum performance benefits from splitting
2107 the files across multiple disks.
2109 However, in situations without much diskspace, an
2110 RR approach may end up filling up a filesystem
2111 with new files while others still have space.
2112 Its therefore important to pay some attention to
2113 the freespace in the filesystem holding each
2114 directory as well. However, if we did that by
2115 itself, we'd keep creating new files in the file
2116 system with the most space until it was as full
2117 as all others, thus negating any performance
2118 benefits of this RAID-1 like approach.
2120 So, we use a user-configurable space threshold. If
2121 there are at least 2 filesystems with more than this
2122 much space available, we use RR selection between them.
2123 If not, then we pick the filesystem with the most space.
2125 This gets a good balance between the two
2129 refresh_disk_space ();
2131 int free_enough = 0;
2133 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2134 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2139 if (free_enough >= 2) {
2140 /* use RR selection process, ensuring that the one
2144 i = last_rr_session_dir;
2147 if (++i == session_dirs.end()) {
2148 i = session_dirs.begin();
2151 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2152 SessionDirectory sdir(i->path);
2153 if (sdir.create ()) {
2155 last_rr_session_dir = i;
2160 } while (i != last_rr_session_dir);
2164 /* pick FS with the most freespace (and that
2165 seems to actually work ...)
2168 vector<space_and_path> sorted;
2169 space_and_path_ascending_cmp cmp;
2171 sorted = session_dirs;
2172 sort (sorted.begin(), sorted.end(), cmp);
2174 for (i = sorted.begin(); i != sorted.end(); ++i) {
2175 SessionDirectory sdir(i->path);
2176 if (sdir.create ()) {
2178 last_rr_session_dir = i;
2188 Session::automation_dir () const
2190 return Glib::build_filename (_path, "automation");
2194 Session::analysis_dir () const
2196 return Glib::build_filename (_path, "analysis");
2200 Session::plugins_dir () const
2202 return Glib::build_filename (_path, "plugins");
2206 Session::externals_dir () const
2208 return Glib::build_filename (_path, "externals");
2212 Session::load_bundles (XMLNode const & node)
2214 XMLNodeList nlist = node.children();
2215 XMLNodeConstIterator niter;
2219 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2220 if ((*niter)->name() == "InputBundle") {
2221 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2222 } else if ((*niter)->name() == "OutputBundle") {
2223 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2225 error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
2234 Session::load_route_groups (const XMLNode& node, int version)
2236 XMLNodeList nlist = node.children();
2237 XMLNodeConstIterator niter;
2241 if (version >= 3000) {
2243 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2244 if ((*niter)->name() == "RouteGroup") {
2245 RouteGroup* rg = new RouteGroup (*this, "");
2246 add_route_group (rg);
2247 rg->set_state (**niter, version);
2251 } else if (version < 3000) {
2253 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2254 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2255 RouteGroup* rg = new RouteGroup (*this, "");
2256 add_route_group (rg);
2257 rg->set_state (**niter, version);
2266 Session::auto_save()
2268 save_state (_current_snapshot_name);
2272 state_file_filter (const string &str, void* /*arg*/)
2274 return (str.length() > strlen(statefile_suffix) &&
2275 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2279 bool operator()(const string* a, const string* b) {
2285 remove_end(string* state)
2287 string statename(*state);
2289 string::size_type start,end;
2290 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2291 statename = statename.substr (start+1);
2294 if ((end = statename.rfind(".ardour")) == string::npos) {
2295 end = statename.length();
2298 return new string(statename.substr (0, end));
2302 Session::possible_states (string path)
2304 PathScanner scanner;
2305 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2307 transform(states->begin(), states->end(), states->begin(), remove_end);
2310 sort (states->begin(), states->end(), cmp);
2316 Session::possible_states () const
2318 return possible_states(_path);
2322 Session::add_route_group (RouteGroup* g)
2324 _route_groups.push_back (g);
2325 route_group_added (g); /* EMIT SIGNAL */
2327 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2328 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2329 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2335 Session::remove_route_group (RouteGroup& rg)
2337 list<RouteGroup*>::iterator i;
2339 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2340 _route_groups.erase (i);
2343 route_group_removed (); /* EMIT SIGNAL */
2347 /** Set a new order for our route groups, without adding or removing any.
2348 * @param groups Route group list in the new order.
2351 Session::reorder_route_groups (list<RouteGroup*> groups)
2353 _route_groups = groups;
2355 route_groups_reordered (); /* EMIT SIGNAL */
2361 Session::route_group_by_name (string name)
2363 list<RouteGroup *>::iterator i;
2365 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2366 if ((*i)->name() == name) {
2374 Session::all_route_group() const
2376 return *_all_route_group;
2380 Session::add_commands (vector<Command*> const & cmds)
2382 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2388 Session::begin_reversible_command (const string& name)
2390 begin_reversible_command (g_quark_from_string (name.c_str ()));
2393 /** Begin a reversible command using a GQuark to identify it.
2394 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2395 * but there must be as many begin...()s as there are commit...()s.
2398 Session::begin_reversible_command (GQuark q)
2400 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2401 to hold all the commands that are committed. This keeps the order of
2402 commands correct in the history.
2405 if (_current_trans == 0) {
2406 /* start a new transaction */
2407 assert (_current_trans_quarks.empty ());
2408 _current_trans = new UndoTransaction();
2409 _current_trans->set_name (g_quark_to_string (q));
2412 _current_trans_quarks.push_front (q);
2416 Session::commit_reversible_command (Command *cmd)
2418 assert (_current_trans);
2419 assert (!_current_trans_quarks.empty ());
2424 _current_trans->add_command (cmd);
2427 _current_trans_quarks.pop_front ();
2429 if (!_current_trans_quarks.empty ()) {
2430 /* the transaction we're committing is not the top-level one */
2434 if (_current_trans->empty()) {
2435 /* no commands were added to the transaction, so just get rid of it */
2436 delete _current_trans;
2441 gettimeofday (&now, 0);
2442 _current_trans->set_timestamp (now);
2444 _history.add (_current_trans);
2449 accept_all_audio_files (const string& path, void* /*arg*/)
2451 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2455 if (!AudioFileSource::safe_audio_file_extension (path)) {
2463 accept_all_midi_files (const string& path, void* /*arg*/)
2465 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2469 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2470 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2471 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2475 accept_all_state_files (const string& path, void* /*arg*/)
2477 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2481 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2485 Session::find_all_sources (string path, set<string>& result)
2490 if (!tree.read (path)) {
2494 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2499 XMLNodeConstIterator niter;
2501 nlist = node->children();
2505 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2509 if ((prop = (*niter)->property (X_("type"))) == 0) {
2513 DataType type (prop->value());
2515 if ((prop = (*niter)->property (X_("name"))) == 0) {
2519 if (Glib::path_is_absolute (prop->value())) {
2520 /* external file, ignore */
2528 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2529 result.insert (found_path);
2537 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2539 PathScanner scanner;
2540 vector<string*>* state_files;
2542 string this_snapshot_path;
2548 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2549 ripped = ripped.substr (0, ripped.length() - 1);
2552 state_files = scanner (ripped, accept_all_state_files, (void *) 0, true, true);
2554 if (state_files == 0) {
2559 this_snapshot_path = _path;
2560 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2561 this_snapshot_path += statefile_suffix;
2563 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2565 if (exclude_this_snapshot && **i == this_snapshot_path) {
2569 if (find_all_sources (**i, result) < 0) {
2577 struct RegionCounter {
2578 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2579 AudioSourceList::iterator iter;
2580 boost::shared_ptr<Region> region;
2583 RegionCounter() : count (0) {}
2587 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2589 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2590 return r.get_value_or (1);
2594 Session::cleanup_regions ()
2596 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2598 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2600 uint32_t used = playlists->region_use_count (i->second);
2602 if (used == 0 && !i->second->automatic ()) {
2603 RegionFactory::map_remove (i->second);
2607 /* dump the history list */
2614 Session::cleanup_sources (CleanupReport& rep)
2616 // FIXME: needs adaptation to midi
2618 vector<boost::shared_ptr<Source> > dead_sources;
2619 PathScanner scanner;
2622 vector<space_and_path>::iterator i;
2623 vector<space_and_path>::iterator nexti;
2624 vector<string*>* candidates;
2625 vector<string*>* candidates2;
2626 vector<string> unused;
2627 set<string> all_sources;
2634 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2636 /* consider deleting all unused playlists */
2638 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2643 /* sync the "all regions" property of each playlist with its current state
2646 playlists->sync_all_regions_with_regions ();
2648 /* find all un-used sources */
2653 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2655 SourceMap::iterator tmp;
2660 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2664 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2665 dead_sources.push_back (i->second);
2666 i->second->drop_references ();
2672 /* build a list of all the possible audio directories for the session */
2674 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2679 SessionDirectory sdir ((*i).path);
2680 audio_path += sdir.sound_path();
2682 if (nexti != session_dirs.end()) {
2690 /* build a list of all the possible midi directories for the session */
2692 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2697 SessionDirectory sdir ((*i).path);
2698 midi_path += sdir.midi_path();
2700 if (nexti != session_dirs.end()) {
2707 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2708 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2714 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2715 candidates->push_back (*i);
2720 candidates = candidates2; // might still be null
2723 /* find all sources, but don't use this snapshot because the
2724 state file on disk still references sources we may have already
2728 find_all_sources_across_snapshots (all_sources, true);
2730 /* add our current source list
2733 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2734 boost::shared_ptr<FileSource> fs;
2735 SourceMap::iterator tmp = i;
2738 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2740 if (!fs->is_stub()) {
2742 if (playlists->source_use_count (fs) != 0) {
2743 all_sources.insert (fs->path());
2746 /* we might not remove this source from disk, because it may be used
2747 by other snapshots, but its not being used in this version
2748 so lets get rid of it now, along with any representative regions
2752 RegionFactory::remove_regions_using_source (i->second);
2762 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2767 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2769 tmppath1 = canonical_path (spath);
2770 tmppath2 = canonical_path ((*i));
2772 if (tmppath1 == tmppath2) {
2779 unused.push_back (spath);
2788 /* now try to move all unused files into the "dead" directory(ies) */
2790 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2791 struct stat statbuf;
2795 /* don't move the file across filesystems, just
2796 stick it in the `dead_dir_name' directory
2797 on whichever filesystem it was already on.
2800 if ((*x).find ("/sounds/") != string::npos) {
2802 /* old school, go up 1 level */
2804 newpath = Glib::path_get_dirname (*x); // "sounds"
2805 newpath = Glib::path_get_dirname (newpath); // "session-name"
2809 /* new school, go up 4 levels */
2811 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2812 newpath = Glib::path_get_dirname (newpath); // "session-name"
2813 newpath = Glib::path_get_dirname (newpath); // "interchange"
2814 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2817 newpath = Glib::build_filename (newpath, dead_dir_name);
2819 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2820 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2824 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2826 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2828 /* the new path already exists, try versioning */
2830 char buf[PATH_MAX+1];
2834 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2837 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2838 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2842 if (version == 999) {
2843 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2847 newpath = newpath_v;
2852 /* it doesn't exist, or we can't read it or something */
2856 stat ((*x).c_str(), &statbuf);
2858 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2859 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2860 (*x), newpath, strerror (errno))
2865 /* see if there an easy to find peakfile for this file, and remove it.
2868 string base = basename_nosuffix (*x);
2869 base += "%A"; /* this is what we add for the channel suffix of all native files,
2870 or for the first channel of embedded files. it will miss
2871 some peakfiles for other channels
2873 string peakpath = peak_path (base);
2875 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2876 if (::g_unlink (peakpath.c_str()) != 0) {
2877 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2878 peakpath, _path, strerror (errno))
2880 /* try to back out */
2881 ::rename (newpath.c_str(), _path.c_str());
2886 rep.paths.push_back (*x);
2887 rep.space += statbuf.st_size;
2890 /* dump the history list */
2894 /* save state so we don't end up a session file
2895 referring to non-existent sources.
2902 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2908 Session::cleanup_trash_sources (CleanupReport& rep)
2910 // FIXME: needs adaptation for MIDI
2912 vector<space_and_path>::iterator i;
2918 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2920 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2922 clear_directory (dead_dir, &rep.space, &rep.paths);
2929 Session::set_dirty ()
2931 bool was_dirty = dirty();
2933 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2937 DirtyChanged(); /* EMIT SIGNAL */
2943 Session::set_clean ()
2945 bool was_dirty = dirty();
2947 _state_of_the_state = Clean;
2951 DirtyChanged(); /* EMIT SIGNAL */
2956 Session::set_deletion_in_progress ()
2958 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2962 Session::clear_deletion_in_progress ()
2964 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2968 Session::add_controllable (boost::shared_ptr<Controllable> c)
2970 /* this adds a controllable to the list managed by the Session.
2971 this is a subset of those managed by the Controllable class
2972 itself, and represents the only ones whose state will be saved
2973 as part of the session.
2976 Glib::Threads::Mutex::Lock lm (controllables_lock);
2977 controllables.insert (c);
2980 struct null_deleter { void operator()(void const *) const {} };
2983 Session::remove_controllable (Controllable* c)
2985 if (_state_of_the_state & Deletion) {
2989 Glib::Threads::Mutex::Lock lm (controllables_lock);
2991 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2993 if (x != controllables.end()) {
2994 controllables.erase (x);
2998 boost::shared_ptr<Controllable>
2999 Session::controllable_by_id (const PBD::ID& id)
3001 Glib::Threads::Mutex::Lock lm (controllables_lock);
3003 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3004 if ((*i)->id() == id) {
3009 return boost::shared_ptr<Controllable>();
3012 boost::shared_ptr<Controllable>
3013 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3015 boost::shared_ptr<Controllable> c;
3016 boost::shared_ptr<Route> r;
3018 switch (desc.top_level_type()) {
3019 case ControllableDescriptor::NamedRoute:
3021 std::string str = desc.top_level_name();
3022 if (str == "master") {
3024 } else if (str == "control" || str == "listen") {
3027 r = route_by_name (desc.top_level_name());
3032 case ControllableDescriptor::RemoteControlID:
3033 r = route_by_remote_id (desc.rid());
3041 switch (desc.subtype()) {
3042 case ControllableDescriptor::Gain:
3043 c = r->gain_control ();
3046 case ControllableDescriptor::Solo:
3047 c = r->solo_control();
3050 case ControllableDescriptor::Mute:
3051 c = r->mute_control();
3054 case ControllableDescriptor::Recenable:
3056 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3059 c = t->rec_enable_control ();
3064 case ControllableDescriptor::PanDirection:
3066 c = r->pannable()->pan_azimuth_control;
3070 case ControllableDescriptor::PanWidth:
3072 c = r->pannable()->pan_width_control;
3076 case ControllableDescriptor::PanElevation:
3078 c = r->pannable()->pan_elevation_control;
3082 case ControllableDescriptor::Balance:
3083 /* XXX simple pan control */
3086 case ControllableDescriptor::PluginParameter:
3088 uint32_t plugin = desc.target (0);
3089 uint32_t parameter_index = desc.target (1);
3091 /* revert to zero based counting */
3097 if (parameter_index > 0) {
3101 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3104 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3105 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3110 case ControllableDescriptor::SendGain:
3112 uint32_t send = desc.target (0);
3114 /* revert to zero-based counting */
3120 boost::shared_ptr<Processor> p = r->nth_send (send);
3123 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3124 boost::shared_ptr<Amp> a = s->amp();
3127 c = s->amp()->gain_control();
3134 /* relax and return a null pointer */
3142 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3145 Stateful::add_instant_xml (node, _path);
3148 if (write_to_config) {
3149 Config->add_instant_xml (node);
3154 Session::instant_xml (const string& node_name)
3156 return Stateful::instant_xml (node_name, _path);
3160 Session::save_history (string snapshot_name)
3168 if (snapshot_name.empty()) {
3169 snapshot_name = _current_snapshot_name;
3172 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3173 const string backup_filename = history_filename + backup_suffix;
3174 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3175 const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3177 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3178 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3179 error << _("could not backup old history file, current history not saved") << endmsg;
3184 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3188 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3190 if (!tree.write (xml_path))
3192 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3194 if (g_remove (xml_path.c_str()) != 0) {
3195 error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3196 xml_path, g_strerror (errno)) << endmsg;
3198 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3199 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3200 backup_path, g_strerror (errno)) << endmsg;
3210 Session::restore_history (string snapshot_name)
3214 if (snapshot_name.empty()) {
3215 snapshot_name = _current_snapshot_name;
3218 const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3219 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3221 info << "Loading history from " << xml_path << endmsg;
3223 if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3224 info << string_compose (_("%1: no history file \"%2\" for this session."),
3225 _name, xml_path) << endmsg;
3229 if (!tree.read (xml_path)) {
3230 error << string_compose (_("Could not understand session history file \"%1\""),
3231 xml_path) << endmsg;
3238 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3241 UndoTransaction* ut = new UndoTransaction ();
3244 ut->set_name(t->property("name")->value());
3245 stringstream ss(t->property("tv-sec")->value());
3247 ss.str(t->property("tv-usec")->value());
3249 ut->set_timestamp(tv);
3251 for (XMLNodeConstIterator child_it = t->children().begin();
3252 child_it != t->children().end(); child_it++)
3254 XMLNode *n = *child_it;
3257 if (n->name() == "MementoCommand" ||
3258 n->name() == "MementoUndoCommand" ||
3259 n->name() == "MementoRedoCommand") {
3261 if ((c = memento_command_factory(n))) {
3265 } else if (n->name() == "NoteDiffCommand") {
3266 PBD::ID id (n->property("midi-source")->value());
3267 boost::shared_ptr<MidiSource> midi_source =
3268 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3270 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3272 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3275 } else if (n->name() == "SysExDiffCommand") {
3277 PBD::ID id (n->property("midi-source")->value());
3278 boost::shared_ptr<MidiSource> midi_source =
3279 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3281 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3283 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3286 } else if (n->name() == "PatchChangeDiffCommand") {
3288 PBD::ID id (n->property("midi-source")->value());
3289 boost::shared_ptr<MidiSource> midi_source =
3290 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3292 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3294 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3297 } else if (n->name() == "StatefulDiffCommand") {
3298 if ((c = stateful_diff_command_factory (n))) {
3299 ut->add_command (c);
3302 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3313 Session::config_changed (std::string p, bool ours)
3319 if (p == "seamless-loop") {
3321 } else if (p == "rf-speed") {
3323 } else if (p == "auto-loop") {
3325 } else if (p == "auto-input") {
3327 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3328 /* auto-input only makes a difference if we're rolling */
3329 set_track_monitor_input_status (!config.get_auto_input());
3332 } else if (p == "punch-in") {
3336 if ((location = _locations->auto_punch_location()) != 0) {
3338 if (config.get_punch_in ()) {
3339 replace_event (SessionEvent::PunchIn, location->start());
3341 remove_event (location->start(), SessionEvent::PunchIn);
3345 } else if (p == "punch-out") {
3349 if ((location = _locations->auto_punch_location()) != 0) {
3351 if (config.get_punch_out()) {
3352 replace_event (SessionEvent::PunchOut, location->end());
3354 clear_events (SessionEvent::PunchOut);
3358 } else if (p == "edit-mode") {
3360 Glib::Threads::Mutex::Lock lm (playlists->lock);
3362 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3363 (*i)->set_edit_mode (Config->get_edit_mode ());
3366 } else if (p == "use-video-sync") {
3368 waiting_for_sync_offset = config.get_use_video_sync();
3370 } else if (p == "mmc-control") {
3372 //poke_midi_thread ();
3374 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3376 _mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3378 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3380 _mmc->set_send_device_id (Config->get_mmc_send_device_id());
3382 } else if (p == "midi-control") {
3384 //poke_midi_thread ();
3386 } else if (p == "raid-path") {
3388 setup_raid_path (config.get_raid_path());
3390 } else if (p == "timecode-format") {
3394 } else if (p == "video-pullup") {
3398 } else if (p == "seamless-loop") {
3400 if (play_loop && transport_rolling()) {
3401 // to reset diskstreams etc
3402 request_play_loop (true);
3405 } else if (p == "rf-speed") {
3407 cumulative_rf_motion = 0;
3410 } else if (p == "click-sound") {
3412 setup_click_sounds (1);
3414 } else if (p == "click-emphasis-sound") {
3416 setup_click_sounds (-1);
3418 } else if (p == "clicking") {
3420 if (Config->get_clicking()) {
3421 if (_click_io && click_data) { // don't require emphasis data
3428 } else if (p == "click-gain") {
3431 _click_gain->set_gain (Config->get_click_gain(), this);
3434 } else if (p == "send-mtc") {
3436 if (Config->get_send_mtc ()) {
3437 /* mark us ready to send */
3438 next_quarter_frame_to_send = 0;
3441 } else if (p == "send-mmc") {
3443 _mmc->enable_send (Config->get_send_mmc ());
3445 } else if (p == "midi-feedback") {
3447 session_midi_feedback = Config->get_midi_feedback();
3449 } else if (p == "jack-time-master") {
3451 engine().reset_timebase ();
3453 } else if (p == "native-file-header-format") {
3455 if (!first_file_header_format_reset) {
3456 reset_native_file_format ();
3459 first_file_header_format_reset = false;
3461 } else if (p == "native-file-data-format") {
3463 if (!first_file_data_format_reset) {
3464 reset_native_file_format ();
3467 first_file_data_format_reset = false;
3469 } else if (p == "external-sync") {
3470 if (!config.get_external_sync()) {
3471 drop_sync_source ();
3473 switch_to_sync_source (Config->get_sync_source());
3475 } else if (p == "denormal-model") {
3477 } else if (p == "history-depth") {
3478 set_history_depth (Config->get_history_depth());
3479 } else if (p == "remote-model") {
3480 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
3483 } else if (p == "initial-program-change") {
3485 if (_mmc->output_port() && Config->get_initial_program_change() >= 0) {
3488 buf[0] = MIDI::program; // channel zero by default
3489 buf[1] = (Config->get_initial_program_change() & 0x7f);
3491 _mmc->output_port()->midimsg (buf, sizeof (buf), 0);
3493 } else if (p == "solo-mute-override") {
3494 // catch_up_on_solo_mute_override ();
3495 } else if (p == "listen-position" || p == "pfl-position") {
3496 listen_position_changed ();
3497 } else if (p == "solo-control-is-listen-control") {
3498 solo_control_mode_changed ();
3499 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3500 last_timecode_valid = false;
3501 } else if (p == "playback-buffer-seconds") {
3502 AudioSource::allocate_working_buffers (frame_rate());
3503 } else if (p == "automation-thinning-factor") {
3504 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3505 } else if (p == "ltc-source-port") {
3506 reconnect_ltc_input ();
3507 } else if (p == "ltc-sink-port") {
3508 reconnect_ltc_output ();
3509 } else if (p == "timecode-generator-offset") {
3510 ltc_tx_parse_offset();
3517 Session::set_history_depth (uint32_t d)
3519 _history.set_depth (d);
3523 Session::load_diskstreams_2X (XMLNode const & node, int)
3526 XMLNodeConstIterator citer;
3528 clist = node.children();
3530 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3533 /* diskstreams added automatically by DiskstreamCreated handler */
3534 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3535 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3536 _diskstreams_2X.push_back (dsp);
3538 error << _("Session: unknown diskstream type in XML") << endmsg;
3542 catch (failed_constructor& err) {
3543 error << _("Session: could not load diskstream via XML state") << endmsg;
3551 /** Connect things to the MMC object */
3553 Session::setup_midi_machine_control ()
3555 _mmc = new MIDI::MachineControl;
3556 _mmc->set_ports (_midi_ports->mmc_input_port(), _midi_ports->mmc_output_port());
3558 _mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3559 _mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3560 _mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3561 _mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3562 _mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3563 _mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3564 _mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3565 _mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3566 _mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3567 _mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3568 _mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3569 _mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3570 _mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3572 /* also handle MIDI SPP because its so common */
3574 _mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3575 _mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3576 _mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3579 boost::shared_ptr<Controllable>
3580 Session::solo_cut_control() const
3582 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3583 controls in Ardour that currently get presented to the user in the GUI that require
3584 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3586 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3587 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3591 return _solo_cut_control;
3595 Session::rename (const std::string& new_name)
3597 string legal_name = legalize_for_path (new_name);
3603 string const old_sources_root = _session_dir->sources_root();
3605 #define RENAME ::rename
3610 * interchange subdirectory
3614 * Backup files are left unchanged and not renamed.
3617 /* pass one: not 100% safe check that the new directory names don't
3621 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3626 /* this is a stupid hack because Glib::path_get_dirname() is
3627 * lexical-only, and so passing it /a/b/c/ gives a different
3628 * result than passing it /a/b/c ...
3631 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3632 oldstr = oldstr.substr (0, oldstr.length() - 1);
3635 string base = Glib::path_get_dirname (oldstr);
3636 string p = Glib::path_get_basename (oldstr);
3638 newstr = Glib::build_filename (base, legal_name);
3640 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3647 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3652 /* this is a stupid hack because Glib::path_get_dirname() is
3653 * lexical-only, and so passing it /a/b/c/ gives a different
3654 * result than passing it /a/b/c ...
3657 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3658 oldstr = oldstr.substr (0, oldstr.length() - 1);
3661 string base = Glib::path_get_dirname (oldstr);
3662 string p = Glib::path_get_basename (oldstr);
3664 newstr = Glib::build_filename (base, legal_name);
3666 cerr << "Rename " << oldstr << " => " << newstr << endl;
3668 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3673 (*_session_dir) = newstr;
3678 /* directory below interchange */
3680 v.push_back (newstr);
3681 v.push_back (interchange_dir_name);
3684 oldstr = Glib::build_filename (v);
3687 v.push_back (newstr);
3688 v.push_back (interchange_dir_name);
3689 v.push_back (legal_name);
3691 newstr = Glib::build_filename (v);
3693 cerr << "Rename " << oldstr << " => " << newstr << endl;
3695 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3702 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3703 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3705 cerr << "Rename " << oldstr << " => " << newstr << endl;
3707 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3714 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3716 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3717 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3719 cerr << "Rename " << oldstr << " => " << newstr << endl;
3721 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3726 /* update file source paths */
3728 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3729 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3731 string p = fs->path ();
3732 boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3737 /* remove old name from recent sessions */
3739 remove_recent_sessions (_path);
3742 _current_snapshot_name = new_name;
3747 /* save state again to get everything just right */
3749 save_state (_current_snapshot_name);
3752 /* add to recent sessions */
3754 store_recent_sessions (new_name, _path);
3762 Session::get_session_info_from_path (XMLTree& tree, const string& xmlpath)
3764 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3768 if (!tree.read (xmlpath)) {
3776 Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format)
3779 bool found_sr = false;
3780 bool found_data_format = false;
3782 if (get_session_info_from_path (tree, xmlpath)) {
3788 const XMLProperty* prop;
3789 if ((prop = tree.root()->property (X_("sample-rate"))) != 0) {
3790 sample_rate = atoi (prop->value());
3794 const XMLNodeList& children (tree.root()->children());
3795 for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
3796 const XMLNode* child = *c;
3797 if (child->name() == "Config") {
3798 const XMLNodeList& options (child->children());
3799 for (XMLNodeList::const_iterator oc = options.begin(); oc != options.end(); ++oc) {
3800 const XMLNode* option = *oc;
3801 const XMLProperty* name = option->property("name");
3807 if (name->value() == "native-file-data-format") {
3808 const XMLProperty* value = option->property ("value");
3810 SampleFormat fmt = (SampleFormat) string_2_enum (option->property ("value")->value(), fmt);
3812 found_data_format = true;
3818 if (found_data_format) {
3823 return !(found_sr && found_data_format); // zero if they are both found