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());
567 sys::path bak_path(xml_path);
569 if (_state_of_the_state & CannotSave) {
573 if (!_engine.connected ()) {
574 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
579 /* tell sources we're saving first, in case they write out to a new file
580 * which should be saved with the state rather than the old one */
581 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
582 i->second->session_saved();
584 tree.set_root (&get_state());
586 if (snapshot_name.empty()) {
587 snapshot_name = _current_snapshot_name;
592 /* proper save: use statefile_suffix (.ardour in English) */
594 xml_path /= snapshot_name + statefile_suffix;
596 /* make a backup copy of the old file */
597 bak_path /= snapshot_name + statefile_suffix + backup_suffix;
599 if (sys::exists (xml_path)) {
602 sys::copy_file (xml_path, bak_path);
604 catch(sys::filesystem_error& ex)
606 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
607 xml_path.to_string(), ex.what())
615 /* pending save: use pending_suffix (.pending in English) */
616 xml_path /= snapshot_name + pending_suffix;
619 sys::path tmp_path(_session_dir->root_path());
621 tmp_path /= snapshot_name + temp_suffix;
623 // cerr << "actually writing state to " << xml_path.to_string() << endl;
625 if (!tree.write (tmp_path.to_string())) {
626 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
627 sys::remove (tmp_path);
632 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
633 error << string_compose (_("could not rename temporary session file %1 to %2"),
634 tmp_path.to_string(), xml_path.to_string()) << endmsg;
635 sys::remove (tmp_path);
642 save_history (snapshot_name);
644 bool was_dirty = dirty();
646 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
649 DirtyChanged (); /* EMIT SIGNAL */
652 StateSaved (snapshot_name); /* EMIT SIGNAL */
659 Session::restore_state (string snapshot_name)
661 if (load_state (snapshot_name) == 0) {
662 set_state (*state_tree->root());
669 Session::load_state (string snapshot_name)
676 state_was_pending = false;
678 /* check for leftover pending state from a crashed capture attempt */
680 sys::path xmlpath(_session_dir->root_path());
681 xmlpath /= snapshot_name + pending_suffix;
683 if (sys::exists (xmlpath)) {
685 /* there is pending state from a crashed capture attempt */
687 if (AskAboutPendingState()) {
688 state_was_pending = true;
692 if (!state_was_pending) {
693 xmlpath = _session_dir->root_path();
694 xmlpath /= snapshot_name + statefile_suffix;
697 if (!sys::exists (xmlpath)) {
698 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
702 state_tree = new XMLTree;
706 if (!state_tree->read (xmlpath.to_string())) {
707 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
713 XMLNode& root (*state_tree->root());
715 if (root.name() != X_("Session")) {
716 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
722 const XMLProperty* prop;
725 if ((prop = root.property ("version")) == 0) {
726 /* no version implies very old version of Ardour */
730 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
731 if (major_version < 2) {
738 sys::path backup_path(_session_dir->root_path());
740 backup_path /= snapshot_name + "-1" + statefile_suffix;
742 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
743 xmlpath.to_string(), backup_path.to_string())
748 sys::copy_file (xmlpath, backup_path);
750 catch(sys::filesystem_error& ex)
752 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
753 xmlpath.to_string(), ex.what())
763 Session::load_options (const XMLNode& node)
767 LocaleGuard lg (X_("POSIX"));
769 Config->set_variables (node, ConfigVariableBase::Session);
771 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
772 if ((prop = child->property ("val")) != 0) {
773 _end_location_is_free = (prop->value() == "yes");
781 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
783 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
784 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
786 return owner & modified_by_session_or_user;
790 Session::get_options () const
793 LocaleGuard lg (X_("POSIX"));
795 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
797 child = option_root.add_child ("end-marker-is-free");
798 child->add_property ("val", _end_location_is_free ? "yes" : "no");
810 Session::get_template()
812 /* if we don't disable rec-enable, diskstreams
813 will believe they need to store their capture
814 sources in their state node.
817 disable_record (false);
823 Session::state(bool full_state)
825 XMLNode* node = new XMLNode("Session");
828 // store libardour version, just in case
830 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
831 libardour_major_version, libardour_minor_version, libardour_micro_version);
832 node->add_property("version", string(buf));
834 /* store configuration settings */
839 node->add_property ("name", _name);
841 if (session_dirs.size() > 1) {
845 vector<space_and_path>::iterator i = session_dirs.begin();
846 vector<space_and_path>::iterator next;
848 ++i; /* skip the first one */
852 while (i != session_dirs.end()) {
856 if (next != session_dirs.end()) {
866 child = node->add_child ("Path");
867 child->add_content (p);
871 /* save the ID counter */
873 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
874 node->add_property ("id-counter", buf);
876 /* various options */
878 node->add_child_nocopy (get_options());
880 child = node->add_child ("Sources");
883 Glib::Mutex::Lock sl (source_lock);
885 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
887 /* Don't save information about AudioFileSources that are empty */
889 boost::shared_ptr<AudioFileSource> fs;
891 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
893 /* Don't save sources that are empty, unless they're destructive (which are OK
894 if they are empty, because we will re-use them every time.)
897 if (!fs->destructive()) {
898 if (fs->length() == 0) {
904 child->add_child_nocopy (siter->second->get_state());
908 child = node->add_child ("Regions");
911 Glib::Mutex::Lock rl (region_lock);
913 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
915 /* only store regions not attached to playlists */
917 if (i->second->playlist() == 0) {
918 child->add_child_nocopy (i->second->state (true));
923 child = node->add_child ("DiskStreams");
926 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
927 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
928 if (!(*i)->hidden()) {
929 child->add_child_nocopy ((*i)->get_state());
935 node->add_child_nocopy (_locations.get_state());
937 // for a template, just create a new Locations, populate it
938 // with the default start and end, and get the state for that.
940 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
941 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
944 end->set_end(compute_initial_length());
946 node->add_child_nocopy (loc.get_state());
949 child = node->add_child ("Connections");
951 Glib::Mutex::Lock lm (bundle_lock);
952 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
953 if (!(*i)->dynamic()) {
954 child->add_child_nocopy ((*i)->get_state());
959 child = node->add_child ("Routes");
961 boost::shared_ptr<RouteList> r = routes.reader ();
963 RoutePublicOrderSorter cmp;
964 RouteList public_order (*r);
965 public_order.sort (cmp);
967 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
968 if (!(*i)->is_hidden()) {
970 child->add_child_nocopy ((*i)->get_state());
972 child->add_child_nocopy ((*i)->get_template());
979 child = node->add_child ("EditGroups");
980 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
981 child->add_child_nocopy ((*i)->get_state());
984 child = node->add_child ("MixGroups");
985 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
986 child->add_child_nocopy ((*i)->get_state());
989 child = node->add_child ("Playlists");
990 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
991 if (!(*i)->hidden()) {
992 if (!(*i)->empty()) {
994 child->add_child_nocopy ((*i)->get_state());
996 child->add_child_nocopy ((*i)->get_template());
1002 child = node->add_child ("UnusedPlaylists");
1003 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1004 if (!(*i)->hidden()) {
1005 if (!(*i)->empty()) {
1007 child->add_child_nocopy ((*i)->get_state());
1009 child->add_child_nocopy ((*i)->get_template());
1017 child = node->add_child ("Click");
1018 child->add_child_nocopy (_click_io->state (full_state));
1022 child = node->add_child ("NamedSelections");
1023 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1025 child->add_child_nocopy ((*i)->get_state());
1030 node->add_child_nocopy (_tempo_map->get_state());
1032 node->add_child_nocopy (get_control_protocol_state());
1035 node->add_child_copy (*_extra_xml);
1042 Session::get_control_protocol_state ()
1044 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1045 return cpm.get_state();
1049 Session::set_state (const XMLNode& node)
1053 const XMLProperty* prop;
1056 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1058 if (node.name() != X_("Session")){
1059 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1063 if ((prop = node.property ("name")) != 0) {
1064 _name = prop->value ();
1067 setup_raid_path(_path);
1069 if ((prop = node.property (X_("id-counter"))) != 0) {
1071 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1072 ID::init_counter (x);
1074 /* old sessions used a timebased counter, so fake
1075 the startup ID counter based on a standard
1080 ID::init_counter (now);
1084 IO::disable_ports ();
1085 IO::disable_connecting ();
1087 /* Object loading order:
1105 if (use_config_midi_ports ()) {
1108 if ((child = find_named_node (node, "extra")) != 0) {
1109 _extra_xml = new XMLNode (*child);
1112 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1113 load_options (*child);
1114 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1115 load_options (*child);
1117 error << _("Session: XML state has no options section") << endmsg;
1120 if ((child = find_named_node (node, "Locations")) == 0) {
1121 error << _("Session: XML state has no locations section") << endmsg;
1123 } else if (_locations.set_state (*child)) {
1129 if ((location = _locations.auto_loop_location()) != 0) {
1130 set_auto_loop_location (location);
1133 if ((location = _locations.auto_punch_location()) != 0) {
1134 set_auto_punch_location (location);
1137 if ((location = _locations.end_location()) == 0) {
1138 _locations.add (end_location);
1140 delete end_location;
1141 end_location = location;
1144 if ((location = _locations.start_location()) == 0) {
1145 _locations.add (start_location);
1147 delete start_location;
1148 start_location = location;
1151 AudioFileSource::set_header_position_offset (start_location->start());
1153 if ((child = find_named_node (node, "Sources")) == 0) {
1154 error << _("Session: XML state has no sources section") << endmsg;
1156 } else if (load_sources (*child)) {
1160 if ((child = find_named_node (node, "Regions")) == 0) {
1161 error << _("Session: XML state has no Regions section") << endmsg;
1163 } else if (load_regions (*child)) {
1167 if ((child = find_named_node (node, "Playlists")) == 0) {
1168 error << _("Session: XML state has no playlists section") << endmsg;
1170 } else if (load_playlists (*child)) {
1174 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1176 } else if (load_unused_playlists (*child)) {
1180 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1181 if (load_named_selections (*child)) {
1186 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1187 error << _("Session: XML state has no diskstreams section") << endmsg;
1189 } else if (load_diskstreams (*child)) {
1193 if ((child = find_named_node (node, "Connections")) == 0) {
1194 error << _("Session: XML state has no connections section") << endmsg;
1196 } else if (load_bundles (*child)) {
1200 if ((child = find_named_node (node, "EditGroups")) == 0) {
1201 error << _("Session: XML state has no edit groups section") << endmsg;
1203 } else if (load_edit_groups (*child)) {
1207 if ((child = find_named_node (node, "MixGroups")) == 0) {
1208 error << _("Session: XML state has no mix groups section") << endmsg;
1210 } else if (load_mix_groups (*child)) {
1214 if ((child = find_named_node (node, "TempoMap")) == 0) {
1215 error << _("Session: XML state has no Tempo Map section") << endmsg;
1217 } else if (_tempo_map->set_state (*child)) {
1221 if ((child = find_named_node (node, "Routes")) == 0) {
1222 error << _("Session: XML state has no routes section") << endmsg;
1224 } else if (load_routes (*child)) {
1228 if ((child = find_named_node (node, "Click")) == 0) {
1229 warning << _("Session: XML state has no click section") << endmsg;
1230 } else if (_click_io) {
1231 _click_io->set_state (*child);
1234 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1235 ControlProtocolManager::instance().set_protocol_states (*child);
1238 /* here beginneth the second phase ... */
1240 StateReady (); /* EMIT SIGNAL */
1242 _state_of_the_state = Clean;
1244 if (state_was_pending) {
1245 save_state (_current_snapshot_name);
1246 remove_pending_capture_state ();
1247 state_was_pending = false;
1257 Session::load_routes (const XMLNode& node)
1260 XMLNodeConstIterator niter;
1261 RouteList new_routes;
1263 nlist = node.children();
1267 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1269 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1272 error << _("Session: cannot create Route from XML description.") << endmsg;
1276 new_routes.push_back (route);
1279 add_routes (new_routes);
1284 boost::shared_ptr<Route>
1285 Session::XMLRouteFactory (const XMLNode& node)
1287 if (node.name() != "Route") {
1288 return boost::shared_ptr<Route> ((Route*) 0);
1291 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1293 DataType type = DataType::AUDIO;
1294 const XMLProperty* prop = node.property("default-type");
1296 type = DataType(prop->value());
1298 assert(type != DataType::NIL);
1300 if (has_diskstream) {
1301 if (type == DataType::AUDIO) {
1302 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1305 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1309 boost::shared_ptr<Route> ret (new Route (*this, node));
1315 Session::load_regions (const XMLNode& node)
1318 XMLNodeConstIterator niter;
1319 boost::shared_ptr<Region> region;
1321 nlist = node.children();
1325 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1326 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1327 error << _("Session: cannot create Region from XML description.") << endmsg;
1334 boost::shared_ptr<Region>
1335 Session::XMLRegionFactory (const XMLNode& node, bool full)
1337 const XMLProperty* type = node.property("type");
1341 if ( !type || type->value() == "audio" ) {
1343 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1345 } else if (type->value() == "midi") {
1347 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1351 } catch (failed_constructor& err) {
1352 return boost::shared_ptr<Region> ();
1355 return boost::shared_ptr<Region> ();
1358 boost::shared_ptr<AudioRegion>
1359 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1361 const XMLProperty* prop;
1362 boost::shared_ptr<Source> source;
1363 boost::shared_ptr<AudioSource> as;
1365 uint32_t nchans = 1;
1368 if (node.name() != X_("Region")) {
1369 return boost::shared_ptr<AudioRegion>();
1372 if ((prop = node.property (X_("channels"))) != 0) {
1373 nchans = atoi (prop->value().c_str());
1376 if ((prop = node.property ("name")) == 0) {
1377 cerr << "no name for this region\n";
1381 if ((prop = node.property (X_("source-0"))) == 0) {
1382 if ((prop = node.property ("source")) == 0) {
1383 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1384 return boost::shared_ptr<AudioRegion>();
1388 PBD::ID s_id (prop->value());
1390 if ((source = source_by_id (s_id)) == 0) {
1391 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1392 return boost::shared_ptr<AudioRegion>();
1395 as = boost::dynamic_pointer_cast<AudioSource>(source);
1397 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1398 return boost::shared_ptr<AudioRegion>();
1401 sources.push_back (as);
1403 /* pickup other channels */
1405 for (uint32_t n=1; n < nchans; ++n) {
1406 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1407 if ((prop = node.property (buf)) != 0) {
1409 PBD::ID id2 (prop->value());
1411 if ((source = source_by_id (id2)) == 0) {
1412 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1413 return boost::shared_ptr<AudioRegion>();
1416 as = boost::dynamic_pointer_cast<AudioSource>(source);
1418 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1419 return boost::shared_ptr<AudioRegion>();
1421 sources.push_back (as);
1426 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1428 /* a final detail: this is the one and only place that we know how long missing files are */
1430 if (region->whole_file()) {
1431 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1432 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1434 sfp->set_length (region->length());
1443 catch (failed_constructor& err) {
1444 return boost::shared_ptr<AudioRegion>();
1448 boost::shared_ptr<MidiRegion>
1449 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1451 const XMLProperty* prop;
1452 boost::shared_ptr<Source> source;
1453 boost::shared_ptr<MidiSource> ms;
1455 uint32_t nchans = 1;
1457 if (node.name() != X_("Region")) {
1458 return boost::shared_ptr<MidiRegion>();
1461 if ((prop = node.property (X_("channels"))) != 0) {
1462 nchans = atoi (prop->value().c_str());
1465 if ((prop = node.property ("name")) == 0) {
1466 cerr << "no name for this region\n";
1470 // Multiple midi channels? that's just crazy talk
1471 assert(nchans == 1);
1473 if ((prop = node.property (X_("source-0"))) == 0) {
1474 if ((prop = node.property ("source")) == 0) {
1475 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1476 return boost::shared_ptr<MidiRegion>();
1480 PBD::ID s_id (prop->value());
1482 if ((source = source_by_id (s_id)) == 0) {
1483 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1484 return boost::shared_ptr<MidiRegion>();
1487 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1489 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1490 return boost::shared_ptr<MidiRegion>();
1493 sources.push_back (ms);
1496 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1497 /* a final detail: this is the one and only place that we know how long missing files are */
1499 if (region->whole_file()) {
1500 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1501 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1503 sfp->set_length (region->length());
1511 catch (failed_constructor& err) {
1512 return boost::shared_ptr<MidiRegion>();
1517 Session::get_sources_as_xml ()
1520 XMLNode* node = new XMLNode (X_("Sources"));
1521 Glib::Mutex::Lock lm (source_lock);
1523 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1524 node->add_child_nocopy (i->second->get_state());
1531 Session::path_from_region_name (DataType type, string name, string identifier)
1533 char buf[PATH_MAX+1];
1535 SessionDirectory sdir(get_best_session_directory_for_new_source());
1536 string sound_dir = ((type == DataType::AUDIO)
1537 ? sdir.sound_path().to_string()
1538 : sdir.midi_path().to_string());
1540 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1542 for (n = 0; n < 999999; ++n) {
1543 if (identifier.length()) {
1544 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1545 identifier.c_str(), n, ext.c_str());
1547 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1551 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1556 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1565 Session::load_sources (const XMLNode& node)
1568 XMLNodeConstIterator niter;
1569 boost::shared_ptr<Source> source;
1571 nlist = node.children();
1575 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1578 if ((source = XMLSourceFactory (**niter)) == 0) {
1579 error << _("Session: cannot create Source from XML description.") << endmsg;
1583 catch (non_existent_source& err) {
1584 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1585 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1592 boost::shared_ptr<Source>
1593 Session::XMLSourceFactory (const XMLNode& node)
1595 if (node.name() != "Source") {
1596 return boost::shared_ptr<Source>();
1600 return SourceFactory::create (*this, node);
1603 catch (failed_constructor& err) {
1604 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1605 return boost::shared_ptr<Source>();
1610 Session::save_template (string template_name)
1613 string xml_path, bak_path, template_path;
1615 if (_state_of_the_state & CannotSave) {
1619 sys::path user_template_dir(user_template_directory());
1623 sys::create_directories (user_template_dir);
1625 catch(sys::filesystem_error& ex)
1627 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1628 user_template_dir.to_string(), ex.what()) << endmsg;
1632 tree.set_root (&get_template());
1634 sys::path template_file_path(user_template_dir);
1635 template_file_path /= template_name + template_suffix;
1637 if (sys::exists (template_file_path))
1639 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1640 template_file_path.to_string()) << endmsg;
1644 if (!tree.write (template_file_path.to_string())) {
1645 error << _("mix template not saved") << endmsg;
1653 Session::refresh_disk_space ()
1656 struct statfs statfsbuf;
1657 vector<space_and_path>::iterator i;
1658 Glib::Mutex::Lock lm (space_lock);
1661 /* get freespace on every FS that is part of the session path */
1663 _total_free_4k_blocks = 0;
1665 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1666 statfs ((*i).path.c_str(), &statfsbuf);
1668 scale = statfsbuf.f_bsize/4096.0;
1670 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1671 _total_free_4k_blocks += (*i).blocks;
1677 Session::get_best_session_directory_for_new_source ()
1679 vector<space_and_path>::iterator i;
1680 string result = _session_dir->root_path().to_string();
1682 /* handle common case without system calls */
1684 if (session_dirs.size() == 1) {
1688 /* OK, here's the algorithm we're following here:
1690 We want to select which directory to use for
1691 the next file source to be created. Ideally,
1692 we'd like to use a round-robin process so as to
1693 get maximum performance benefits from splitting
1694 the files across multiple disks.
1696 However, in situations without much diskspace, an
1697 RR approach may end up filling up a filesystem
1698 with new files while others still have space.
1699 Its therefore important to pay some attention to
1700 the freespace in the filesystem holding each
1701 directory as well. However, if we did that by
1702 itself, we'd keep creating new files in the file
1703 system with the most space until it was as full
1704 as all others, thus negating any performance
1705 benefits of this RAID-1 like approach.
1707 So, we use a user-configurable space threshold. If
1708 there are at least 2 filesystems with more than this
1709 much space available, we use RR selection between them.
1710 If not, then we pick the filesystem with the most space.
1712 This gets a good balance between the two
1716 refresh_disk_space ();
1718 int free_enough = 0;
1720 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1721 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1726 if (free_enough >= 2) {
1727 /* use RR selection process, ensuring that the one
1731 i = last_rr_session_dir;
1734 if (++i == session_dirs.end()) {
1735 i = session_dirs.begin();
1738 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1739 if (create_session_directory ((*i).path)) {
1741 last_rr_session_dir = i;
1746 } while (i != last_rr_session_dir);
1750 /* pick FS with the most freespace (and that
1751 seems to actually work ...)
1754 vector<space_and_path> sorted;
1755 space_and_path_ascending_cmp cmp;
1757 sorted = session_dirs;
1758 sort (sorted.begin(), sorted.end(), cmp);
1760 for (i = sorted.begin(); i != sorted.end(); ++i) {
1761 if (create_session_directory ((*i).path)) {
1763 last_rr_session_dir = i;
1773 Session::load_playlists (const XMLNode& node)
1776 XMLNodeConstIterator niter;
1777 boost::shared_ptr<Playlist> playlist;
1779 nlist = node.children();
1783 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1785 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1786 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1794 Session::load_unused_playlists (const XMLNode& node)
1797 XMLNodeConstIterator niter;
1798 boost::shared_ptr<Playlist> playlist;
1800 nlist = node.children();
1804 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1806 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1807 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1811 // now manually untrack it
1813 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1819 boost::shared_ptr<Playlist>
1820 Session::XMLPlaylistFactory (const XMLNode& node)
1823 return PlaylistFactory::create (*this, node);
1826 catch (failed_constructor& err) {
1827 return boost::shared_ptr<Playlist>();
1832 Session::load_named_selections (const XMLNode& node)
1835 XMLNodeConstIterator niter;
1838 nlist = node.children();
1842 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1844 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1845 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1853 Session::XMLNamedSelectionFactory (const XMLNode& node)
1856 return new NamedSelection (*this, node);
1859 catch (failed_constructor& err) {
1865 Session::automation_dir () const
1868 res += "automation/";
1873 Session::load_bundles (const XMLNode& node)
1875 XMLNodeList nlist = node.children();
1876 XMLNodeConstIterator niter;
1880 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1881 if ((*niter)->name() == "InputConnection") {
1882 add_bundle (new ARDOUR::InputBundle (**niter));
1883 } else if ((*niter)->name() == "OutputConnection") {
1884 add_bundle (new ARDOUR::OutputBundle (**niter));
1886 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1895 Session::load_edit_groups (const XMLNode& node)
1897 return load_route_groups (node, true);
1901 Session::load_mix_groups (const XMLNode& node)
1903 return load_route_groups (node, false);
1907 Session::load_route_groups (const XMLNode& node, bool edit)
1909 XMLNodeList nlist = node.children();
1910 XMLNodeConstIterator niter;
1915 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1916 if ((*niter)->name() == "RouteGroup") {
1918 rg = add_edit_group ("");
1919 rg->set_state (**niter);
1921 rg = add_mix_group ("");
1922 rg->set_state (**niter);
1931 state_file_filter (const string &str, void *arg)
1933 return (str.length() > strlen(statefile_suffix) &&
1934 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
1938 bool operator()(const string* a, const string* b) {
1944 remove_end(string* state)
1946 string statename(*state);
1948 string::size_type start,end;
1949 if ((start = statename.find_last_of ('/')) != string::npos) {
1950 statename = statename.substr (start+1);
1953 if ((end = statename.rfind(".ardour")) == string::npos) {
1954 end = statename.length();
1957 return new string(statename.substr (0, end));
1961 Session::possible_states (string path)
1963 PathScanner scanner;
1964 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
1966 transform(states->begin(), states->end(), states->begin(), remove_end);
1969 sort (states->begin(), states->end(), cmp);
1975 Session::possible_states () const
1977 return possible_states(_path);
1981 Session::auto_save()
1983 save_state (_current_snapshot_name);
1987 Session::add_edit_group (string name)
1989 RouteGroup* rg = new RouteGroup (*this, name);
1990 edit_groups.push_back (rg);
1991 edit_group_added (rg); /* EMIT SIGNAL */
1997 Session::add_mix_group (string name)
1999 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2000 mix_groups.push_back (rg);
2001 mix_group_added (rg); /* EMIT SIGNAL */
2007 Session::remove_edit_group (RouteGroup& rg)
2009 list<RouteGroup*>::iterator i;
2011 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2012 (*i)->apply (&Route::drop_edit_group, this);
2013 edit_groups.erase (i);
2014 edit_group_removed (); /* EMIT SIGNAL */
2021 Session::remove_mix_group (RouteGroup& rg)
2023 list<RouteGroup*>::iterator i;
2025 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2026 (*i)->apply (&Route::drop_mix_group, this);
2027 mix_groups.erase (i);
2028 mix_group_removed (); /* EMIT SIGNAL */
2035 Session::mix_group_by_name (string name)
2037 list<RouteGroup *>::iterator i;
2039 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2040 if ((*i)->name() == name) {
2048 Session::edit_group_by_name (string name)
2050 list<RouteGroup *>::iterator i;
2052 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2053 if ((*i)->name() == name) {
2061 Session::begin_reversible_command (const string& name)
2063 current_trans = new UndoTransaction;
2064 current_trans->set_name (name);
2068 Session::commit_reversible_command (Command *cmd)
2073 current_trans->add_command (cmd);
2076 gettimeofday (&now, 0);
2077 current_trans->set_timestamp (now);
2079 _history.add (current_trans);
2082 Session::GlobalRouteBooleanState
2083 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2085 GlobalRouteBooleanState s;
2086 boost::shared_ptr<RouteList> r = routes.reader ();
2088 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2089 if (!(*i)->is_hidden()) {
2090 RouteBooleanState v;
2093 Route* r = (*i).get();
2094 v.second = (r->*method)();
2103 Session::GlobalRouteMeterState
2104 Session::get_global_route_metering ()
2106 GlobalRouteMeterState s;
2107 boost::shared_ptr<RouteList> r = routes.reader ();
2109 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2110 if (!(*i)->is_hidden()) {
2114 v.second = (*i)->meter_point();
2124 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2126 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2128 boost::shared_ptr<Route> r = (i->first.lock());
2131 r->set_meter_point (i->second, arg);
2137 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2139 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2141 boost::shared_ptr<Route> r = (i->first.lock());
2144 Route* rp = r.get();
2145 (rp->*method) (i->second, arg);
2151 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2153 set_global_route_boolean (s, &Route::set_mute, src);
2157 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2159 set_global_route_boolean (s, &Route::set_solo, src);
2163 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2165 set_global_route_boolean (s, &Route::set_record_enable, src);
2170 Session::global_mute_memento (void* src)
2172 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2176 Session::global_metering_memento (void* src)
2178 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2182 Session::global_solo_memento (void* src)
2184 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2188 Session::global_record_enable_memento (void* src)
2190 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2195 accept_all_non_peak_files (const string& path, void *arg)
2197 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2201 accept_all_state_files (const string& path, void *arg)
2203 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2207 Session::find_all_sources (string path, set<string>& result)
2212 if (!tree.read (path)) {
2216 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2221 XMLNodeConstIterator niter;
2223 nlist = node->children();
2227 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2231 if ((prop = (*niter)->property (X_("name"))) == 0) {
2235 if (prop->value()[0] == '/') {
2236 /* external file, ignore */
2240 sys::path source_path = _session_dir->sound_path ();
2242 source_path /= prop->value ();
2244 result.insert (source_path.to_string ());
2251 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2253 PathScanner scanner;
2254 vector<string*>* state_files;
2256 string this_snapshot_path;
2262 if (ripped[ripped.length()-1] == '/') {
2263 ripped = ripped.substr (0, ripped.length() - 1);
2266 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2268 if (state_files == 0) {
2273 this_snapshot_path = _path;
2274 this_snapshot_path += _current_snapshot_name;
2275 this_snapshot_path += statefile_suffix;
2277 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2279 if (exclude_this_snapshot && **i == this_snapshot_path) {
2283 if (find_all_sources (**i, result) < 0) {
2291 struct RegionCounter {
2292 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2293 AudioSourceList::iterator iter;
2294 boost::shared_ptr<Region> region;
2297 RegionCounter() : count (0) {}
2301 Session::cleanup_sources (Session::cleanup_report& rep)
2303 // FIXME: needs adaptation to midi
2305 vector<boost::shared_ptr<Source> > dead_sources;
2306 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2307 PathScanner scanner;
2309 vector<space_and_path>::iterator i;
2310 vector<space_and_path>::iterator nexti;
2311 vector<string*>* soundfiles;
2312 vector<string> unused;
2313 set<string> all_sources;
2318 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2320 /* step 1: consider deleting all unused playlists */
2322 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2325 status = AskAboutPlaylistDeletion (*x);
2334 playlists_tbd.push_back (*x);
2338 /* leave it alone */
2343 /* now delete any that were marked for deletion */
2345 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2346 (*x)->drop_references ();
2349 playlists_tbd.clear ();
2351 /* step 2: find all un-used sources */
2356 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2358 SourceMap::iterator tmp;
2363 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2367 if (!i->second->used() && i->second->length() > 0) {
2368 dead_sources.push_back (i->second);
2369 i->second->GoingAway();
2375 /* build a list of all the possible sound directories for the session */
2377 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2382 SessionDirectory sdir ((*i).path);
2383 sound_path += sdir.sound_path().to_string();
2385 if (nexti != session_dirs.end()) {
2392 /* now do the same thing for the files that ended up in the sounds dir(s)
2393 but are not referenced as sources in any snapshot.
2396 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2398 if (soundfiles == 0) {
2402 /* find all sources, but don't use this snapshot because the
2403 state file on disk still references sources we may have already
2407 find_all_sources_across_snapshots (all_sources, true);
2409 /* add our current source list
2412 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2413 boost::shared_ptr<AudioFileSource> fs;
2415 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2416 all_sources.insert (fs->path());
2420 char tmppath1[PATH_MAX+1];
2421 char tmppath2[PATH_MAX+1];
2423 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2428 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2430 realpath(spath.c_str(), tmppath1);
2431 realpath((*i).c_str(), tmppath2);
2433 if (strcmp(tmppath1, tmppath2) == 0) {
2440 unused.push_back (spath);
2444 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2446 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2447 struct stat statbuf;
2449 rep.paths.push_back (*x);
2450 if (stat ((*x).c_str(), &statbuf) == 0) {
2451 rep.space += statbuf.st_size;
2456 /* don't move the file across filesystems, just
2457 stick it in the `dead_sound_dir_name' directory
2458 on whichever filesystem it was already on.
2461 if ((*x).find ("/sounds/") != string::npos) {
2463 /* old school, go up 1 level */
2465 newpath = Glib::path_get_dirname (*x); // "sounds"
2466 newpath = Glib::path_get_dirname (newpath); // "session-name"
2470 /* new school, go up 4 levels */
2472 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2473 newpath = Glib::path_get_dirname (newpath); // "session-name"
2474 newpath = Glib::path_get_dirname (newpath); // "interchange"
2475 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2479 newpath += dead_sound_dir_name;
2481 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2482 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2487 newpath += Glib::path_get_basename ((*x));
2489 if (access (newpath.c_str(), F_OK) == 0) {
2491 /* the new path already exists, try versioning */
2493 char buf[PATH_MAX+1];
2497 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2500 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2501 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2505 if (version == 999) {
2506 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2510 newpath = newpath_v;
2515 /* it doesn't exist, or we can't read it or something */
2519 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2520 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2521 (*x), newpath, strerror (errno))
2526 /* see if there an easy to find peakfile for this file, and remove it.
2529 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2530 peakpath += peakfile_suffix;
2532 if (access (peakpath.c_str(), W_OK) == 0) {
2533 if (::unlink (peakpath.c_str()) != 0) {
2534 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2535 peakpath, _path, strerror (errno))
2537 /* try to back out */
2538 rename (newpath.c_str(), _path.c_str());
2546 /* dump the history list */
2550 /* save state so we don't end up a session file
2551 referring to non-existent sources.
2557 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2562 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2564 // FIXME: needs adaptation for MIDI
2566 vector<space_and_path>::iterator i;
2567 string dead_sound_dir;
2568 struct dirent* dentry;
2569 struct stat statbuf;
2575 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2577 dead_sound_dir = (*i).path;
2578 dead_sound_dir += dead_sound_dir_name;
2580 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2584 while ((dentry = readdir (dead)) != 0) {
2586 /* avoid '.' and '..' */
2588 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2589 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2595 fullpath = dead_sound_dir;
2597 fullpath += dentry->d_name;
2599 if (stat (fullpath.c_str(), &statbuf)) {
2603 if (!S_ISREG (statbuf.st_mode)) {
2607 if (unlink (fullpath.c_str())) {
2608 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2609 fullpath, strerror (errno))
2613 rep.paths.push_back (dentry->d_name);
2614 rep.space += statbuf.st_size;
2625 Session::set_dirty ()
2627 bool was_dirty = dirty();
2629 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2632 DirtyChanged(); /* EMIT SIGNAL */
2638 Session::set_clean ()
2640 bool was_dirty = dirty();
2642 _state_of_the_state = Clean;
2645 DirtyChanged(); /* EMIT SIGNAL */
2650 Session::set_deletion_in_progress ()
2652 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2656 Session::add_controllable (boost::shared_ptr<Controllable> c)
2658 /* this adds a controllable to the list managed by the Session.
2659 this is a subset of those managed by the Controllable class
2660 itself, and represents the only ones whose state will be saved
2661 as part of the session.
2664 Glib::Mutex::Lock lm (controllables_lock);
2665 controllables.insert (c);
2668 struct null_deleter { void operator()(void const *) const {} };
2671 Session::remove_controllable (Controllable* c)
2673 if (_state_of_the_state | Deletion) {
2677 Glib::Mutex::Lock lm (controllables_lock);
2679 Controllables::iterator x = controllables.find(
2680 boost::shared_ptr<Controllable>(c, null_deleter()));
2682 if (x != controllables.end()) {
2683 controllables.erase (x);
2687 boost::shared_ptr<Controllable>
2688 Session::controllable_by_id (const PBD::ID& id)
2690 Glib::Mutex::Lock lm (controllables_lock);
2692 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2693 if ((*i)->id() == id) {
2698 return boost::shared_ptr<Controllable>();
2702 Session::add_instant_xml (XMLNode& node)
2704 Stateful::add_instant_xml (node, _path);
2705 Config->add_instant_xml (node);
2709 Session::instant_xml (const string& node_name)
2711 return Stateful::instant_xml (node_name, _path);
2715 Session::save_history (string snapshot_name)
2721 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2723 if (snapshot_name.empty()) {
2724 snapshot_name = _current_snapshot_name;
2727 xml_path = _path + snapshot_name + ".history";
2729 bak_path = xml_path + ".bak";
2731 if ((access (xml_path.c_str(), F_OK) == 0) &&
2732 (rename (xml_path.c_str(), bak_path.c_str())))
2734 error << _("could not backup old history file, current history not saved.") << endmsg;
2738 if (!tree.write (xml_path))
2740 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2742 /* don't leave a corrupt file lying around if it is
2746 if (unlink (xml_path.c_str())) {
2747 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2749 if (rename (bak_path.c_str(), xml_path.c_str()))
2751 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2762 Session::restore_history (string snapshot_name)
2767 if (snapshot_name.empty()) {
2768 snapshot_name = _current_snapshot_name;
2772 xmlpath = _path + snapshot_name + ".history";
2773 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2775 if (access (xmlpath.c_str(), F_OK)) {
2776 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2780 if (!tree.read (xmlpath)) {
2781 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2785 /* replace history */
2788 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2791 UndoTransaction* ut = new UndoTransaction ();
2794 ut->set_name(t->property("name")->value());
2795 stringstream ss(t->property("tv_sec")->value());
2797 ss.str(t->property("tv_usec")->value());
2799 ut->set_timestamp(tv);
2801 for (XMLNodeConstIterator child_it = t->children().begin();
2802 child_it != t->children().end();
2805 XMLNode *n = *child_it;
2808 if (n->name() == "MementoCommand" ||
2809 n->name() == "MementoUndoCommand" ||
2810 n->name() == "MementoRedoCommand") {
2812 if ((c = memento_command_factory(n))) {
2816 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2818 if ((c = global_state_command_factory (*n))) {
2819 ut->add_command (c);
2824 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2835 Session::config_changed (const char* parameter_name)
2837 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2839 if (PARAM_IS ("seamless-loop")) {
2841 } else if (PARAM_IS ("rf-speed")) {
2843 } else if (PARAM_IS ("auto-loop")) {
2845 } else if (PARAM_IS ("auto-input")) {
2847 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2848 /* auto-input only makes a difference if we're rolling */
2850 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2852 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2853 if ((*i)->record_enabled ()) {
2854 (*i)->monitor_input (!Config->get_auto_input());
2859 } else if (PARAM_IS ("punch-in")) {
2863 if ((location = _locations.auto_punch_location()) != 0) {
2865 if (Config->get_punch_in ()) {
2866 replace_event (Event::PunchIn, location->start());
2868 remove_event (location->start(), Event::PunchIn);
2872 } else if (PARAM_IS ("punch-out")) {
2876 if ((location = _locations.auto_punch_location()) != 0) {
2878 if (Config->get_punch_out()) {
2879 replace_event (Event::PunchOut, location->end());
2881 clear_events (Event::PunchOut);
2885 } else if (PARAM_IS ("edit-mode")) {
2887 Glib::Mutex::Lock lm (playlist_lock);
2889 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2890 (*i)->set_edit_mode (Config->get_edit_mode ());
2893 } else if (PARAM_IS ("use-video-sync")) {
2895 waiting_for_sync_offset = Config->get_use_video_sync();
2897 } else if (PARAM_IS ("mmc-control")) {
2899 //poke_midi_thread ();
2901 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
2904 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
2907 } else if (PARAM_IS ("mmc-send-id")) {
2910 mmc->set_send_device_id (Config->get_mmc_send_device_id());
2913 } else if (PARAM_IS ("midi-control")) {
2915 //poke_midi_thread ();
2917 } else if (PARAM_IS ("raid-path")) {
2919 setup_raid_path (Config->get_raid_path());
2921 } else if (PARAM_IS ("smpte-format")) {
2925 } else if (PARAM_IS ("video-pullup")) {
2929 } else if (PARAM_IS ("seamless-loop")) {
2931 if (play_loop && transport_rolling()) {
2932 // to reset diskstreams etc
2933 request_play_loop (true);
2936 } else if (PARAM_IS ("rf-speed")) {
2938 cumulative_rf_motion = 0;
2941 } else if (PARAM_IS ("click-sound")) {
2943 setup_click_sounds (1);
2945 } else if (PARAM_IS ("click-emphasis-sound")) {
2947 setup_click_sounds (-1);
2949 } else if (PARAM_IS ("clicking")) {
2951 if (Config->get_clicking()) {
2952 if (_click_io && click_data) { // don't require emphasis data
2959 } else if (PARAM_IS ("send-mtc")) {
2961 /* only set the internal flag if we have
2965 if (_mtc_port != 0) {
2966 session_send_mtc = Config->get_send_mtc();
2967 if (session_send_mtc) {
2968 /* mark us ready to send */
2969 next_quarter_frame_to_send = 0;
2972 session_send_mtc = false;
2975 } else if (PARAM_IS ("send-mmc")) {
2977 /* only set the internal flag if we have
2981 if (_mmc_port != 0) {
2982 session_send_mmc = Config->get_send_mmc();
2985 session_send_mmc = false;
2988 } else if (PARAM_IS ("midi-feedback")) {
2990 /* only set the internal flag if we have
2994 if (_mtc_port != 0) {
2995 session_midi_feedback = Config->get_midi_feedback();
2998 } else if (PARAM_IS ("jack-time-master")) {
3000 engine().reset_timebase ();
3002 } else if (PARAM_IS ("native-file-header-format")) {
3004 if (!first_file_header_format_reset) {
3005 reset_native_file_format ();
3008 first_file_header_format_reset = false;
3010 } else if (PARAM_IS ("native-file-data-format")) {
3012 if (!first_file_data_format_reset) {
3013 reset_native_file_format ();
3016 first_file_data_format_reset = false;
3018 } else if (PARAM_IS ("slave-source")) {
3019 set_slave_source (Config->get_slave_source());
3020 } else if (PARAM_IS ("remote-model")) {
3021 set_remote_control_ids ();
3022 } else if (PARAM_IS ("denormal-model")) {