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>
60 #include <pbd/copyfile.h>
62 #include <ardour/audioengine.h>
63 #include <ardour/configuration.h>
64 #include <ardour/session.h>
65 #include <ardour/session_directory.h>
66 #include <ardour/session_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;
446 if(!copy_file (template_path, session_file_path.to_string())) {
447 error << string_compose (_("Could not use session template %1 to create new session."), template_path)
455 Session::load_diskstreams (const XMLNode& node)
458 XMLNodeConstIterator citer;
460 clist = node.children();
462 for (citer = clist.begin(); citer != clist.end(); ++citer) {
465 /* diskstreams added automatically by DiskstreamCreated handler */
466 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
467 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
468 add_diskstream (dstream);
469 } else if ((*citer)->name() == "MidiDiskstream") {
470 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
471 add_diskstream (dstream);
473 error << _("Session: unknown diskstream type in XML") << endmsg;
477 catch (failed_constructor& err) {
478 error << _("Session: could not load diskstream via XML state") << endmsg;
487 Session::maybe_write_autosave()
489 if (dirty() && record_status() != Recording) {
490 save_state("", true);
495 Session::remove_pending_capture_state ()
497 sys::path pending_state_file_path(_session_dir->root_path());
499 pending_state_file_path /= _current_snapshot_name + pending_suffix;
503 sys::remove (pending_state_file_path);
505 catch(sys::filesystem_error& ex)
507 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
508 pending_state_file_path.to_string(), ex.what()) << endmsg;
512 /** Rename a state file.
513 * @param snapshot_name Snapshot name.
516 Session::rename_state (string old_name, string new_name)
518 if (old_name == _current_snapshot_name || old_name == _name) {
519 /* refuse to rename the current snapshot or the "main" one */
523 const string old_xml_path = _path + old_name + statefile_suffix;
524 const string new_xml_path = _path + new_name + statefile_suffix;
526 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
527 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
531 /** Remove a state file.
532 * @param snapshot_name Snapshot name.
535 Session::remove_state (string snapshot_name)
537 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
538 /* refuse to remove the current snapshot or the "main" one */
542 sys::path xml_path(_session_dir->root_path());
544 xml_path /= snapshot_name + statefile_suffix;
546 sys::path backup_path(xml_path.to_string() + backup_suffix);
548 /* make a backup copy of the state file */
549 if (sys::exists (xml_path)) {
550 copy_file (xml_path.to_string(), backup_path.to_string());
554 sys::remove (xml_path);
558 Session::save_state (string snapshot_name, bool pending)
561 sys::path xml_path(_session_dir->root_path());
562 sys::path bak_path(xml_path);
564 if (_state_of_the_state & CannotSave) {
568 if (!_engine.connected ()) {
569 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
574 /* tell sources we're saving first, in case they write out to a new file
575 * which should be saved with the state rather than the old one */
576 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
577 i->second->session_saved();
579 tree.set_root (&get_state());
581 if (snapshot_name.empty()) {
582 snapshot_name = _current_snapshot_name;
587 /* proper save: use statefile_suffix (.ardour in English) */
589 xml_path /= snapshot_name + statefile_suffix;
591 /* make a backup copy of the old file */
592 bak_path /= snapshot_name + statefile_suffix + backup_suffix;
594 if (sys::exists (xml_path)) {
595 copy_file (xml_path.to_string(), bak_path.to_string());
600 /* pending save: use pending_suffix (.pending in English) */
601 xml_path /= snapshot_name + pending_suffix;
604 sys::path tmp_path(_session_dir->root_path());
606 tmp_path /= snapshot_name + temp_suffix;
608 // cerr << "actually writing state to " << xml_path.to_string() << endl;
610 if (!tree.write (tmp_path.to_string())) {
611 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
612 sys::remove (tmp_path);
617 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
618 error << string_compose (_("could not rename temporary session file %1 to %2"),
619 tmp_path.to_string(), xml_path.to_string()) << endmsg;
620 sys::remove (tmp_path);
627 save_history (snapshot_name);
629 bool was_dirty = dirty();
631 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
634 DirtyChanged (); /* EMIT SIGNAL */
637 StateSaved (snapshot_name); /* EMIT SIGNAL */
644 Session::restore_state (string snapshot_name)
646 if (load_state (snapshot_name) == 0) {
647 set_state (*state_tree->root());
654 Session::load_state (string snapshot_name)
661 state_was_pending = false;
663 /* check for leftover pending state from a crashed capture attempt */
665 sys::path xmlpath(_session_dir->root_path());
666 xmlpath /= snapshot_name + pending_suffix;
668 if (sys::exists (xmlpath)) {
670 /* there is pending state from a crashed capture attempt */
672 if (AskAboutPendingState()) {
673 state_was_pending = true;
677 if (!state_was_pending) {
678 xmlpath = _session_dir->root_path();
679 xmlpath /= snapshot_name + statefile_suffix;
682 if (!sys::exists (xmlpath)) {
683 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
687 state_tree = new XMLTree;
691 if (!state_tree->read (xmlpath.to_string())) {
692 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
698 XMLNode& root (*state_tree->root());
700 if (root.name() != X_("Session")) {
701 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
707 const XMLProperty* prop;
710 if ((prop = root.property ("version")) == 0) {
711 /* no version implies very old version of Ardour */
715 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
716 if (major_version < 2) {
723 sys::path backup_path(_session_dir->root_path());
725 backup_path /= snapshot_name + "-1" + statefile_suffix;
727 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
728 xmlpath.to_string(), backup_path.to_string())
731 copy_file (xmlpath.to_string(), backup_path.to_string());
733 /* if it fails, don't worry. right? */
740 Session::load_options (const XMLNode& node)
744 LocaleGuard lg (X_("POSIX"));
746 Config->set_variables (node, ConfigVariableBase::Session);
748 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
749 if ((prop = child->property ("val")) != 0) {
750 _end_location_is_free = (prop->value() == "yes");
758 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
760 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
761 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
763 return owner & modified_by_session_or_user;
767 Session::get_options () const
770 LocaleGuard lg (X_("POSIX"));
772 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
774 child = option_root.add_child ("end-marker-is-free");
775 child->add_property ("val", _end_location_is_free ? "yes" : "no");
787 Session::get_template()
789 /* if we don't disable rec-enable, diskstreams
790 will believe they need to store their capture
791 sources in their state node.
794 disable_record (false);
800 Session::state(bool full_state)
802 XMLNode* node = new XMLNode("Session");
805 // store libardour version, just in case
807 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
808 libardour_major_version, libardour_minor_version, libardour_micro_version);
809 node->add_property("version", string(buf));
811 /* store configuration settings */
816 node->add_property ("name", _name);
818 if (session_dirs.size() > 1) {
822 vector<space_and_path>::iterator i = session_dirs.begin();
823 vector<space_and_path>::iterator next;
825 ++i; /* skip the first one */
829 while (i != session_dirs.end()) {
833 if (next != session_dirs.end()) {
843 child = node->add_child ("Path");
844 child->add_content (p);
848 /* save the ID counter */
850 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
851 node->add_property ("id-counter", buf);
853 /* various options */
855 node->add_child_nocopy (get_options());
857 child = node->add_child ("Sources");
860 Glib::Mutex::Lock sl (source_lock);
862 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
864 /* Don't save information about AudioFileSources that are empty */
866 boost::shared_ptr<AudioFileSource> fs;
868 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
870 /* Don't save sources that are empty, unless they're destructive (which are OK
871 if they are empty, because we will re-use them every time.)
874 if (!fs->destructive()) {
875 if (fs->length() == 0) {
881 child->add_child_nocopy (siter->second->get_state());
885 child = node->add_child ("Regions");
888 Glib::Mutex::Lock rl (region_lock);
890 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
892 /* only store regions not attached to playlists */
894 if (i->second->playlist() == 0) {
895 child->add_child_nocopy (i->second->state (true));
900 child = node->add_child ("DiskStreams");
903 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
904 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
905 if (!(*i)->hidden()) {
906 child->add_child_nocopy ((*i)->get_state());
912 node->add_child_nocopy (_locations.get_state());
914 // for a template, just create a new Locations, populate it
915 // with the default start and end, and get the state for that.
917 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
918 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
921 end->set_end(compute_initial_length());
923 node->add_child_nocopy (loc.get_state());
926 child = node->add_child ("Connections");
928 Glib::Mutex::Lock lm (bundle_lock);
929 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
930 if (!(*i)->dynamic()) {
931 child->add_child_nocopy ((*i)->get_state());
936 child = node->add_child ("Routes");
938 boost::shared_ptr<RouteList> r = routes.reader ();
940 RoutePublicOrderSorter cmp;
941 RouteList public_order (*r);
942 public_order.sort (cmp);
944 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
945 if (!(*i)->is_hidden()) {
947 child->add_child_nocopy ((*i)->get_state());
949 child->add_child_nocopy ((*i)->get_template());
956 child = node->add_child ("EditGroups");
957 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
958 child->add_child_nocopy ((*i)->get_state());
961 child = node->add_child ("MixGroups");
962 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
963 child->add_child_nocopy ((*i)->get_state());
966 child = node->add_child ("Playlists");
967 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
968 if (!(*i)->hidden()) {
969 if (!(*i)->empty()) {
971 child->add_child_nocopy ((*i)->get_state());
973 child->add_child_nocopy ((*i)->get_template());
979 child = node->add_child ("UnusedPlaylists");
980 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
981 if (!(*i)->hidden()) {
982 if (!(*i)->empty()) {
984 child->add_child_nocopy ((*i)->get_state());
986 child->add_child_nocopy ((*i)->get_template());
994 child = node->add_child ("Click");
995 child->add_child_nocopy (_click_io->state (full_state));
999 child = node->add_child ("NamedSelections");
1000 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1002 child->add_child_nocopy ((*i)->get_state());
1007 node->add_child_nocopy (_tempo_map->get_state());
1009 node->add_child_nocopy (get_control_protocol_state());
1012 node->add_child_copy (*_extra_xml);
1019 Session::get_control_protocol_state ()
1021 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1022 return cpm.get_state();
1026 Session::set_state (const XMLNode& node)
1030 const XMLProperty* prop;
1033 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1035 if (node.name() != X_("Session")){
1036 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1040 if ((prop = node.property ("name")) != 0) {
1041 _name = prop->value ();
1044 setup_raid_path(_path);
1046 if ((prop = node.property (X_("id-counter"))) != 0) {
1048 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1049 ID::init_counter (x);
1051 /* old sessions used a timebased counter, so fake
1052 the startup ID counter based on a standard
1057 ID::init_counter (now);
1061 IO::disable_ports ();
1062 IO::disable_connecting ();
1064 /* Object loading order:
1082 if (use_config_midi_ports ()) {
1085 if ((child = find_named_node (node, "extra")) != 0) {
1086 _extra_xml = new XMLNode (*child);
1089 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1090 load_options (*child);
1091 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1092 load_options (*child);
1094 error << _("Session: XML state has no options section") << endmsg;
1097 if ((child = find_named_node (node, "Locations")) == 0) {
1098 error << _("Session: XML state has no locations section") << endmsg;
1100 } else if (_locations.set_state (*child)) {
1106 if ((location = _locations.auto_loop_location()) != 0) {
1107 set_auto_loop_location (location);
1110 if ((location = _locations.auto_punch_location()) != 0) {
1111 set_auto_punch_location (location);
1114 if ((location = _locations.end_location()) == 0) {
1115 _locations.add (end_location);
1117 delete end_location;
1118 end_location = location;
1121 if ((location = _locations.start_location()) == 0) {
1122 _locations.add (start_location);
1124 delete start_location;
1125 start_location = location;
1128 AudioFileSource::set_header_position_offset (start_location->start());
1130 if ((child = find_named_node (node, "Sources")) == 0) {
1131 error << _("Session: XML state has no sources section") << endmsg;
1133 } else if (load_sources (*child)) {
1137 if ((child = find_named_node (node, "Regions")) == 0) {
1138 error << _("Session: XML state has no Regions section") << endmsg;
1140 } else if (load_regions (*child)) {
1144 if ((child = find_named_node (node, "Playlists")) == 0) {
1145 error << _("Session: XML state has no playlists section") << endmsg;
1147 } else if (load_playlists (*child)) {
1151 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1153 } else if (load_unused_playlists (*child)) {
1157 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1158 if (load_named_selections (*child)) {
1163 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1164 error << _("Session: XML state has no diskstreams section") << endmsg;
1166 } else if (load_diskstreams (*child)) {
1170 if ((child = find_named_node (node, "Connections")) == 0) {
1171 error << _("Session: XML state has no connections section") << endmsg;
1173 } else if (load_bundles (*child)) {
1177 if ((child = find_named_node (node, "EditGroups")) == 0) {
1178 error << _("Session: XML state has no edit groups section") << endmsg;
1180 } else if (load_edit_groups (*child)) {
1184 if ((child = find_named_node (node, "MixGroups")) == 0) {
1185 error << _("Session: XML state has no mix groups section") << endmsg;
1187 } else if (load_mix_groups (*child)) {
1191 if ((child = find_named_node (node, "TempoMap")) == 0) {
1192 error << _("Session: XML state has no Tempo Map section") << endmsg;
1194 } else if (_tempo_map->set_state (*child)) {
1198 if ((child = find_named_node (node, "Routes")) == 0) {
1199 error << _("Session: XML state has no routes section") << endmsg;
1201 } else if (load_routes (*child)) {
1205 if ((child = find_named_node (node, "Click")) == 0) {
1206 warning << _("Session: XML state has no click section") << endmsg;
1207 } else if (_click_io) {
1208 _click_io->set_state (*child);
1211 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1212 ControlProtocolManager::instance().set_protocol_states (*child);
1215 /* here beginneth the second phase ... */
1217 StateReady (); /* EMIT SIGNAL */
1219 _state_of_the_state = Clean;
1221 if (state_was_pending) {
1222 save_state (_current_snapshot_name);
1223 remove_pending_capture_state ();
1224 state_was_pending = false;
1234 Session::load_routes (const XMLNode& node)
1237 XMLNodeConstIterator niter;
1238 RouteList new_routes;
1240 nlist = node.children();
1244 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1246 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1249 error << _("Session: cannot create Route from XML description.") << endmsg;
1253 new_routes.push_back (route);
1256 add_routes (new_routes);
1261 boost::shared_ptr<Route>
1262 Session::XMLRouteFactory (const XMLNode& node)
1264 if (node.name() != "Route") {
1265 return boost::shared_ptr<Route> ((Route*) 0);
1268 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1270 DataType type = DataType::AUDIO;
1271 const XMLProperty* prop = node.property("default-type");
1273 type = DataType(prop->value());
1275 assert(type != DataType::NIL);
1277 if (has_diskstream) {
1278 if (type == DataType::AUDIO) {
1279 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1282 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1286 boost::shared_ptr<Route> ret (new Route (*this, node));
1292 Session::load_regions (const XMLNode& node)
1295 XMLNodeConstIterator niter;
1296 boost::shared_ptr<Region> region;
1298 nlist = node.children();
1302 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1303 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1304 error << _("Session: cannot create Region from XML description.") << endmsg;
1311 boost::shared_ptr<Region>
1312 Session::XMLRegionFactory (const XMLNode& node, bool full)
1314 const XMLProperty* type = node.property("type");
1318 if ( !type || type->value() == "audio" ) {
1320 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1322 } else if (type->value() == "midi") {
1324 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1328 } catch (failed_constructor& err) {
1329 return boost::shared_ptr<Region> ();
1332 return boost::shared_ptr<Region> ();
1335 boost::shared_ptr<AudioRegion>
1336 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1338 const XMLProperty* prop;
1339 boost::shared_ptr<Source> source;
1340 boost::shared_ptr<AudioSource> as;
1342 uint32_t nchans = 1;
1345 if (node.name() != X_("Region")) {
1346 return boost::shared_ptr<AudioRegion>();
1349 if ((prop = node.property (X_("channels"))) != 0) {
1350 nchans = atoi (prop->value().c_str());
1353 if ((prop = node.property ("name")) == 0) {
1354 cerr << "no name for this region\n";
1358 if ((prop = node.property (X_("source-0"))) == 0) {
1359 if ((prop = node.property ("source")) == 0) {
1360 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1361 return boost::shared_ptr<AudioRegion>();
1365 PBD::ID s_id (prop->value());
1367 if ((source = source_by_id (s_id)) == 0) {
1368 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1369 return boost::shared_ptr<AudioRegion>();
1372 as = boost::dynamic_pointer_cast<AudioSource>(source);
1374 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1375 return boost::shared_ptr<AudioRegion>();
1378 sources.push_back (as);
1380 /* pickup other channels */
1382 for (uint32_t n=1; n < nchans; ++n) {
1383 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1384 if ((prop = node.property (buf)) != 0) {
1386 PBD::ID id2 (prop->value());
1388 if ((source = source_by_id (id2)) == 0) {
1389 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1390 return boost::shared_ptr<AudioRegion>();
1393 as = boost::dynamic_pointer_cast<AudioSource>(source);
1395 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1396 return boost::shared_ptr<AudioRegion>();
1398 sources.push_back (as);
1403 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1405 /* a final detail: this is the one and only place that we know how long missing files are */
1407 if (region->whole_file()) {
1408 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1409 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1411 sfp->set_length (region->length());
1420 catch (failed_constructor& err) {
1421 return boost::shared_ptr<AudioRegion>();
1425 boost::shared_ptr<MidiRegion>
1426 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1428 const XMLProperty* prop;
1429 boost::shared_ptr<Source> source;
1430 boost::shared_ptr<MidiSource> ms;
1432 uint32_t nchans = 1;
1434 if (node.name() != X_("Region")) {
1435 return boost::shared_ptr<MidiRegion>();
1438 if ((prop = node.property (X_("channels"))) != 0) {
1439 nchans = atoi (prop->value().c_str());
1442 if ((prop = node.property ("name")) == 0) {
1443 cerr << "no name for this region\n";
1447 // Multiple midi channels? that's just crazy talk
1448 assert(nchans == 1);
1450 if ((prop = node.property (X_("source-0"))) == 0) {
1451 if ((prop = node.property ("source")) == 0) {
1452 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1453 return boost::shared_ptr<MidiRegion>();
1457 PBD::ID s_id (prop->value());
1459 if ((source = source_by_id (s_id)) == 0) {
1460 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1461 return boost::shared_ptr<MidiRegion>();
1464 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1466 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1467 return boost::shared_ptr<MidiRegion>();
1470 sources.push_back (ms);
1473 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1474 /* a final detail: this is the one and only place that we know how long missing files are */
1476 if (region->whole_file()) {
1477 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1478 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1480 sfp->set_length (region->length());
1488 catch (failed_constructor& err) {
1489 return boost::shared_ptr<MidiRegion>();
1494 Session::get_sources_as_xml ()
1497 XMLNode* node = new XMLNode (X_("Sources"));
1498 Glib::Mutex::Lock lm (source_lock);
1500 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1501 node->add_child_nocopy (i->second->get_state());
1508 Session::path_from_region_name (DataType type, string name, string identifier)
1510 char buf[PATH_MAX+1];
1512 SessionDirectory sdir(get_best_session_directory_for_new_source());
1513 string sound_dir = ((type == DataType::AUDIO)
1514 ? sdir.sound_path().to_string()
1515 : sdir.midi_path().to_string());
1517 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1519 for (n = 0; n < 999999; ++n) {
1520 if (identifier.length()) {
1521 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1522 identifier.c_str(), n, ext.c_str());
1524 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1528 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1533 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1542 Session::load_sources (const XMLNode& node)
1545 XMLNodeConstIterator niter;
1546 boost::shared_ptr<Source> source;
1548 nlist = node.children();
1552 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1555 if ((source = XMLSourceFactory (**niter)) == 0) {
1556 error << _("Session: cannot create Source from XML description.") << endmsg;
1560 catch (non_existent_source& err) {
1561 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1562 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1569 boost::shared_ptr<Source>
1570 Session::XMLSourceFactory (const XMLNode& node)
1572 if (node.name() != "Source") {
1573 return boost::shared_ptr<Source>();
1577 return SourceFactory::create (*this, node);
1580 catch (failed_constructor& err) {
1581 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1582 return boost::shared_ptr<Source>();
1587 Session::save_template (string template_name)
1590 string xml_path, bak_path, template_path;
1592 if (_state_of_the_state & CannotSave) {
1596 sys::path user_template_dir(user_template_directory());
1600 sys::create_directories (user_template_dir);
1602 catch(sys::filesystem_error& ex)
1604 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1605 user_template_dir.to_string(), ex.what()) << endmsg;
1609 tree.set_root (&get_template());
1611 sys::path template_file_path(user_template_dir);
1612 template_file_path /= template_name + template_suffix;
1614 if (sys::exists (template_file_path))
1616 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1617 template_file_path.to_string()) << endmsg;
1621 if (!tree.write (template_file_path.to_string())) {
1622 error << _("mix template not saved") << endmsg;
1630 Session::refresh_disk_space ()
1633 struct statfs statfsbuf;
1634 vector<space_and_path>::iterator i;
1635 Glib::Mutex::Lock lm (space_lock);
1638 /* get freespace on every FS that is part of the session path */
1640 _total_free_4k_blocks = 0;
1642 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1643 statfs ((*i).path.c_str(), &statfsbuf);
1645 scale = statfsbuf.f_bsize/4096.0;
1647 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1648 _total_free_4k_blocks += (*i).blocks;
1654 Session::get_best_session_directory_for_new_source ()
1656 vector<space_and_path>::iterator i;
1657 string result = _session_dir->root_path().to_string();
1659 /* handle common case without system calls */
1661 if (session_dirs.size() == 1) {
1665 /* OK, here's the algorithm we're following here:
1667 We want to select which directory to use for
1668 the next file source to be created. Ideally,
1669 we'd like to use a round-robin process so as to
1670 get maximum performance benefits from splitting
1671 the files across multiple disks.
1673 However, in situations without much diskspace, an
1674 RR approach may end up filling up a filesystem
1675 with new files while others still have space.
1676 Its therefore important to pay some attention to
1677 the freespace in the filesystem holding each
1678 directory as well. However, if we did that by
1679 itself, we'd keep creating new files in the file
1680 system with the most space until it was as full
1681 as all others, thus negating any performance
1682 benefits of this RAID-1 like approach.
1684 So, we use a user-configurable space threshold. If
1685 there are at least 2 filesystems with more than this
1686 much space available, we use RR selection between them.
1687 If not, then we pick the filesystem with the most space.
1689 This gets a good balance between the two
1693 refresh_disk_space ();
1695 int free_enough = 0;
1697 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1698 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1703 if (free_enough >= 2) {
1704 /* use RR selection process, ensuring that the one
1708 i = last_rr_session_dir;
1711 if (++i == session_dirs.end()) {
1712 i = session_dirs.begin();
1715 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1716 if (create_session_directory ((*i).path)) {
1718 last_rr_session_dir = i;
1723 } while (i != last_rr_session_dir);
1727 /* pick FS with the most freespace (and that
1728 seems to actually work ...)
1731 vector<space_and_path> sorted;
1732 space_and_path_ascending_cmp cmp;
1734 sorted = session_dirs;
1735 sort (sorted.begin(), sorted.end(), cmp);
1737 for (i = sorted.begin(); i != sorted.end(); ++i) {
1738 if (create_session_directory ((*i).path)) {
1740 last_rr_session_dir = i;
1750 Session::load_playlists (const XMLNode& node)
1753 XMLNodeConstIterator niter;
1754 boost::shared_ptr<Playlist> playlist;
1756 nlist = node.children();
1760 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1762 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1763 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1771 Session::load_unused_playlists (const XMLNode& node)
1774 XMLNodeConstIterator niter;
1775 boost::shared_ptr<Playlist> playlist;
1777 nlist = node.children();
1781 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1783 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1784 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1788 // now manually untrack it
1790 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1796 boost::shared_ptr<Playlist>
1797 Session::XMLPlaylistFactory (const XMLNode& node)
1800 return PlaylistFactory::create (*this, node);
1803 catch (failed_constructor& err) {
1804 return boost::shared_ptr<Playlist>();
1809 Session::load_named_selections (const XMLNode& node)
1812 XMLNodeConstIterator niter;
1815 nlist = node.children();
1819 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1821 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1822 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1830 Session::XMLNamedSelectionFactory (const XMLNode& node)
1833 return new NamedSelection (*this, node);
1836 catch (failed_constructor& err) {
1842 Session::automation_dir () const
1845 res += "automation/";
1850 Session::load_bundles (const XMLNode& node)
1852 XMLNodeList nlist = node.children();
1853 XMLNodeConstIterator niter;
1857 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1858 if ((*niter)->name() == "InputConnection") {
1859 add_bundle (new ARDOUR::InputBundle (**niter));
1860 } else if ((*niter)->name() == "OutputConnection") {
1861 add_bundle (new ARDOUR::OutputBundle (**niter));
1863 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1872 Session::load_edit_groups (const XMLNode& node)
1874 return load_route_groups (node, true);
1878 Session::load_mix_groups (const XMLNode& node)
1880 return load_route_groups (node, false);
1884 Session::load_route_groups (const XMLNode& node, bool edit)
1886 XMLNodeList nlist = node.children();
1887 XMLNodeConstIterator niter;
1892 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1893 if ((*niter)->name() == "RouteGroup") {
1895 rg = add_edit_group ("");
1896 rg->set_state (**niter);
1898 rg = add_mix_group ("");
1899 rg->set_state (**niter);
1908 state_file_filter (const string &str, void *arg)
1910 return (str.length() > strlen(statefile_suffix) &&
1911 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
1915 bool operator()(const string* a, const string* b) {
1921 remove_end(string* state)
1923 string statename(*state);
1925 string::size_type start,end;
1926 if ((start = statename.find_last_of ('/')) != string::npos) {
1927 statename = statename.substr (start+1);
1930 if ((end = statename.rfind(".ardour")) == string::npos) {
1931 end = statename.length();
1934 return new string(statename.substr (0, end));
1938 Session::possible_states (string path)
1940 PathScanner scanner;
1941 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
1943 transform(states->begin(), states->end(), states->begin(), remove_end);
1946 sort (states->begin(), states->end(), cmp);
1952 Session::possible_states () const
1954 return possible_states(_path);
1958 Session::auto_save()
1960 save_state (_current_snapshot_name);
1964 Session::add_edit_group (string name)
1966 RouteGroup* rg = new RouteGroup (*this, name);
1967 edit_groups.push_back (rg);
1968 edit_group_added (rg); /* EMIT SIGNAL */
1974 Session::add_mix_group (string name)
1976 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
1977 mix_groups.push_back (rg);
1978 mix_group_added (rg); /* EMIT SIGNAL */
1984 Session::remove_edit_group (RouteGroup& rg)
1986 list<RouteGroup*>::iterator i;
1988 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
1989 (*i)->apply (&Route::drop_edit_group, this);
1990 edit_groups.erase (i);
1991 edit_group_removed (); /* EMIT SIGNAL */
1998 Session::remove_mix_group (RouteGroup& rg)
2000 list<RouteGroup*>::iterator i;
2002 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2003 (*i)->apply (&Route::drop_mix_group, this);
2004 mix_groups.erase (i);
2005 mix_group_removed (); /* EMIT SIGNAL */
2012 Session::mix_group_by_name (string name)
2014 list<RouteGroup *>::iterator i;
2016 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2017 if ((*i)->name() == name) {
2025 Session::edit_group_by_name (string name)
2027 list<RouteGroup *>::iterator i;
2029 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2030 if ((*i)->name() == name) {
2038 Session::begin_reversible_command (const string& name)
2040 current_trans = new UndoTransaction;
2041 current_trans->set_name (name);
2045 Session::commit_reversible_command (Command *cmd)
2050 current_trans->add_command (cmd);
2053 gettimeofday (&now, 0);
2054 current_trans->set_timestamp (now);
2056 _history.add (current_trans);
2059 Session::GlobalRouteBooleanState
2060 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2062 GlobalRouteBooleanState s;
2063 boost::shared_ptr<RouteList> r = routes.reader ();
2065 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2066 if (!(*i)->is_hidden()) {
2067 RouteBooleanState v;
2070 Route* r = (*i).get();
2071 v.second = (r->*method)();
2080 Session::GlobalRouteMeterState
2081 Session::get_global_route_metering ()
2083 GlobalRouteMeterState s;
2084 boost::shared_ptr<RouteList> r = routes.reader ();
2086 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2087 if (!(*i)->is_hidden()) {
2091 v.second = (*i)->meter_point();
2101 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2103 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2105 boost::shared_ptr<Route> r = (i->first.lock());
2108 r->set_meter_point (i->second, arg);
2114 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2116 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2118 boost::shared_ptr<Route> r = (i->first.lock());
2121 Route* rp = r.get();
2122 (rp->*method) (i->second, arg);
2128 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2130 set_global_route_boolean (s, &Route::set_mute, src);
2134 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2136 set_global_route_boolean (s, &Route::set_solo, src);
2140 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2142 set_global_route_boolean (s, &Route::set_record_enable, src);
2147 Session::global_mute_memento (void* src)
2149 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2153 Session::global_metering_memento (void* src)
2155 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2159 Session::global_solo_memento (void* src)
2161 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2165 Session::global_record_enable_memento (void* src)
2167 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2172 accept_all_non_peak_files (const string& path, void *arg)
2174 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2178 accept_all_state_files (const string& path, void *arg)
2180 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2184 Session::find_all_sources (string path, set<string>& result)
2189 if (!tree.read (path)) {
2193 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2198 XMLNodeConstIterator niter;
2200 nlist = node->children();
2204 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2208 if ((prop = (*niter)->property (X_("name"))) == 0) {
2212 if (prop->value()[0] == '/') {
2213 /* external file, ignore */
2217 sys::path source_path = _session_dir->sound_path ();
2219 source_path /= prop->value ();
2221 result.insert (source_path.to_string ());
2228 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2230 PathScanner scanner;
2231 vector<string*>* state_files;
2233 string this_snapshot_path;
2239 if (ripped[ripped.length()-1] == '/') {
2240 ripped = ripped.substr (0, ripped.length() - 1);
2243 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2245 if (state_files == 0) {
2250 this_snapshot_path = _path;
2251 this_snapshot_path += _current_snapshot_name;
2252 this_snapshot_path += statefile_suffix;
2254 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2256 if (exclude_this_snapshot && **i == this_snapshot_path) {
2260 if (find_all_sources (**i, result) < 0) {
2268 struct RegionCounter {
2269 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2270 AudioSourceList::iterator iter;
2271 boost::shared_ptr<Region> region;
2274 RegionCounter() : count (0) {}
2278 Session::cleanup_sources (Session::cleanup_report& rep)
2280 // FIXME: needs adaptation to midi
2282 vector<boost::shared_ptr<Source> > dead_sources;
2283 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2284 PathScanner scanner;
2286 vector<space_and_path>::iterator i;
2287 vector<space_and_path>::iterator nexti;
2288 vector<string*>* soundfiles;
2289 vector<string> unused;
2290 set<string> all_sources;
2295 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2297 /* step 1: consider deleting all unused playlists */
2299 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2302 status = AskAboutPlaylistDeletion (*x);
2311 playlists_tbd.push_back (*x);
2315 /* leave it alone */
2320 /* now delete any that were marked for deletion */
2322 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2323 (*x)->drop_references ();
2326 playlists_tbd.clear ();
2328 /* step 2: find all un-used sources */
2333 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2335 SourceMap::iterator tmp;
2340 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2344 if (!i->second->used() && i->second->length() > 0) {
2345 dead_sources.push_back (i->second);
2346 i->second->GoingAway();
2352 /* build a list of all the possible sound directories for the session */
2354 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2359 SessionDirectory sdir ((*i).path);
2360 sound_path += sdir.sound_path().to_string();
2362 if (nexti != session_dirs.end()) {
2369 /* now do the same thing for the files that ended up in the sounds dir(s)
2370 but are not referenced as sources in any snapshot.
2373 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2375 if (soundfiles == 0) {
2379 /* find all sources, but don't use this snapshot because the
2380 state file on disk still references sources we may have already
2384 find_all_sources_across_snapshots (all_sources, true);
2386 /* add our current source list
2389 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2390 boost::shared_ptr<AudioFileSource> fs;
2392 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2393 all_sources.insert (fs->path());
2397 char tmppath1[PATH_MAX+1];
2398 char tmppath2[PATH_MAX+1];
2400 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2405 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2407 realpath(spath.c_str(), tmppath1);
2408 realpath((*i).c_str(), tmppath2);
2410 if (strcmp(tmppath1, tmppath2) == 0) {
2417 unused.push_back (spath);
2421 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2423 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2424 struct stat statbuf;
2426 rep.paths.push_back (*x);
2427 if (stat ((*x).c_str(), &statbuf) == 0) {
2428 rep.space += statbuf.st_size;
2433 /* don't move the file across filesystems, just
2434 stick it in the `dead_sound_dir_name' directory
2435 on whichever filesystem it was already on.
2438 if ((*x).find ("/sounds/") != string::npos) {
2440 /* old school, go up 1 level */
2442 newpath = Glib::path_get_dirname (*x); // "sounds"
2443 newpath = Glib::path_get_dirname (newpath); // "session-name"
2447 /* new school, go up 4 levels */
2449 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2450 newpath = Glib::path_get_dirname (newpath); // "session-name"
2451 newpath = Glib::path_get_dirname (newpath); // "interchange"
2452 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2456 newpath += dead_sound_dir_name;
2458 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2459 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2464 newpath += Glib::path_get_basename ((*x));
2466 if (access (newpath.c_str(), F_OK) == 0) {
2468 /* the new path already exists, try versioning */
2470 char buf[PATH_MAX+1];
2474 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2477 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2478 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2482 if (version == 999) {
2483 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2487 newpath = newpath_v;
2492 /* it doesn't exist, or we can't read it or something */
2496 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2497 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2498 (*x), newpath, strerror (errno))
2503 /* see if there an easy to find peakfile for this file, and remove it.
2506 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2507 peakpath += peakfile_suffix;
2509 if (access (peakpath.c_str(), W_OK) == 0) {
2510 if (::unlink (peakpath.c_str()) != 0) {
2511 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2512 peakpath, _path, strerror (errno))
2514 /* try to back out */
2515 rename (newpath.c_str(), _path.c_str());
2523 /* dump the history list */
2527 /* save state so we don't end up a session file
2528 referring to non-existent sources.
2534 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2539 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2541 // FIXME: needs adaptation for MIDI
2543 vector<space_and_path>::iterator i;
2544 string dead_sound_dir;
2545 struct dirent* dentry;
2546 struct stat statbuf;
2552 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2554 dead_sound_dir = (*i).path;
2555 dead_sound_dir += dead_sound_dir_name;
2557 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2561 while ((dentry = readdir (dead)) != 0) {
2563 /* avoid '.' and '..' */
2565 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2566 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2572 fullpath = dead_sound_dir;
2574 fullpath += dentry->d_name;
2576 if (stat (fullpath.c_str(), &statbuf)) {
2580 if (!S_ISREG (statbuf.st_mode)) {
2584 if (unlink (fullpath.c_str())) {
2585 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2586 fullpath, strerror (errno))
2590 rep.paths.push_back (dentry->d_name);
2591 rep.space += statbuf.st_size;
2602 Session::set_dirty ()
2604 bool was_dirty = dirty();
2606 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2609 DirtyChanged(); /* EMIT SIGNAL */
2615 Session::set_clean ()
2617 bool was_dirty = dirty();
2619 _state_of_the_state = Clean;
2622 DirtyChanged(); /* EMIT SIGNAL */
2627 Session::set_deletion_in_progress ()
2629 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2633 Session::add_controllable (boost::shared_ptr<Controllable> c)
2635 /* this adds a controllable to the list managed by the Session.
2636 this is a subset of those managed by the Controllable class
2637 itself, and represents the only ones whose state will be saved
2638 as part of the session.
2641 Glib::Mutex::Lock lm (controllables_lock);
2642 controllables.insert (c);
2645 struct null_deleter { void operator()(void const *) const {} };
2648 Session::remove_controllable (Controllable* c)
2650 if (_state_of_the_state | Deletion) {
2654 Glib::Mutex::Lock lm (controllables_lock);
2656 Controllables::iterator x = controllables.find(
2657 boost::shared_ptr<Controllable>(c, null_deleter()));
2659 if (x != controllables.end()) {
2660 controllables.erase (x);
2664 boost::shared_ptr<Controllable>
2665 Session::controllable_by_id (const PBD::ID& id)
2667 Glib::Mutex::Lock lm (controllables_lock);
2669 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2670 if ((*i)->id() == id) {
2675 return boost::shared_ptr<Controllable>();
2679 Session::add_instant_xml (XMLNode& node)
2681 Stateful::add_instant_xml (node, _path);
2682 Config->add_instant_xml (node);
2686 Session::instant_xml (const string& node_name)
2688 return Stateful::instant_xml (node_name, _path);
2692 Session::save_history (string snapshot_name)
2698 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2700 if (snapshot_name.empty()) {
2701 snapshot_name = _current_snapshot_name;
2704 xml_path = _path + snapshot_name + ".history";
2706 bak_path = xml_path + ".bak";
2708 if ((access (xml_path.c_str(), F_OK) == 0) &&
2709 (rename (xml_path.c_str(), bak_path.c_str())))
2711 error << _("could not backup old history file, current history not saved.") << endmsg;
2715 if (!tree.write (xml_path))
2717 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2719 /* don't leave a corrupt file lying around if it is
2723 if (unlink (xml_path.c_str())) {
2724 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2726 if (rename (bak_path.c_str(), xml_path.c_str()))
2728 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2739 Session::restore_history (string snapshot_name)
2744 if (snapshot_name.empty()) {
2745 snapshot_name = _current_snapshot_name;
2749 xmlpath = _path + snapshot_name + ".history";
2750 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2752 if (access (xmlpath.c_str(), F_OK)) {
2753 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2757 if (!tree.read (xmlpath)) {
2758 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2762 /* replace history */
2765 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2768 UndoTransaction* ut = new UndoTransaction ();
2771 ut->set_name(t->property("name")->value());
2772 stringstream ss(t->property("tv_sec")->value());
2774 ss.str(t->property("tv_usec")->value());
2776 ut->set_timestamp(tv);
2778 for (XMLNodeConstIterator child_it = t->children().begin();
2779 child_it != t->children().end();
2782 XMLNode *n = *child_it;
2785 if (n->name() == "MementoCommand" ||
2786 n->name() == "MementoUndoCommand" ||
2787 n->name() == "MementoRedoCommand") {
2789 if ((c = memento_command_factory(n))) {
2793 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2795 if ((c = global_state_command_factory (*n))) {
2796 ut->add_command (c);
2801 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2812 Session::config_changed (const char* parameter_name)
2814 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2816 if (PARAM_IS ("seamless-loop")) {
2818 } else if (PARAM_IS ("rf-speed")) {
2820 } else if (PARAM_IS ("auto-loop")) {
2822 } else if (PARAM_IS ("auto-input")) {
2824 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2825 /* auto-input only makes a difference if we're rolling */
2827 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2829 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2830 if ((*i)->record_enabled ()) {
2831 (*i)->monitor_input (!Config->get_auto_input());
2836 } else if (PARAM_IS ("punch-in")) {
2840 if ((location = _locations.auto_punch_location()) != 0) {
2842 if (Config->get_punch_in ()) {
2843 replace_event (Event::PunchIn, location->start());
2845 remove_event (location->start(), Event::PunchIn);
2849 } else if (PARAM_IS ("punch-out")) {
2853 if ((location = _locations.auto_punch_location()) != 0) {
2855 if (Config->get_punch_out()) {
2856 replace_event (Event::PunchOut, location->end());
2858 clear_events (Event::PunchOut);
2862 } else if (PARAM_IS ("edit-mode")) {
2864 Glib::Mutex::Lock lm (playlist_lock);
2866 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2867 (*i)->set_edit_mode (Config->get_edit_mode ());
2870 } else if (PARAM_IS ("use-video-sync")) {
2872 waiting_for_sync_offset = Config->get_use_video_sync();
2874 } else if (PARAM_IS ("mmc-control")) {
2876 //poke_midi_thread ();
2878 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
2881 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
2884 } else if (PARAM_IS ("mmc-send-id")) {
2887 mmc->set_send_device_id (Config->get_mmc_send_device_id());
2890 } else if (PARAM_IS ("midi-control")) {
2892 //poke_midi_thread ();
2894 } else if (PARAM_IS ("raid-path")) {
2896 setup_raid_path (Config->get_raid_path());
2898 } else if (PARAM_IS ("smpte-format")) {
2902 } else if (PARAM_IS ("video-pullup")) {
2906 } else if (PARAM_IS ("seamless-loop")) {
2908 if (play_loop && transport_rolling()) {
2909 // to reset diskstreams etc
2910 request_play_loop (true);
2913 } else if (PARAM_IS ("rf-speed")) {
2915 cumulative_rf_motion = 0;
2918 } else if (PARAM_IS ("click-sound")) {
2920 setup_click_sounds (1);
2922 } else if (PARAM_IS ("click-emphasis-sound")) {
2924 setup_click_sounds (-1);
2926 } else if (PARAM_IS ("clicking")) {
2928 if (Config->get_clicking()) {
2929 if (_click_io && click_data) { // don't require emphasis data
2936 } else if (PARAM_IS ("send-mtc")) {
2938 /* only set the internal flag if we have
2942 if (_mtc_port != 0) {
2943 session_send_mtc = Config->get_send_mtc();
2944 if (session_send_mtc) {
2945 /* mark us ready to send */
2946 next_quarter_frame_to_send = 0;
2949 session_send_mtc = false;
2952 } else if (PARAM_IS ("send-mmc")) {
2954 /* only set the internal flag if we have
2958 if (_mmc_port != 0) {
2959 session_send_mmc = Config->get_send_mmc();
2962 session_send_mmc = false;
2965 } else if (PARAM_IS ("midi-feedback")) {
2967 /* only set the internal flag if we have
2971 if (_mtc_port != 0) {
2972 session_midi_feedback = Config->get_midi_feedback();
2975 } else if (PARAM_IS ("jack-time-master")) {
2977 engine().reset_timebase ();
2979 } else if (PARAM_IS ("native-file-header-format")) {
2981 if (!first_file_header_format_reset) {
2982 reset_native_file_format ();
2985 first_file_header_format_reset = false;
2987 } else if (PARAM_IS ("native-file-data-format")) {
2989 if (!first_file_data_format_reset) {
2990 reset_native_file_format ();
2993 first_file_data_format_reset = false;
2995 } else if (PARAM_IS ("slave-source")) {
2996 set_slave_source (Config->get_slave_source());
2997 } else if (PARAM_IS ("remote-model")) {
2998 set_remote_control_ids ();
2999 } else if (PARAM_IS ("denormal-model")) {