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.
20 #define __STDC_FORMAT_MACROS 1
28 #include <sigc++/bind.h>
30 #include <cstdio> /* snprintf(3) ... grrr */
45 #include <sys/param.h>
46 #include <sys/mount.h>
51 #include <midi++/mmc.h>
52 #include <midi++/port.h>
53 #include <pbd/error.h>
55 #include <glibmm/thread.h>
56 #include <pbd/pathscanner.h>
57 #include <pbd/pthread_utils.h>
58 #include <pbd/search_path.h>
59 #include <pbd/stacktrace.h>
61 #include <ardour/audioengine.h>
62 #include <ardour/configuration.h>
63 #include <ardour/session.h>
64 #include <ardour/session_directory.h>
65 #include <ardour/session_utils.h>
66 #include <ardour/session_state_utils.h>
67 #include <ardour/buffer.h>
68 #include <ardour/audio_diskstream.h>
69 #include <ardour/midi_diskstream.h>
70 #include <ardour/utils.h>
71 #include <ardour/audioplaylist.h>
72 #include <ardour/midi_playlist.h>
73 #include <ardour/smf_source.h>
74 #include <ardour/audiofilesource.h>
75 #include <ardour/silentfilesource.h>
76 #include <ardour/sndfilesource.h>
77 #include <ardour/midi_source.h>
78 #include <ardour/sndfile_helpers.h>
79 #include <ardour/auditioner.h>
80 #include <ardour/export.h>
81 #include <ardour/io_processor.h>
82 #include <ardour/send.h>
83 #include <ardour/processor.h>
84 #include <ardour/bundle.h>
85 #include <ardour/slave.h>
86 #include <ardour/tempo.h>
87 #include <ardour/audio_track.h>
88 #include <ardour/midi_track.h>
89 #include <ardour/cycle_timer.h>
90 #include <ardour/utils.h>
91 #include <ardour/named_selection.h>
92 #include <ardour/version.h>
93 #include <ardour/location.h>
94 #include <ardour/audioregion.h>
95 #include <ardour/midi_region.h>
96 #include <ardour/crossfade.h>
97 #include <ardour/control_protocol_manager.h>
98 #include <ardour/region_factory.h>
99 #include <ardour/source_factory.h>
100 #include <ardour/playlist_factory.h>
101 #include <ardour/filename_extensions.h>
102 #include <ardour/directory_names.h>
103 #include <ardour/template_utils.h>
105 #include <control_protocol/control_protocol.h>
111 using namespace ARDOUR;
115 Session::first_stage_init (string fullpath, string snapshot_name)
117 if (fullpath.length() == 0) {
119 throw failed_constructor();
122 char buf[PATH_MAX+1];
123 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
124 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
126 throw failed_constructor();
131 if (_path[_path.length()-1] != '/') {
135 /* these two are just provisional settings. set_state()
136 will likely override them.
139 _name = _current_snapshot_name = snapshot_name;
141 _current_frame_rate = _engine.frame_rate ();
142 _tempo_map = new TempoMap (_current_frame_rate);
143 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
145 g_atomic_int_set (&processing_prohibited, 0);
147 _transport_speed = 0;
148 _last_transport_speed = 0;
149 auto_play_legal = false;
150 transport_sub_state = 0;
151 _transport_frame = 0;
153 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
154 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
155 _end_location_is_free = true;
156 g_atomic_int_set (&_record_status, Disabled);
157 loop_changing = false;
159 _last_roll_location = 0;
160 _last_record_location = 0;
161 pending_locate_frame = 0;
162 pending_locate_roll = false;
163 pending_locate_flush = false;
164 dstream_buffer_size = 0;
166 state_was_pending = false;
168 outbound_mtc_smpte_frame = 0;
169 next_quarter_frame_to_send = -1;
170 current_block_size = 0;
171 solo_update_disabled = false;
172 currently_soloing = false;
173 _have_captured = false;
174 _worst_output_latency = 0;
175 _worst_input_latency = 0;
176 _worst_track_latency = 0;
177 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
179 butler_mixdown_buffer = 0;
180 butler_gain_buffer = 0;
182 session_send_mmc = false;
183 session_send_mtc = false;
184 post_transport_work = PostTransportWork (0);
185 g_atomic_int_set (&butler_should_do_transport_work, 0);
186 g_atomic_int_set (&butler_active, 0);
187 g_atomic_int_set (&_playback_load, 100);
188 g_atomic_int_set (&_capture_load, 100);
189 g_atomic_int_set (&_playback_load_min, 100);
190 g_atomic_int_set (&_capture_load_min, 100);
192 waiting_to_start = false;
194 _gain_automation_buffer = 0;
195 _pan_automation_buffer = 0;
197 pending_abort = false;
198 destructive_index = 0;
200 first_file_data_format_reset = true;
201 first_file_header_format_reset = true;
202 butler_thread = (pthread_t) 0;
203 //midi_thread = (pthread_t) 0;
205 AudioDiskstream::allocate_working_buffers();
207 /* default short fade = 15ms */
209 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
210 SndFileSource::setup_standard_crossfades (frame_rate());
212 last_mmc_step.tv_sec = 0;
213 last_mmc_step.tv_usec = 0;
216 /* click sounds are unset by default, which causes us to internal
217 waveforms for clicks.
221 click_emphasis_data = 0;
223 click_emphasis_length = 0;
226 process_function = &Session::process_with_events;
228 if (Config->get_use_video_sync()) {
229 waiting_for_sync_offset = true;
231 waiting_for_sync_offset = false;
234 _current_frame_rate = 48000;
235 _base_frame_rate = 48000;
239 _smpte_offset_negative = true;
240 last_smpte_valid = false;
244 last_rr_session_dir = session_dirs.begin();
245 refresh_disk_space ();
247 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
251 average_slave_delta = 1800;
252 have_first_delta_accumulator = false;
253 delta_accumulator_cnt = 0;
254 slave_state = Stopped;
256 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
258 /* These are all static "per-class" signals */
260 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
261 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
262 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
263 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
264 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
265 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
267 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
269 IO::MoreChannels.connect (mem_fun (*this, &Session::ensure_buffers));
271 /* stop IO objects from doing stuff until we're ready for them */
273 IO::disable_panners ();
274 IO::disable_ports ();
275 IO::disable_connecting ();
279 Session::second_stage_init (bool new_session)
281 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
284 if (load_state (_current_snapshot_name)) {
287 remove_empty_sounds ();
290 if (start_butler_thread()) {
294 /*if (start_midi_thread ()) {
298 // set_state() will call setup_raid_path(), but if it's a new session we need
299 // to call setup_raid_path() here.
301 if (set_state (*state_tree->root())) {
305 setup_raid_path(_path);
308 /* we can't save till after ::when_engine_running() is called,
309 because otherwise we save state with no connections made.
310 therefore, we reset _state_of_the_state because ::set_state()
311 will have cleared it.
313 we also have to include Loading so that any events that get
314 generated between here and the end of ::when_engine_running()
315 will be processed directly rather than queued.
318 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
320 // set_auto_input (true);
321 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
322 _locations.added.connect (mem_fun (this, &Session::locations_added));
323 setup_click_sounds (0);
324 setup_midi_control ();
326 /* Pay attention ... */
328 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
329 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
332 when_engine_running();
335 /* handle this one in a different way than all others, so that its clear what happened */
337 catch (AudioEngine::PortRegistrationFailure& err) {
338 error << _("Unable to create all required ports")
347 //send_full_time_code ();
348 _engine.transport_locate (0);
349 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
350 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
352 ControlProtocolManager::instance().set_session (*this);
355 _end_location_is_free = true;
357 _end_location_is_free = false;
364 Session::raid_path () const
366 SearchPath raid_search_path;
368 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
369 raid_search_path += sys::path((*i).path);
372 return raid_search_path.to_string ();
376 Session::setup_raid_path (string path)
385 session_dirs.clear ();
387 SearchPath search_path(path);
388 SearchPath sound_search_path;
389 SearchPath midi_search_path;
392 SearchPath::const_iterator i = search_path.begin();
393 i != search_path.end();
397 sp.path = (*i).to_string ();
398 sp.blocks = 0; // not needed
399 session_dirs.push_back (sp);
401 SessionDirectory sdir(sp.path);
403 sound_search_path += sdir.sound_path ();
404 midi_search_path += sdir.midi_path ();
407 // set the AudioFileSource and SMFSource search path
409 AudioFileSource::set_search_path (sound_search_path.to_string ());
410 SMFSource::set_search_path (midi_search_path.to_string ());
412 // reset the round-robin soundfile path thingie
414 last_rr_session_dir = session_dirs.begin();
418 Session::initialize_start_and_end_locations (nframes_t start, nframes_t end)
420 start_location->set_end (start);
421 _locations.add (start_location);
423 end_location->set_end (end);
424 _locations.add (end_location);
428 Session::create_session_file ()
430 _state_of_the_state = Clean;
432 if (save_state (_current_snapshot_name)) {
433 error << "Could not create new session file" << endmsg;
440 Session::create_session_file_from_template (const string& template_path)
442 sys::path session_file_path(_session_dir->root_path());
444 session_file_path /= _name + statefile_suffix;
448 sys::copy_file (template_path, session_file_path);
450 catch(sys::filesystem_error& ex)
452 error << string_compose (_("Could not use session template %1 to create new session (%2)."),
453 template_path, ex.what())
461 Session::load_diskstreams (const XMLNode& node)
464 XMLNodeConstIterator citer;
466 clist = node.children();
468 for (citer = clist.begin(); citer != clist.end(); ++citer) {
471 /* diskstreams added automatically by DiskstreamCreated handler */
472 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
473 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
474 add_diskstream (dstream);
475 } else if ((*citer)->name() == "MidiDiskstream") {
476 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
477 add_diskstream (dstream);
479 error << _("Session: unknown diskstream type in XML") << endmsg;
483 catch (failed_constructor& err) {
484 error << _("Session: could not load diskstream via XML state") << endmsg;
493 Session::maybe_write_autosave()
495 if (dirty() && record_status() != Recording) {
496 save_state("", true);
501 Session::remove_pending_capture_state ()
503 sys::path pending_state_file_path(_session_dir->root_path());
505 pending_state_file_path /= _current_snapshot_name + pending_suffix;
509 sys::remove (pending_state_file_path);
511 catch(sys::filesystem_error& ex)
513 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
514 pending_state_file_path.to_string(), ex.what()) << endmsg;
518 /** Rename a state file.
519 * @param snapshot_name Snapshot name.
522 Session::rename_state (string old_name, string new_name)
524 if (old_name == _current_snapshot_name || old_name == _name) {
525 /* refuse to rename the current snapshot or the "main" one */
529 const string old_xml_path = _path + old_name + statefile_suffix;
530 const string new_xml_path = _path + new_name + statefile_suffix;
532 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
533 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
537 /** Remove a state file.
538 * @param snapshot_name Snapshot name.
541 Session::remove_state (string snapshot_name)
543 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
544 // refuse to remove the current snapshot or the "main" one
548 sys::path xml_path(_session_dir->root_path());
550 xml_path /= snapshot_name + statefile_suffix;
552 if (!create_backup_file (xml_path)) {
553 // don't remove it if a backup can't be made
554 // create_backup_file will log the error.
559 sys::remove (xml_path);
563 Session::save_state (string snapshot_name, bool pending)
566 sys::path xml_path(_session_dir->root_path());
568 if (_state_of_the_state & CannotSave) {
572 if (!_engine.connected ()) {
573 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
578 /* tell sources we're saving first, in case they write out to a new file
579 * which should be saved with the state rather than the old one */
580 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
581 i->second->session_saved();
583 tree.set_root (&get_state());
585 if (snapshot_name.empty()) {
586 snapshot_name = _current_snapshot_name;
591 /* proper save: use statefile_suffix (.ardour in English) */
593 xml_path /= snapshot_name + statefile_suffix;
595 /* make a backup copy of the old file */
597 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
598 // create_backup_file will log the error
604 /* pending save: use pending_suffix (.pending in English) */
605 xml_path /= snapshot_name + pending_suffix;
608 sys::path tmp_path(_session_dir->root_path());
610 tmp_path /= snapshot_name + temp_suffix;
612 // cerr << "actually writing state to " << xml_path.to_string() << endl;
614 if (!tree.write (tmp_path.to_string())) {
615 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
616 sys::remove (tmp_path);
621 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
622 error << string_compose (_("could not rename temporary session file %1 to %2"),
623 tmp_path.to_string(), xml_path.to_string()) << endmsg;
624 sys::remove (tmp_path);
631 save_history (snapshot_name);
633 bool was_dirty = dirty();
635 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
638 DirtyChanged (); /* EMIT SIGNAL */
641 StateSaved (snapshot_name); /* EMIT SIGNAL */
648 Session::restore_state (string snapshot_name)
650 if (load_state (snapshot_name) == 0) {
651 set_state (*state_tree->root());
658 Session::load_state (string snapshot_name)
665 state_was_pending = false;
667 /* check for leftover pending state from a crashed capture attempt */
669 sys::path xmlpath(_session_dir->root_path());
670 xmlpath /= snapshot_name + pending_suffix;
672 if (sys::exists (xmlpath)) {
674 /* there is pending state from a crashed capture attempt */
676 if (AskAboutPendingState()) {
677 state_was_pending = true;
681 if (!state_was_pending) {
682 xmlpath = _session_dir->root_path();
683 xmlpath /= snapshot_name + statefile_suffix;
686 if (!sys::exists (xmlpath)) {
687 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
691 state_tree = new XMLTree;
695 if (!state_tree->read (xmlpath.to_string())) {
696 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
702 XMLNode& root (*state_tree->root());
704 if (root.name() != X_("Session")) {
705 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
711 const XMLProperty* prop;
714 if ((prop = root.property ("version")) == 0) {
715 /* no version implies very old version of Ardour */
719 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
720 if (major_version < 2) {
727 sys::path backup_path(_session_dir->root_path());
729 backup_path /= snapshot_name + "-1" + statefile_suffix;
731 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
732 xmlpath.to_string(), backup_path.to_string())
737 sys::copy_file (xmlpath, backup_path);
739 catch(sys::filesystem_error& ex)
741 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
742 xmlpath.to_string(), ex.what())
752 Session::load_options (const XMLNode& node)
756 LocaleGuard lg (X_("POSIX"));
758 Config->set_variables (node, ConfigVariableBase::Session);
760 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
761 if ((prop = child->property ("val")) != 0) {
762 _end_location_is_free = (prop->value() == "yes");
770 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
772 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
773 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
775 return owner & modified_by_session_or_user;
779 Session::get_options () const
782 LocaleGuard lg (X_("POSIX"));
784 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
786 child = option_root.add_child ("end-marker-is-free");
787 child->add_property ("val", _end_location_is_free ? "yes" : "no");
799 Session::get_template()
801 /* if we don't disable rec-enable, diskstreams
802 will believe they need to store their capture
803 sources in their state node.
806 disable_record (false);
812 Session::state(bool full_state)
814 XMLNode* node = new XMLNode("Session");
817 // store libardour version, just in case
819 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
820 libardour_major_version, libardour_minor_version, libardour_micro_version);
821 node->add_property("version", string(buf));
823 /* store configuration settings */
828 node->add_property ("name", _name);
830 if (session_dirs.size() > 1) {
834 vector<space_and_path>::iterator i = session_dirs.begin();
835 vector<space_and_path>::iterator next;
837 ++i; /* skip the first one */
841 while (i != session_dirs.end()) {
845 if (next != session_dirs.end()) {
855 child = node->add_child ("Path");
856 child->add_content (p);
860 /* save the ID counter */
862 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
863 node->add_property ("id-counter", buf);
865 /* various options */
867 node->add_child_nocopy (get_options());
869 child = node->add_child ("Sources");
872 Glib::Mutex::Lock sl (source_lock);
874 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
876 /* Don't save information about AudioFileSources that are empty */
878 boost::shared_ptr<AudioFileSource> fs;
880 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
882 /* Don't save sources that are empty, unless they're destructive (which are OK
883 if they are empty, because we will re-use them every time.)
886 if (!fs->destructive()) {
887 if (fs->length() == 0) {
893 child->add_child_nocopy (siter->second->get_state());
897 child = node->add_child ("Regions");
900 Glib::Mutex::Lock rl (region_lock);
902 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
904 /* only store regions not attached to playlists */
906 if (i->second->playlist() == 0) {
907 child->add_child_nocopy (i->second->state (true));
912 child = node->add_child ("DiskStreams");
915 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
916 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
917 if (!(*i)->hidden()) {
918 child->add_child_nocopy ((*i)->get_state());
924 node->add_child_nocopy (_locations.get_state());
926 // for a template, just create a new Locations, populate it
927 // with the default start and end, and get the state for that.
929 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
930 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
933 end->set_end(compute_initial_length());
935 node->add_child_nocopy (loc.get_state());
938 child = node->add_child ("Connections");
940 Glib::Mutex::Lock lm (bundle_lock);
941 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
942 if (!(*i)->dynamic()) {
943 child->add_child_nocopy ((*i)->get_state());
948 child = node->add_child ("Routes");
950 boost::shared_ptr<RouteList> r = routes.reader ();
952 RoutePublicOrderSorter cmp;
953 RouteList public_order (*r);
954 public_order.sort (cmp);
956 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
957 if (!(*i)->is_hidden()) {
959 child->add_child_nocopy ((*i)->get_state());
961 child->add_child_nocopy ((*i)->get_template());
968 child = node->add_child ("EditGroups");
969 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
970 child->add_child_nocopy ((*i)->get_state());
973 child = node->add_child ("MixGroups");
974 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
975 child->add_child_nocopy ((*i)->get_state());
978 child = node->add_child ("Playlists");
979 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
980 if (!(*i)->hidden()) {
981 if (!(*i)->empty()) {
983 child->add_child_nocopy ((*i)->get_state());
985 child->add_child_nocopy ((*i)->get_template());
991 child = node->add_child ("UnusedPlaylists");
992 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
993 if (!(*i)->hidden()) {
994 if (!(*i)->empty()) {
996 child->add_child_nocopy ((*i)->get_state());
998 child->add_child_nocopy ((*i)->get_template());
1006 child = node->add_child ("Click");
1007 child->add_child_nocopy (_click_io->state (full_state));
1011 child = node->add_child ("NamedSelections");
1012 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1014 child->add_child_nocopy ((*i)->get_state());
1019 node->add_child_nocopy (_tempo_map->get_state());
1021 node->add_child_nocopy (get_control_protocol_state());
1024 node->add_child_copy (*_extra_xml);
1031 Session::get_control_protocol_state ()
1033 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1034 return cpm.get_state();
1038 Session::set_state (const XMLNode& node)
1042 const XMLProperty* prop;
1045 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1047 if (node.name() != X_("Session")){
1048 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1052 if ((prop = node.property ("name")) != 0) {
1053 _name = prop->value ();
1056 setup_raid_path(_path);
1058 if ((prop = node.property (X_("id-counter"))) != 0) {
1060 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1061 ID::init_counter (x);
1063 /* old sessions used a timebased counter, so fake
1064 the startup ID counter based on a standard
1069 ID::init_counter (now);
1073 IO::disable_ports ();
1074 IO::disable_connecting ();
1076 /* Object loading order:
1094 if (use_config_midi_ports ()) {
1097 if ((child = find_named_node (node, "extra")) != 0) {
1098 _extra_xml = new XMLNode (*child);
1101 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1102 load_options (*child);
1103 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1104 load_options (*child);
1106 error << _("Session: XML state has no options section") << endmsg;
1109 if ((child = find_named_node (node, "Locations")) == 0) {
1110 error << _("Session: XML state has no locations section") << endmsg;
1112 } else if (_locations.set_state (*child)) {
1118 if ((location = _locations.auto_loop_location()) != 0) {
1119 set_auto_loop_location (location);
1122 if ((location = _locations.auto_punch_location()) != 0) {
1123 set_auto_punch_location (location);
1126 if ((location = _locations.end_location()) == 0) {
1127 _locations.add (end_location);
1129 delete end_location;
1130 end_location = location;
1133 if ((location = _locations.start_location()) == 0) {
1134 _locations.add (start_location);
1136 delete start_location;
1137 start_location = location;
1140 AudioFileSource::set_header_position_offset (start_location->start());
1142 if ((child = find_named_node (node, "Sources")) == 0) {
1143 error << _("Session: XML state has no sources section") << endmsg;
1145 } else if (load_sources (*child)) {
1149 if ((child = find_named_node (node, "Regions")) == 0) {
1150 error << _("Session: XML state has no Regions section") << endmsg;
1152 } else if (load_regions (*child)) {
1156 if ((child = find_named_node (node, "Playlists")) == 0) {
1157 error << _("Session: XML state has no playlists section") << endmsg;
1159 } else if (load_playlists (*child)) {
1163 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1165 } else if (load_unused_playlists (*child)) {
1169 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1170 if (load_named_selections (*child)) {
1175 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1176 error << _("Session: XML state has no diskstreams section") << endmsg;
1178 } else if (load_diskstreams (*child)) {
1182 if ((child = find_named_node (node, "Connections")) == 0) {
1183 error << _("Session: XML state has no connections section") << endmsg;
1185 } else if (load_bundles (*child)) {
1189 if ((child = find_named_node (node, "EditGroups")) == 0) {
1190 error << _("Session: XML state has no edit groups section") << endmsg;
1192 } else if (load_edit_groups (*child)) {
1196 if ((child = find_named_node (node, "MixGroups")) == 0) {
1197 error << _("Session: XML state has no mix groups section") << endmsg;
1199 } else if (load_mix_groups (*child)) {
1203 if ((child = find_named_node (node, "TempoMap")) == 0) {
1204 error << _("Session: XML state has no Tempo Map section") << endmsg;
1206 } else if (_tempo_map->set_state (*child)) {
1210 if ((child = find_named_node (node, "Routes")) == 0) {
1211 error << _("Session: XML state has no routes section") << endmsg;
1213 } else if (load_routes (*child)) {
1217 if ((child = find_named_node (node, "Click")) == 0) {
1218 warning << _("Session: XML state has no click section") << endmsg;
1219 } else if (_click_io) {
1220 _click_io->set_state (*child);
1223 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1224 ControlProtocolManager::instance().set_protocol_states (*child);
1227 /* here beginneth the second phase ... */
1229 StateReady (); /* EMIT SIGNAL */
1231 _state_of_the_state = Clean;
1233 if (state_was_pending) {
1234 save_state (_current_snapshot_name);
1235 remove_pending_capture_state ();
1236 state_was_pending = false;
1246 Session::load_routes (const XMLNode& node)
1249 XMLNodeConstIterator niter;
1250 RouteList new_routes;
1252 nlist = node.children();
1256 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1258 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1261 error << _("Session: cannot create Route from XML description.") << endmsg;
1265 new_routes.push_back (route);
1268 add_routes (new_routes);
1273 boost::shared_ptr<Route>
1274 Session::XMLRouteFactory (const XMLNode& node)
1276 if (node.name() != "Route") {
1277 return boost::shared_ptr<Route> ((Route*) 0);
1280 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1282 DataType type = DataType::AUDIO;
1283 const XMLProperty* prop = node.property("default-type");
1285 type = DataType(prop->value());
1287 assert(type != DataType::NIL);
1289 if (has_diskstream) {
1290 if (type == DataType::AUDIO) {
1291 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1294 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1298 boost::shared_ptr<Route> ret (new Route (*this, node));
1304 Session::load_regions (const XMLNode& node)
1307 XMLNodeConstIterator niter;
1308 boost::shared_ptr<Region> region;
1310 nlist = node.children();
1314 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1315 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1316 error << _("Session: cannot create Region from XML description.") << endmsg;
1323 boost::shared_ptr<Region>
1324 Session::XMLRegionFactory (const XMLNode& node, bool full)
1326 const XMLProperty* type = node.property("type");
1330 if ( !type || type->value() == "audio" ) {
1332 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1334 } else if (type->value() == "midi") {
1336 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1340 } catch (failed_constructor& err) {
1341 return boost::shared_ptr<Region> ();
1344 return boost::shared_ptr<Region> ();
1347 boost::shared_ptr<AudioRegion>
1348 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1350 const XMLProperty* prop;
1351 boost::shared_ptr<Source> source;
1352 boost::shared_ptr<AudioSource> as;
1354 uint32_t nchans = 1;
1357 if (node.name() != X_("Region")) {
1358 return boost::shared_ptr<AudioRegion>();
1361 if ((prop = node.property (X_("channels"))) != 0) {
1362 nchans = atoi (prop->value().c_str());
1365 if ((prop = node.property ("name")) == 0) {
1366 cerr << "no name for this region\n";
1370 if ((prop = node.property (X_("source-0"))) == 0) {
1371 if ((prop = node.property ("source")) == 0) {
1372 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1373 return boost::shared_ptr<AudioRegion>();
1377 PBD::ID s_id (prop->value());
1379 if ((source = source_by_id (s_id)) == 0) {
1380 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1381 return boost::shared_ptr<AudioRegion>();
1384 as = boost::dynamic_pointer_cast<AudioSource>(source);
1386 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1387 return boost::shared_ptr<AudioRegion>();
1390 sources.push_back (as);
1392 /* pickup other channels */
1394 for (uint32_t n=1; n < nchans; ++n) {
1395 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1396 if ((prop = node.property (buf)) != 0) {
1398 PBD::ID id2 (prop->value());
1400 if ((source = source_by_id (id2)) == 0) {
1401 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1402 return boost::shared_ptr<AudioRegion>();
1405 as = boost::dynamic_pointer_cast<AudioSource>(source);
1407 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1408 return boost::shared_ptr<AudioRegion>();
1410 sources.push_back (as);
1415 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1417 /* a final detail: this is the one and only place that we know how long missing files are */
1419 if (region->whole_file()) {
1420 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1421 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1423 sfp->set_length (region->length());
1432 catch (failed_constructor& err) {
1433 return boost::shared_ptr<AudioRegion>();
1437 boost::shared_ptr<MidiRegion>
1438 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1440 const XMLProperty* prop;
1441 boost::shared_ptr<Source> source;
1442 boost::shared_ptr<MidiSource> ms;
1444 uint32_t nchans = 1;
1446 if (node.name() != X_("Region")) {
1447 return boost::shared_ptr<MidiRegion>();
1450 if ((prop = node.property (X_("channels"))) != 0) {
1451 nchans = atoi (prop->value().c_str());
1454 if ((prop = node.property ("name")) == 0) {
1455 cerr << "no name for this region\n";
1459 // Multiple midi channels? that's just crazy talk
1460 assert(nchans == 1);
1462 if ((prop = node.property (X_("source-0"))) == 0) {
1463 if ((prop = node.property ("source")) == 0) {
1464 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1465 return boost::shared_ptr<MidiRegion>();
1469 PBD::ID s_id (prop->value());
1471 if ((source = source_by_id (s_id)) == 0) {
1472 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1473 return boost::shared_ptr<MidiRegion>();
1476 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1478 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1479 return boost::shared_ptr<MidiRegion>();
1482 sources.push_back (ms);
1485 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1486 /* a final detail: this is the one and only place that we know how long missing files are */
1488 if (region->whole_file()) {
1489 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1490 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1492 sfp->set_length (region->length());
1500 catch (failed_constructor& err) {
1501 return boost::shared_ptr<MidiRegion>();
1506 Session::get_sources_as_xml ()
1509 XMLNode* node = new XMLNode (X_("Sources"));
1510 Glib::Mutex::Lock lm (source_lock);
1512 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1513 node->add_child_nocopy (i->second->get_state());
1520 Session::path_from_region_name (DataType type, string name, string identifier)
1522 char buf[PATH_MAX+1];
1524 SessionDirectory sdir(get_best_session_directory_for_new_source());
1525 string sound_dir = ((type == DataType::AUDIO)
1526 ? sdir.sound_path().to_string()
1527 : sdir.midi_path().to_string());
1529 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1531 for (n = 0; n < 999999; ++n) {
1532 if (identifier.length()) {
1533 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1534 identifier.c_str(), n, ext.c_str());
1536 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1540 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1545 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1554 Session::load_sources (const XMLNode& node)
1557 XMLNodeConstIterator niter;
1558 boost::shared_ptr<Source> source;
1560 nlist = node.children();
1564 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1567 if ((source = XMLSourceFactory (**niter)) == 0) {
1568 error << _("Session: cannot create Source from XML description.") << endmsg;
1572 catch (non_existent_source& err) {
1573 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1574 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1581 boost::shared_ptr<Source>
1582 Session::XMLSourceFactory (const XMLNode& node)
1584 if (node.name() != "Source") {
1585 return boost::shared_ptr<Source>();
1589 return SourceFactory::create (*this, node);
1592 catch (failed_constructor& err) {
1593 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1594 return boost::shared_ptr<Source>();
1599 Session::save_template (string template_name)
1603 if (_state_of_the_state & CannotSave) {
1607 sys::path user_template_dir(user_template_directory());
1611 sys::create_directories (user_template_dir);
1613 catch(sys::filesystem_error& ex)
1615 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1616 user_template_dir.to_string(), ex.what()) << endmsg;
1620 tree.set_root (&get_template());
1622 sys::path template_file_path(user_template_dir);
1623 template_file_path /= template_name + template_suffix;
1625 if (sys::exists (template_file_path))
1627 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1628 template_file_path.to_string()) << endmsg;
1632 if (!tree.write (template_file_path.to_string())) {
1633 error << _("mix template not saved") << endmsg;
1641 Session::refresh_disk_space ()
1644 struct statfs statfsbuf;
1645 vector<space_and_path>::iterator i;
1646 Glib::Mutex::Lock lm (space_lock);
1649 /* get freespace on every FS that is part of the session path */
1651 _total_free_4k_blocks = 0;
1653 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1654 statfs ((*i).path.c_str(), &statfsbuf);
1656 scale = statfsbuf.f_bsize/4096.0;
1658 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1659 _total_free_4k_blocks += (*i).blocks;
1665 Session::get_best_session_directory_for_new_source ()
1667 vector<space_and_path>::iterator i;
1668 string result = _session_dir->root_path().to_string();
1670 /* handle common case without system calls */
1672 if (session_dirs.size() == 1) {
1676 /* OK, here's the algorithm we're following here:
1678 We want to select which directory to use for
1679 the next file source to be created. Ideally,
1680 we'd like to use a round-robin process so as to
1681 get maximum performance benefits from splitting
1682 the files across multiple disks.
1684 However, in situations without much diskspace, an
1685 RR approach may end up filling up a filesystem
1686 with new files while others still have space.
1687 Its therefore important to pay some attention to
1688 the freespace in the filesystem holding each
1689 directory as well. However, if we did that by
1690 itself, we'd keep creating new files in the file
1691 system with the most space until it was as full
1692 as all others, thus negating any performance
1693 benefits of this RAID-1 like approach.
1695 So, we use a user-configurable space threshold. If
1696 there are at least 2 filesystems with more than this
1697 much space available, we use RR selection between them.
1698 If not, then we pick the filesystem with the most space.
1700 This gets a good balance between the two
1704 refresh_disk_space ();
1706 int free_enough = 0;
1708 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1709 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1714 if (free_enough >= 2) {
1715 /* use RR selection process, ensuring that the one
1719 i = last_rr_session_dir;
1722 if (++i == session_dirs.end()) {
1723 i = session_dirs.begin();
1726 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1727 if (create_session_directory ((*i).path)) {
1729 last_rr_session_dir = i;
1734 } while (i != last_rr_session_dir);
1738 /* pick FS with the most freespace (and that
1739 seems to actually work ...)
1742 vector<space_and_path> sorted;
1743 space_and_path_ascending_cmp cmp;
1745 sorted = session_dirs;
1746 sort (sorted.begin(), sorted.end(), cmp);
1748 for (i = sorted.begin(); i != sorted.end(); ++i) {
1749 if (create_session_directory ((*i).path)) {
1751 last_rr_session_dir = i;
1761 Session::load_playlists (const XMLNode& node)
1764 XMLNodeConstIterator niter;
1765 boost::shared_ptr<Playlist> playlist;
1767 nlist = node.children();
1771 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1773 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1774 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1782 Session::load_unused_playlists (const XMLNode& node)
1785 XMLNodeConstIterator niter;
1786 boost::shared_ptr<Playlist> playlist;
1788 nlist = node.children();
1792 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1794 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1795 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1799 // now manually untrack it
1801 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1807 boost::shared_ptr<Playlist>
1808 Session::XMLPlaylistFactory (const XMLNode& node)
1811 return PlaylistFactory::create (*this, node);
1814 catch (failed_constructor& err) {
1815 return boost::shared_ptr<Playlist>();
1820 Session::load_named_selections (const XMLNode& node)
1823 XMLNodeConstIterator niter;
1826 nlist = node.children();
1830 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1832 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1833 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1841 Session::XMLNamedSelectionFactory (const XMLNode& node)
1844 return new NamedSelection (*this, node);
1847 catch (failed_constructor& err) {
1853 Session::automation_dir () const
1856 res += "automation/";
1861 Session::load_bundles (const XMLNode& node)
1863 XMLNodeList nlist = node.children();
1864 XMLNodeConstIterator niter;
1868 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1869 if ((*niter)->name() == "InputConnection") {
1870 add_bundle (new ARDOUR::InputBundle (**niter));
1871 } else if ((*niter)->name() == "OutputConnection") {
1872 add_bundle (new ARDOUR::OutputBundle (**niter));
1874 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1883 Session::load_edit_groups (const XMLNode& node)
1885 return load_route_groups (node, true);
1889 Session::load_mix_groups (const XMLNode& node)
1891 return load_route_groups (node, false);
1895 Session::load_route_groups (const XMLNode& node, bool edit)
1897 XMLNodeList nlist = node.children();
1898 XMLNodeConstIterator niter;
1903 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1904 if ((*niter)->name() == "RouteGroup") {
1906 rg = add_edit_group ("");
1907 rg->set_state (**niter);
1909 rg = add_mix_group ("");
1910 rg->set_state (**niter);
1919 Session::auto_save()
1921 save_state (_current_snapshot_name);
1925 Session::add_edit_group (string name)
1927 RouteGroup* rg = new RouteGroup (*this, name);
1928 edit_groups.push_back (rg);
1929 edit_group_added (rg); /* EMIT SIGNAL */
1935 Session::add_mix_group (string name)
1937 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
1938 mix_groups.push_back (rg);
1939 mix_group_added (rg); /* EMIT SIGNAL */
1945 Session::remove_edit_group (RouteGroup& rg)
1947 list<RouteGroup*>::iterator i;
1949 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
1950 (*i)->apply (&Route::drop_edit_group, this);
1951 edit_groups.erase (i);
1952 edit_group_removed (); /* EMIT SIGNAL */
1959 Session::remove_mix_group (RouteGroup& rg)
1961 list<RouteGroup*>::iterator i;
1963 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
1964 (*i)->apply (&Route::drop_mix_group, this);
1965 mix_groups.erase (i);
1966 mix_group_removed (); /* EMIT SIGNAL */
1973 Session::mix_group_by_name (string name)
1975 list<RouteGroup *>::iterator i;
1977 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1978 if ((*i)->name() == name) {
1986 Session::edit_group_by_name (string name)
1988 list<RouteGroup *>::iterator i;
1990 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1991 if ((*i)->name() == name) {
1999 Session::begin_reversible_command (const string& name)
2001 current_trans = new UndoTransaction;
2002 current_trans->set_name (name);
2006 Session::commit_reversible_command (Command *cmd)
2011 current_trans->add_command (cmd);
2014 gettimeofday (&now, 0);
2015 current_trans->set_timestamp (now);
2017 _history.add (current_trans);
2020 Session::GlobalRouteBooleanState
2021 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2023 GlobalRouteBooleanState s;
2024 boost::shared_ptr<RouteList> r = routes.reader ();
2026 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2027 if (!(*i)->is_hidden()) {
2028 RouteBooleanState v;
2031 Route* r = (*i).get();
2032 v.second = (r->*method)();
2041 Session::GlobalRouteMeterState
2042 Session::get_global_route_metering ()
2044 GlobalRouteMeterState s;
2045 boost::shared_ptr<RouteList> r = routes.reader ();
2047 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2048 if (!(*i)->is_hidden()) {
2052 v.second = (*i)->meter_point();
2062 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2064 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2066 boost::shared_ptr<Route> r = (i->first.lock());
2069 r->set_meter_point (i->second, arg);
2075 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2077 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2079 boost::shared_ptr<Route> r = (i->first.lock());
2082 Route* rp = r.get();
2083 (rp->*method) (i->second, arg);
2089 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2091 set_global_route_boolean (s, &Route::set_mute, src);
2095 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2097 set_global_route_boolean (s, &Route::set_solo, src);
2101 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2103 set_global_route_boolean (s, &Route::set_record_enable, src);
2108 Session::global_mute_memento (void* src)
2110 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2114 Session::global_metering_memento (void* src)
2116 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2120 Session::global_solo_memento (void* src)
2122 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2126 Session::global_record_enable_memento (void* src)
2128 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2133 accept_all_non_peak_files (const string& path, void *arg)
2135 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2139 accept_all_state_files (const string& path, void *arg)
2141 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2145 Session::find_all_sources (string path, set<string>& result)
2150 if (!tree.read (path)) {
2154 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2159 XMLNodeConstIterator niter;
2161 nlist = node->children();
2165 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2169 if ((prop = (*niter)->property (X_("name"))) == 0) {
2173 if (prop->value()[0] == '/') {
2174 /* external file, ignore */
2178 sys::path source_path = _session_dir->sound_path ();
2180 source_path /= prop->value ();
2182 result.insert (source_path.to_string ());
2189 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2191 PathScanner scanner;
2192 vector<string*>* state_files;
2194 string this_snapshot_path;
2200 if (ripped[ripped.length()-1] == '/') {
2201 ripped = ripped.substr (0, ripped.length() - 1);
2204 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2206 if (state_files == 0) {
2211 this_snapshot_path = _path;
2212 this_snapshot_path += _current_snapshot_name;
2213 this_snapshot_path += statefile_suffix;
2215 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2217 if (exclude_this_snapshot && **i == this_snapshot_path) {
2221 if (find_all_sources (**i, result) < 0) {
2229 struct RegionCounter {
2230 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2231 AudioSourceList::iterator iter;
2232 boost::shared_ptr<Region> region;
2235 RegionCounter() : count (0) {}
2239 Session::cleanup_sources (Session::cleanup_report& rep)
2241 // FIXME: needs adaptation to midi
2243 vector<boost::shared_ptr<Source> > dead_sources;
2244 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2245 PathScanner scanner;
2247 vector<space_and_path>::iterator i;
2248 vector<space_and_path>::iterator nexti;
2249 vector<string*>* soundfiles;
2250 vector<string> unused;
2251 set<string> all_sources;
2256 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2258 /* step 1: consider deleting all unused playlists */
2260 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2263 status = AskAboutPlaylistDeletion (*x);
2272 playlists_tbd.push_back (*x);
2276 /* leave it alone */
2281 /* now delete any that were marked for deletion */
2283 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2284 (*x)->drop_references ();
2287 playlists_tbd.clear ();
2289 /* step 2: find all un-used sources */
2294 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2296 SourceMap::iterator tmp;
2301 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2305 if (!i->second->used() && i->second->length() > 0) {
2306 dead_sources.push_back (i->second);
2307 i->second->GoingAway();
2313 /* build a list of all the possible sound directories for the session */
2315 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2320 SessionDirectory sdir ((*i).path);
2321 sound_path += sdir.sound_path().to_string();
2323 if (nexti != session_dirs.end()) {
2330 /* now do the same thing for the files that ended up in the sounds dir(s)
2331 but are not referenced as sources in any snapshot.
2334 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2336 if (soundfiles == 0) {
2340 /* find all sources, but don't use this snapshot because the
2341 state file on disk still references sources we may have already
2345 find_all_sources_across_snapshots (all_sources, true);
2347 /* add our current source list
2350 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2351 boost::shared_ptr<AudioFileSource> fs;
2353 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2354 all_sources.insert (fs->path());
2358 char tmppath1[PATH_MAX+1];
2359 char tmppath2[PATH_MAX+1];
2361 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2366 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2368 realpath(spath.c_str(), tmppath1);
2369 realpath((*i).c_str(), tmppath2);
2371 if (strcmp(tmppath1, tmppath2) == 0) {
2378 unused.push_back (spath);
2382 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2384 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2385 struct stat statbuf;
2387 rep.paths.push_back (*x);
2388 if (stat ((*x).c_str(), &statbuf) == 0) {
2389 rep.space += statbuf.st_size;
2394 /* don't move the file across filesystems, just
2395 stick it in the `dead_sound_dir_name' directory
2396 on whichever filesystem it was already on.
2399 if ((*x).find ("/sounds/") != string::npos) {
2401 /* old school, go up 1 level */
2403 newpath = Glib::path_get_dirname (*x); // "sounds"
2404 newpath = Glib::path_get_dirname (newpath); // "session-name"
2408 /* new school, go up 4 levels */
2410 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2411 newpath = Glib::path_get_dirname (newpath); // "session-name"
2412 newpath = Glib::path_get_dirname (newpath); // "interchange"
2413 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2417 newpath += dead_sound_dir_name;
2419 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2420 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2425 newpath += Glib::path_get_basename ((*x));
2427 if (access (newpath.c_str(), F_OK) == 0) {
2429 /* the new path already exists, try versioning */
2431 char buf[PATH_MAX+1];
2435 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2438 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2439 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2443 if (version == 999) {
2444 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2448 newpath = newpath_v;
2453 /* it doesn't exist, or we can't read it or something */
2457 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2458 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2459 (*x), newpath, strerror (errno))
2464 /* see if there an easy to find peakfile for this file, and remove it.
2467 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2468 peakpath += peakfile_suffix;
2470 if (access (peakpath.c_str(), W_OK) == 0) {
2471 if (::unlink (peakpath.c_str()) != 0) {
2472 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2473 peakpath, _path, strerror (errno))
2475 /* try to back out */
2476 rename (newpath.c_str(), _path.c_str());
2484 /* dump the history list */
2488 /* save state so we don't end up a session file
2489 referring to non-existent sources.
2495 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2500 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2502 // FIXME: needs adaptation for MIDI
2504 vector<space_and_path>::iterator i;
2505 string dead_sound_dir;
2506 struct dirent* dentry;
2507 struct stat statbuf;
2513 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2515 dead_sound_dir = (*i).path;
2516 dead_sound_dir += dead_sound_dir_name;
2518 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2522 while ((dentry = readdir (dead)) != 0) {
2524 /* avoid '.' and '..' */
2526 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2527 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2533 fullpath = dead_sound_dir;
2535 fullpath += dentry->d_name;
2537 if (stat (fullpath.c_str(), &statbuf)) {
2541 if (!S_ISREG (statbuf.st_mode)) {
2545 if (unlink (fullpath.c_str())) {
2546 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2547 fullpath, strerror (errno))
2551 rep.paths.push_back (dentry->d_name);
2552 rep.space += statbuf.st_size;
2563 Session::set_dirty ()
2565 bool was_dirty = dirty();
2567 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2570 DirtyChanged(); /* EMIT SIGNAL */
2576 Session::set_clean ()
2578 bool was_dirty = dirty();
2580 _state_of_the_state = Clean;
2583 DirtyChanged(); /* EMIT SIGNAL */
2588 Session::set_deletion_in_progress ()
2590 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2594 Session::add_controllable (boost::shared_ptr<Controllable> c)
2596 /* this adds a controllable to the list managed by the Session.
2597 this is a subset of those managed by the Controllable class
2598 itself, and represents the only ones whose state will be saved
2599 as part of the session.
2602 Glib::Mutex::Lock lm (controllables_lock);
2603 controllables.insert (c);
2606 struct null_deleter { void operator()(void const *) const {} };
2609 Session::remove_controllable (Controllable* c)
2611 if (_state_of_the_state | Deletion) {
2615 Glib::Mutex::Lock lm (controllables_lock);
2617 Controllables::iterator x = controllables.find(
2618 boost::shared_ptr<Controllable>(c, null_deleter()));
2620 if (x != controllables.end()) {
2621 controllables.erase (x);
2625 boost::shared_ptr<Controllable>
2626 Session::controllable_by_id (const PBD::ID& id)
2628 Glib::Mutex::Lock lm (controllables_lock);
2630 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2631 if ((*i)->id() == id) {
2636 return boost::shared_ptr<Controllable>();
2640 Session::add_instant_xml (XMLNode& node)
2642 Stateful::add_instant_xml (node, _path);
2643 Config->add_instant_xml (node);
2647 Session::instant_xml (const string& node_name)
2649 return Stateful::instant_xml (node_name, _path);
2653 Session::save_history (string snapshot_name)
2659 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2661 if (snapshot_name.empty()) {
2662 snapshot_name = _current_snapshot_name;
2665 xml_path = _path + snapshot_name + ".history";
2667 bak_path = xml_path + ".bak";
2669 if ((access (xml_path.c_str(), F_OK) == 0) &&
2670 (rename (xml_path.c_str(), bak_path.c_str())))
2672 error << _("could not backup old history file, current history not saved.") << endmsg;
2676 if (!tree.write (xml_path))
2678 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2680 /* don't leave a corrupt file lying around if it is
2684 if (unlink (xml_path.c_str())) {
2685 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2687 if (rename (bak_path.c_str(), xml_path.c_str()))
2689 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2700 Session::restore_history (string snapshot_name)
2705 if (snapshot_name.empty()) {
2706 snapshot_name = _current_snapshot_name;
2710 xmlpath = _path + snapshot_name + ".history";
2711 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2713 if (access (xmlpath.c_str(), F_OK)) {
2714 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2718 if (!tree.read (xmlpath)) {
2719 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2723 /* replace history */
2726 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2729 UndoTransaction* ut = new UndoTransaction ();
2732 ut->set_name(t->property("name")->value());
2733 stringstream ss(t->property("tv_sec")->value());
2735 ss.str(t->property("tv_usec")->value());
2737 ut->set_timestamp(tv);
2739 for (XMLNodeConstIterator child_it = t->children().begin();
2740 child_it != t->children().end();
2743 XMLNode *n = *child_it;
2746 if (n->name() == "MementoCommand" ||
2747 n->name() == "MementoUndoCommand" ||
2748 n->name() == "MementoRedoCommand") {
2750 if ((c = memento_command_factory(n))) {
2754 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2756 if ((c = global_state_command_factory (*n))) {
2757 ut->add_command (c);
2762 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2773 Session::config_changed (const char* parameter_name)
2775 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2777 if (PARAM_IS ("seamless-loop")) {
2779 } else if (PARAM_IS ("rf-speed")) {
2781 } else if (PARAM_IS ("auto-loop")) {
2783 } else if (PARAM_IS ("auto-input")) {
2785 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2786 /* auto-input only makes a difference if we're rolling */
2788 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2790 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2791 if ((*i)->record_enabled ()) {
2792 (*i)->monitor_input (!Config->get_auto_input());
2797 } else if (PARAM_IS ("punch-in")) {
2801 if ((location = _locations.auto_punch_location()) != 0) {
2803 if (Config->get_punch_in ()) {
2804 replace_event (Event::PunchIn, location->start());
2806 remove_event (location->start(), Event::PunchIn);
2810 } else if (PARAM_IS ("punch-out")) {
2814 if ((location = _locations.auto_punch_location()) != 0) {
2816 if (Config->get_punch_out()) {
2817 replace_event (Event::PunchOut, location->end());
2819 clear_events (Event::PunchOut);
2823 } else if (PARAM_IS ("edit-mode")) {
2825 Glib::Mutex::Lock lm (playlist_lock);
2827 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2828 (*i)->set_edit_mode (Config->get_edit_mode ());
2831 } else if (PARAM_IS ("use-video-sync")) {
2833 waiting_for_sync_offset = Config->get_use_video_sync();
2835 } else if (PARAM_IS ("mmc-control")) {
2837 //poke_midi_thread ();
2839 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
2842 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
2845 } else if (PARAM_IS ("mmc-send-id")) {
2848 mmc->set_send_device_id (Config->get_mmc_send_device_id());
2851 } else if (PARAM_IS ("midi-control")) {
2853 //poke_midi_thread ();
2855 } else if (PARAM_IS ("raid-path")) {
2857 setup_raid_path (Config->get_raid_path());
2859 } else if (PARAM_IS ("smpte-format")) {
2863 } else if (PARAM_IS ("video-pullup")) {
2867 } else if (PARAM_IS ("seamless-loop")) {
2869 if (play_loop && transport_rolling()) {
2870 // to reset diskstreams etc
2871 request_play_loop (true);
2874 } else if (PARAM_IS ("rf-speed")) {
2876 cumulative_rf_motion = 0;
2879 } else if (PARAM_IS ("click-sound")) {
2881 setup_click_sounds (1);
2883 } else if (PARAM_IS ("click-emphasis-sound")) {
2885 setup_click_sounds (-1);
2887 } else if (PARAM_IS ("clicking")) {
2889 if (Config->get_clicking()) {
2890 if (_click_io && click_data) { // don't require emphasis data
2897 } else if (PARAM_IS ("send-mtc")) {
2899 /* only set the internal flag if we have
2903 if (_mtc_port != 0) {
2904 session_send_mtc = Config->get_send_mtc();
2905 if (session_send_mtc) {
2906 /* mark us ready to send */
2907 next_quarter_frame_to_send = 0;
2910 session_send_mtc = false;
2913 } else if (PARAM_IS ("send-mmc")) {
2915 /* only set the internal flag if we have
2919 if (_mmc_port != 0) {
2920 session_send_mmc = Config->get_send_mmc();
2923 session_send_mmc = false;
2926 } else if (PARAM_IS ("midi-feedback")) {
2928 /* only set the internal flag if we have
2932 if (_mtc_port != 0) {
2933 session_midi_feedback = Config->get_midi_feedback();
2936 } else if (PARAM_IS ("jack-time-master")) {
2938 engine().reset_timebase ();
2940 } else if (PARAM_IS ("native-file-header-format")) {
2942 if (!first_file_header_format_reset) {
2943 reset_native_file_format ();
2946 first_file_header_format_reset = false;
2948 } else if (PARAM_IS ("native-file-data-format")) {
2950 if (!first_file_data_format_reset) {
2951 reset_native_file_format ();
2954 first_file_data_format_reset = false;
2956 } else if (PARAM_IS ("slave-source")) {
2957 set_slave_source (Config->get_slave_source());
2958 } else if (PARAM_IS ("remote-model")) {
2959 set_remote_control_ids ();
2960 } else if (PARAM_IS ("denormal-model")) {