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.get_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.get_string ());
410 SMFSource::set_search_path (midi_search_path.get_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 string out_path = _path + _name + statefile_suffix;
444 if(!copy_file (template_path, out_path)) {
445 error << string_compose (_("Could not use session template %1 to create new session."), template_path)
453 Session::load_diskstreams (const XMLNode& node)
456 XMLNodeConstIterator citer;
458 clist = node.children();
460 for (citer = clist.begin(); citer != clist.end(); ++citer) {
463 /* diskstreams added automatically by DiskstreamCreated handler */
464 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
465 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
466 add_diskstream (dstream);
467 } else if ((*citer)->name() == "MidiDiskstream") {
468 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
469 add_diskstream (dstream);
471 error << _("Session: unknown diskstream type in XML") << endmsg;
475 catch (failed_constructor& err) {
476 error << _("Session: could not load diskstream via XML state") << endmsg;
485 Session::maybe_write_autosave()
487 if (dirty() && record_status() != Recording) {
488 save_state("", true);
493 Session::remove_pending_capture_state ()
498 xml_path += _current_snapshot_name;
499 xml_path += pending_suffix;
501 unlink (xml_path.c_str());
504 /** Rename a state file.
505 * @param snapshot_name Snapshot name.
508 Session::rename_state (string old_name, string new_name)
510 if (old_name == _current_snapshot_name || old_name == _name) {
511 /* refuse to rename the current snapshot or the "main" one */
515 const string old_xml_path = _path + old_name + statefile_suffix;
516 const string new_xml_path = _path + new_name + statefile_suffix;
518 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
519 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
523 /** Remove a state file.
524 * @param snapshot_name Snapshot name.
527 Session::remove_state (string snapshot_name)
529 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
530 /* refuse to remove the current snapshot or the "main" one */
534 const string xml_path = _path + snapshot_name + statefile_suffix;
536 /* make a backup copy of the state file */
537 const string bak_path = xml_path + ".bak";
538 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
539 copy_file (xml_path, bak_path);
543 unlink (xml_path.c_str());
547 Session::save_state (string snapshot_name, bool pending)
553 if (_state_of_the_state & CannotSave) {
557 if (!_engine.connected ()) {
558 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
563 tree.set_root (&get_state());
565 if (snapshot_name.empty()) {
566 snapshot_name = _current_snapshot_name;
571 /* proper save: use statefile_suffix (.ardour in English) */
573 xml_path += snapshot_name;
574 xml_path += statefile_suffix;
576 /* make a backup copy of the old file */
580 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
581 copy_file (xml_path, bak_path);
586 /* pending save: use pending_suffix (.pending in English) */
588 xml_path += snapshot_name;
589 xml_path += pending_suffix;
596 tmp_path += snapshot_name;
599 // cerr << "actually writing state to " << xml_path << endl;
601 if (!tree.write (tmp_path)) {
602 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
603 unlink (tmp_path.c_str());
608 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
609 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
610 unlink (tmp_path.c_str());
617 save_history (snapshot_name);
619 bool was_dirty = dirty();
621 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
624 DirtyChanged (); /* EMIT SIGNAL */
627 StateSaved (snapshot_name); /* EMIT SIGNAL */
634 Session::restore_state (string snapshot_name)
636 if (load_state (snapshot_name) == 0) {
637 set_state (*state_tree->root());
644 Session::load_state (string snapshot_name)
653 state_was_pending = false;
655 /* check for leftover pending state from a crashed capture attempt */
658 xmlpath += snapshot_name;
659 xmlpath += pending_suffix;
661 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
663 /* there is pending state from a crashed capture attempt */
665 if (AskAboutPendingState()) {
666 state_was_pending = true;
670 if (!state_was_pending) {
673 xmlpath += snapshot_name;
674 xmlpath += statefile_suffix;
677 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
678 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
682 state_tree = new XMLTree;
686 if (!state_tree->read (xmlpath)) {
687 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
693 XMLNode& root (*state_tree->root());
695 if (root.name() != X_("Session")) {
696 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
702 const XMLProperty* prop;
705 if ((prop = root.property ("version")) == 0) {
706 /* no version implies very old version of Ardour */
710 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
711 if (major_version < 2) {
720 backup_path += snapshot_name;
722 backup_path += statefile_suffix;
724 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
725 xmlpath, backup_path)
728 copy_file (xmlpath, backup_path);
730 /* if it fails, don't worry. right? */
737 Session::load_options (const XMLNode& node)
741 LocaleGuard lg (X_("POSIX"));
743 Config->set_variables (node, ConfigVariableBase::Session);
745 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
746 if ((prop = child->property ("val")) != 0) {
747 _end_location_is_free = (prop->value() == "yes");
755 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
757 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
758 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
760 return owner & modified_by_session_or_user;
764 Session::get_options () const
767 LocaleGuard lg (X_("POSIX"));
769 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
771 child = option_root.add_child ("end-marker-is-free");
772 child->add_property ("val", _end_location_is_free ? "yes" : "no");
784 Session::get_template()
786 /* if we don't disable rec-enable, diskstreams
787 will believe they need to store their capture
788 sources in their state node.
791 disable_record (false);
797 Session::state(bool full_state)
799 XMLNode* node = new XMLNode("Session");
802 // store libardour version, just in case
804 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
805 libardour_major_version, libardour_minor_version, libardour_micro_version);
806 node->add_property("version", string(buf));
808 /* store configuration settings */
813 node->add_property ("name", _name);
815 if (session_dirs.size() > 1) {
819 vector<space_and_path>::iterator i = session_dirs.begin();
820 vector<space_and_path>::iterator next;
822 ++i; /* skip the first one */
826 while (i != session_dirs.end()) {
830 if (next != session_dirs.end()) {
840 child = node->add_child ("Path");
841 child->add_content (p);
845 /* save the ID counter */
847 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
848 node->add_property ("id-counter", buf);
850 /* various options */
852 node->add_child_nocopy (get_options());
854 child = node->add_child ("Sources");
857 Glib::Mutex::Lock sl (source_lock);
859 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
861 /* Don't save information about AudioFileSources that are empty */
863 boost::shared_ptr<AudioFileSource> fs;
865 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
867 /* Don't save sources that are empty, unless they're destructive (which are OK
868 if they are empty, because we will re-use them every time.)
871 if (!fs->destructive()) {
872 if (fs->length() == 0) {
878 child->add_child_nocopy (siter->second->get_state());
882 child = node->add_child ("Regions");
885 Glib::Mutex::Lock rl (region_lock);
887 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
889 /* only store regions not attached to playlists */
891 if (i->second->playlist() == 0) {
892 child->add_child_nocopy (i->second->state (true));
897 child = node->add_child ("DiskStreams");
900 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
901 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
902 if (!(*i)->hidden()) {
903 child->add_child_nocopy ((*i)->get_state());
909 node->add_child_nocopy (_locations.get_state());
911 // for a template, just create a new Locations, populate it
912 // with the default start and end, and get the state for that.
914 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
915 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
918 end->set_end(compute_initial_length());
920 node->add_child_nocopy (loc.get_state());
923 child = node->add_child ("Connections");
925 Glib::Mutex::Lock lm (bundle_lock);
926 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
927 if (!(*i)->dynamic()) {
928 child->add_child_nocopy ((*i)->get_state());
933 child = node->add_child ("Routes");
935 boost::shared_ptr<RouteList> r = routes.reader ();
937 RoutePublicOrderSorter cmp;
938 RouteList public_order (*r);
939 public_order.sort (cmp);
941 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
942 if (!(*i)->is_hidden()) {
944 child->add_child_nocopy ((*i)->get_state());
946 child->add_child_nocopy ((*i)->get_template());
953 child = node->add_child ("EditGroups");
954 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
955 child->add_child_nocopy ((*i)->get_state());
958 child = node->add_child ("MixGroups");
959 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
960 child->add_child_nocopy ((*i)->get_state());
963 child = node->add_child ("Playlists");
964 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
965 if (!(*i)->hidden()) {
966 if (!(*i)->empty()) {
968 child->add_child_nocopy ((*i)->get_state());
970 child->add_child_nocopy ((*i)->get_template());
976 child = node->add_child ("UnusedPlaylists");
977 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
978 if (!(*i)->hidden()) {
979 if (!(*i)->empty()) {
981 child->add_child_nocopy ((*i)->get_state());
983 child->add_child_nocopy ((*i)->get_template());
991 child = node->add_child ("Click");
992 child->add_child_nocopy (_click_io->state (full_state));
996 child = node->add_child ("NamedSelections");
997 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
999 child->add_child_nocopy ((*i)->get_state());
1004 node->add_child_nocopy (_tempo_map->get_state());
1006 node->add_child_nocopy (get_control_protocol_state());
1009 node->add_child_copy (*_extra_xml);
1016 Session::get_control_protocol_state ()
1018 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1019 return cpm.get_state();
1023 Session::set_state (const XMLNode& node)
1027 const XMLProperty* prop;
1030 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1032 if (node.name() != X_("Session")){
1033 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1037 if ((prop = node.property ("name")) != 0) {
1038 _name = prop->value ();
1041 setup_raid_path(_path);
1043 if ((prop = node.property (X_("id-counter"))) != 0) {
1045 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1046 ID::init_counter (x);
1048 /* old sessions used a timebased counter, so fake
1049 the startup ID counter based on a standard
1054 ID::init_counter (now);
1058 IO::disable_ports ();
1059 IO::disable_connecting ();
1061 /* Object loading order:
1079 if (use_config_midi_ports ()) {
1082 if ((child = find_named_node (node, "extra")) != 0) {
1083 _extra_xml = new XMLNode (*child);
1086 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1087 load_options (*child);
1088 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1089 load_options (*child);
1091 error << _("Session: XML state has no options section") << endmsg;
1094 if ((child = find_named_node (node, "Locations")) == 0) {
1095 error << _("Session: XML state has no locations section") << endmsg;
1097 } else if (_locations.set_state (*child)) {
1103 if ((location = _locations.auto_loop_location()) != 0) {
1104 set_auto_loop_location (location);
1107 if ((location = _locations.auto_punch_location()) != 0) {
1108 set_auto_punch_location (location);
1111 if ((location = _locations.end_location()) == 0) {
1112 _locations.add (end_location);
1114 delete end_location;
1115 end_location = location;
1118 if ((location = _locations.start_location()) == 0) {
1119 _locations.add (start_location);
1121 delete start_location;
1122 start_location = location;
1125 AudioFileSource::set_header_position_offset (start_location->start());
1127 if ((child = find_named_node (node, "Sources")) == 0) {
1128 error << _("Session: XML state has no sources section") << endmsg;
1130 } else if (load_sources (*child)) {
1134 if ((child = find_named_node (node, "Regions")) == 0) {
1135 error << _("Session: XML state has no Regions section") << endmsg;
1137 } else if (load_regions (*child)) {
1141 if ((child = find_named_node (node, "Playlists")) == 0) {
1142 error << _("Session: XML state has no playlists section") << endmsg;
1144 } else if (load_playlists (*child)) {
1148 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1150 } else if (load_unused_playlists (*child)) {
1154 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1155 if (load_named_selections (*child)) {
1160 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1161 error << _("Session: XML state has no diskstreams section") << endmsg;
1163 } else if (load_diskstreams (*child)) {
1167 if ((child = find_named_node (node, "Connections")) == 0) {
1168 error << _("Session: XML state has no connections section") << endmsg;
1170 } else if (load_bundles (*child)) {
1174 if ((child = find_named_node (node, "EditGroups")) == 0) {
1175 error << _("Session: XML state has no edit groups section") << endmsg;
1177 } else if (load_edit_groups (*child)) {
1181 if ((child = find_named_node (node, "MixGroups")) == 0) {
1182 error << _("Session: XML state has no mix groups section") << endmsg;
1184 } else if (load_mix_groups (*child)) {
1188 if ((child = find_named_node (node, "TempoMap")) == 0) {
1189 error << _("Session: XML state has no Tempo Map section") << endmsg;
1191 } else if (_tempo_map->set_state (*child)) {
1195 if ((child = find_named_node (node, "Routes")) == 0) {
1196 error << _("Session: XML state has no routes section") << endmsg;
1198 } else if (load_routes (*child)) {
1202 if ((child = find_named_node (node, "Click")) == 0) {
1203 warning << _("Session: XML state has no click section") << endmsg;
1204 } else if (_click_io) {
1205 _click_io->set_state (*child);
1208 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1209 ControlProtocolManager::instance().set_protocol_states (*child);
1212 /* here beginneth the second phase ... */
1214 StateReady (); /* EMIT SIGNAL */
1216 _state_of_the_state = Clean;
1218 if (state_was_pending) {
1219 save_state (_current_snapshot_name);
1220 remove_pending_capture_state ();
1221 state_was_pending = false;
1231 Session::load_routes (const XMLNode& node)
1234 XMLNodeConstIterator niter;
1235 RouteList new_routes;
1237 nlist = node.children();
1241 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1243 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1246 error << _("Session: cannot create Route from XML description.") << endmsg;
1250 new_routes.push_back (route);
1253 add_routes (new_routes);
1258 boost::shared_ptr<Route>
1259 Session::XMLRouteFactory (const XMLNode& node)
1261 if (node.name() != "Route") {
1262 return boost::shared_ptr<Route> ((Route*) 0);
1265 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1267 DataType type = DataType::AUDIO;
1268 const XMLProperty* prop = node.property("default-type");
1270 type = DataType(prop->value());
1272 assert(type != DataType::NIL);
1274 if (has_diskstream) {
1275 if (type == DataType::AUDIO) {
1276 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1279 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1283 boost::shared_ptr<Route> ret (new Route (*this, node));
1289 Session::load_regions (const XMLNode& node)
1292 XMLNodeConstIterator niter;
1293 boost::shared_ptr<Region> region;
1295 nlist = node.children();
1299 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1300 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1301 error << _("Session: cannot create Region from XML description.") << endmsg;
1308 boost::shared_ptr<Region>
1309 Session::XMLRegionFactory (const XMLNode& node, bool full)
1311 const XMLProperty* type = node.property("type");
1315 if ( !type || type->value() == "audio" ) {
1317 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1319 } else if (type->value() == "midi") {
1321 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1325 } catch (failed_constructor& err) {
1326 return boost::shared_ptr<Region> ();
1329 return boost::shared_ptr<Region> ();
1332 boost::shared_ptr<AudioRegion>
1333 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1335 const XMLProperty* prop;
1336 boost::shared_ptr<Source> source;
1337 boost::shared_ptr<AudioSource> as;
1339 uint32_t nchans = 1;
1342 if (node.name() != X_("Region")) {
1343 return boost::shared_ptr<AudioRegion>();
1346 if ((prop = node.property (X_("channels"))) != 0) {
1347 nchans = atoi (prop->value().c_str());
1350 if ((prop = node.property ("name")) == 0) {
1351 cerr << "no name for this region\n";
1355 if ((prop = node.property (X_("source-0"))) == 0) {
1356 if ((prop = node.property ("source")) == 0) {
1357 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1358 return boost::shared_ptr<AudioRegion>();
1362 PBD::ID s_id (prop->value());
1364 if ((source = source_by_id (s_id)) == 0) {
1365 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1366 return boost::shared_ptr<AudioRegion>();
1369 as = boost::dynamic_pointer_cast<AudioSource>(source);
1371 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1372 return boost::shared_ptr<AudioRegion>();
1375 sources.push_back (as);
1377 /* pickup other channels */
1379 for (uint32_t n=1; n < nchans; ++n) {
1380 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1381 if ((prop = node.property (buf)) != 0) {
1383 PBD::ID id2 (prop->value());
1385 if ((source = source_by_id (id2)) == 0) {
1386 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1387 return boost::shared_ptr<AudioRegion>();
1390 as = boost::dynamic_pointer_cast<AudioSource>(source);
1392 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1393 return boost::shared_ptr<AudioRegion>();
1395 sources.push_back (as);
1400 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1402 /* a final detail: this is the one and only place that we know how long missing files are */
1404 if (region->whole_file()) {
1405 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1406 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1408 sfp->set_length (region->length());
1417 catch (failed_constructor& err) {
1418 return boost::shared_ptr<AudioRegion>();
1422 boost::shared_ptr<MidiRegion>
1423 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1425 const XMLProperty* prop;
1426 boost::shared_ptr<Source> source;
1427 boost::shared_ptr<MidiSource> ms;
1429 uint32_t nchans = 1;
1431 if (node.name() != X_("Region")) {
1432 return boost::shared_ptr<MidiRegion>();
1435 if ((prop = node.property (X_("channels"))) != 0) {
1436 nchans = atoi (prop->value().c_str());
1439 if ((prop = node.property ("name")) == 0) {
1440 cerr << "no name for this region\n";
1444 // Multiple midi channels? that's just crazy talk
1445 assert(nchans == 1);
1447 if ((prop = node.property (X_("source-0"))) == 0) {
1448 if ((prop = node.property ("source")) == 0) {
1449 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1450 return boost::shared_ptr<MidiRegion>();
1454 PBD::ID s_id (prop->value());
1456 if ((source = source_by_id (s_id)) == 0) {
1457 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1458 return boost::shared_ptr<MidiRegion>();
1461 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1463 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1464 return boost::shared_ptr<MidiRegion>();
1467 sources.push_back (ms);
1470 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1471 /* a final detail: this is the one and only place that we know how long missing files are */
1473 if (region->whole_file()) {
1474 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1475 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1477 sfp->set_length (region->length());
1485 catch (failed_constructor& err) {
1486 return boost::shared_ptr<MidiRegion>();
1491 Session::get_sources_as_xml ()
1494 XMLNode* node = new XMLNode (X_("Sources"));
1495 Glib::Mutex::Lock lm (source_lock);
1497 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1498 node->add_child_nocopy (i->second->get_state());
1505 Session::path_from_region_name (string name, string identifier)
1507 char buf[PATH_MAX+1];
1509 SessionDirectory sdir(get_best_session_directory_for_new_source());
1510 string sound_dir = sdir.sound_path().to_string();
1512 for (n = 0; n < 999999; ++n) {
1513 if (identifier.length()) {
1514 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", sound_dir.c_str(), name.c_str(),
1515 identifier.c_str(), n);
1517 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", sound_dir.c_str(), name.c_str(), n);
1520 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1525 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1534 Session::load_sources (const XMLNode& node)
1537 XMLNodeConstIterator niter;
1538 boost::shared_ptr<Source> source;
1540 nlist = node.children();
1544 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1547 if ((source = XMLSourceFactory (**niter)) == 0) {
1548 error << _("Session: cannot create Source from XML description.") << endmsg;
1552 catch (non_existent_source& err) {
1553 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1554 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1561 boost::shared_ptr<Source>
1562 Session::XMLSourceFactory (const XMLNode& node)
1564 if (node.name() != "Source") {
1565 return boost::shared_ptr<Source>();
1569 return SourceFactory::create (*this, node);
1572 catch (failed_constructor& err) {
1573 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1574 return boost::shared_ptr<Source>();
1579 Session::save_template (string template_name)
1582 string xml_path, bak_path, template_path;
1584 if (_state_of_the_state & CannotSave) {
1588 sys::path user_template_dir(user_template_directory());
1592 sys::create_directories (user_template_dir);
1594 catch(sys::filesystem_error& ex)
1596 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1597 user_template_dir.to_string(), ex.what()) << endmsg;
1601 tree.set_root (&get_template());
1603 sys::path template_file_path(user_template_dir);
1604 template_file_path /= template_name + template_suffix;
1606 if (sys::exists (template_file_path))
1608 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1609 template_file_path.to_string()) << endmsg;
1613 if (!tree.write (template_file_path.to_string())) {
1614 error << _("mix template not saved") << endmsg;
1622 Session::refresh_disk_space ()
1625 struct statfs statfsbuf;
1626 vector<space_and_path>::iterator i;
1627 Glib::Mutex::Lock lm (space_lock);
1630 /* get freespace on every FS that is part of the session path */
1632 _total_free_4k_blocks = 0;
1634 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1635 statfs ((*i).path.c_str(), &statfsbuf);
1637 scale = statfsbuf.f_bsize/4096.0;
1639 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1640 _total_free_4k_blocks += (*i).blocks;
1646 Session::get_best_session_directory_for_new_source ()
1648 vector<space_and_path>::iterator i;
1649 string result = _session_dir->root_path().to_string();
1651 /* handle common case without system calls */
1653 if (session_dirs.size() == 1) {
1657 /* OK, here's the algorithm we're following here:
1659 We want to select which directory to use for
1660 the next file source to be created. Ideally,
1661 we'd like to use a round-robin process so as to
1662 get maximum performance benefits from splitting
1663 the files across multiple disks.
1665 However, in situations without much diskspace, an
1666 RR approach may end up filling up a filesystem
1667 with new files while others still have space.
1668 Its therefore important to pay some attention to
1669 the freespace in the filesystem holding each
1670 directory as well. However, if we did that by
1671 itself, we'd keep creating new files in the file
1672 system with the most space until it was as full
1673 as all others, thus negating any performance
1674 benefits of this RAID-1 like approach.
1676 So, we use a user-configurable space threshold. If
1677 there are at least 2 filesystems with more than this
1678 much space available, we use RR selection between them.
1679 If not, then we pick the filesystem with the most space.
1681 This gets a good balance between the two
1685 refresh_disk_space ();
1687 int free_enough = 0;
1689 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1690 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1695 if (free_enough >= 2) {
1696 /* use RR selection process, ensuring that the one
1700 i = last_rr_session_dir;
1703 if (++i == session_dirs.end()) {
1704 i = session_dirs.begin();
1707 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1708 if (create_session_directory ((*i).path)) {
1710 last_rr_session_dir = i;
1715 } while (i != last_rr_session_dir);
1719 /* pick FS with the most freespace (and that
1720 seems to actually work ...)
1723 vector<space_and_path> sorted;
1724 space_and_path_ascending_cmp cmp;
1726 sorted = session_dirs;
1727 sort (sorted.begin(), sorted.end(), cmp);
1729 for (i = sorted.begin(); i != sorted.end(); ++i) {
1730 if (create_session_directory ((*i).path)) {
1732 last_rr_session_dir = i;
1742 Session::load_playlists (const XMLNode& node)
1745 XMLNodeConstIterator niter;
1746 boost::shared_ptr<Playlist> playlist;
1748 nlist = node.children();
1752 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1754 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1755 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1763 Session::load_unused_playlists (const XMLNode& node)
1766 XMLNodeConstIterator niter;
1767 boost::shared_ptr<Playlist> playlist;
1769 nlist = node.children();
1773 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1775 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1776 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1780 // now manually untrack it
1782 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1788 boost::shared_ptr<Playlist>
1789 Session::XMLPlaylistFactory (const XMLNode& node)
1792 return PlaylistFactory::create (*this, node);
1795 catch (failed_constructor& err) {
1796 return boost::shared_ptr<Playlist>();
1801 Session::load_named_selections (const XMLNode& node)
1804 XMLNodeConstIterator niter;
1807 nlist = node.children();
1811 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1813 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1814 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1822 Session::XMLNamedSelectionFactory (const XMLNode& node)
1825 return new NamedSelection (*this, node);
1828 catch (failed_constructor& err) {
1834 Session::automation_dir () const
1837 res += "automation/";
1842 Session::load_bundles (const XMLNode& node)
1844 XMLNodeList nlist = node.children();
1845 XMLNodeConstIterator niter;
1849 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1850 if ((*niter)->name() == "InputConnection") {
1851 add_bundle (new ARDOUR::InputBundle (**niter));
1852 } else if ((*niter)->name() == "OutputConnection") {
1853 add_bundle (new ARDOUR::OutputBundle (**niter));
1855 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1864 Session::load_edit_groups (const XMLNode& node)
1866 return load_route_groups (node, true);
1870 Session::load_mix_groups (const XMLNode& node)
1872 return load_route_groups (node, false);
1876 Session::load_route_groups (const XMLNode& node, bool edit)
1878 XMLNodeList nlist = node.children();
1879 XMLNodeConstIterator niter;
1884 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1885 if ((*niter)->name() == "RouteGroup") {
1887 rg = add_edit_group ("");
1888 rg->set_state (**niter);
1890 rg = add_mix_group ("");
1891 rg->set_state (**niter);
1900 state_file_filter (const string &str, void *arg)
1902 return (str.length() > strlen(statefile_suffix) &&
1903 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
1907 bool operator()(const string* a, const string* b) {
1913 remove_end(string* state)
1915 string statename(*state);
1917 string::size_type start,end;
1918 if ((start = statename.find_last_of ('/')) != string::npos) {
1919 statename = statename.substr (start+1);
1922 if ((end = statename.rfind(".ardour")) == string::npos) {
1923 end = statename.length();
1926 return new string(statename.substr (0, end));
1930 Session::possible_states (string path)
1932 PathScanner scanner;
1933 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
1935 transform(states->begin(), states->end(), states->begin(), remove_end);
1938 sort (states->begin(), states->end(), cmp);
1944 Session::possible_states () const
1946 return possible_states(_path);
1950 Session::auto_save()
1952 save_state (_current_snapshot_name);
1956 Session::add_edit_group (string name)
1958 RouteGroup* rg = new RouteGroup (*this, name);
1959 edit_groups.push_back (rg);
1960 edit_group_added (rg); /* EMIT SIGNAL */
1966 Session::add_mix_group (string name)
1968 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
1969 mix_groups.push_back (rg);
1970 mix_group_added (rg); /* EMIT SIGNAL */
1976 Session::remove_edit_group (RouteGroup& rg)
1978 list<RouteGroup*>::iterator i;
1980 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
1981 (*i)->apply (&Route::drop_edit_group, this);
1982 edit_groups.erase (i);
1983 edit_group_removed (); /* EMIT SIGNAL */
1990 Session::remove_mix_group (RouteGroup& rg)
1992 list<RouteGroup*>::iterator i;
1994 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
1995 (*i)->apply (&Route::drop_mix_group, this);
1996 mix_groups.erase (i);
1997 mix_group_removed (); /* EMIT SIGNAL */
2004 Session::mix_group_by_name (string name)
2006 list<RouteGroup *>::iterator i;
2008 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2009 if ((*i)->name() == name) {
2017 Session::edit_group_by_name (string name)
2019 list<RouteGroup *>::iterator i;
2021 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2022 if ((*i)->name() == name) {
2030 Session::begin_reversible_command (const string& name)
2032 current_trans = new UndoTransaction;
2033 current_trans->set_name (name);
2037 Session::commit_reversible_command (Command *cmd)
2042 current_trans->add_command (cmd);
2045 gettimeofday (&now, 0);
2046 current_trans->set_timestamp (now);
2048 _history.add (current_trans);
2051 Session::GlobalRouteBooleanState
2052 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2054 GlobalRouteBooleanState s;
2055 boost::shared_ptr<RouteList> r = routes.reader ();
2057 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2058 if (!(*i)->is_hidden()) {
2059 RouteBooleanState v;
2062 Route* r = (*i).get();
2063 v.second = (r->*method)();
2072 Session::GlobalRouteMeterState
2073 Session::get_global_route_metering ()
2075 GlobalRouteMeterState s;
2076 boost::shared_ptr<RouteList> r = routes.reader ();
2078 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2079 if (!(*i)->is_hidden()) {
2083 v.second = (*i)->meter_point();
2093 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2095 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2097 boost::shared_ptr<Route> r = (i->first.lock());
2100 r->set_meter_point (i->second, arg);
2106 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2108 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2110 boost::shared_ptr<Route> r = (i->first.lock());
2113 Route* rp = r.get();
2114 (rp->*method) (i->second, arg);
2120 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2122 set_global_route_boolean (s, &Route::set_mute, src);
2126 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2128 set_global_route_boolean (s, &Route::set_solo, src);
2132 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2134 set_global_route_boolean (s, &Route::set_record_enable, src);
2139 Session::global_mute_memento (void* src)
2141 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2145 Session::global_metering_memento (void* src)
2147 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2151 Session::global_solo_memento (void* src)
2153 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2157 Session::global_record_enable_memento (void* src)
2159 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2164 accept_all_non_peak_files (const string& path, void *arg)
2166 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2170 accept_all_state_files (const string& path, void *arg)
2172 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2176 Session::find_all_sources (string path, set<string>& result)
2181 if (!tree.read (path)) {
2185 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2190 XMLNodeConstIterator niter;
2192 nlist = node->children();
2196 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2200 if ((prop = (*niter)->property (X_("name"))) == 0) {
2204 if (prop->value()[0] == '/') {
2205 /* external file, ignore */
2209 sys::path source_path = _session_dir->sound_path ();
2211 source_path /= prop->value ();
2213 result.insert (source_path.to_string ());
2220 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2222 PathScanner scanner;
2223 vector<string*>* state_files;
2225 string this_snapshot_path;
2231 if (ripped[ripped.length()-1] == '/') {
2232 ripped = ripped.substr (0, ripped.length() - 1);
2235 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2237 if (state_files == 0) {
2242 this_snapshot_path = _path;
2243 this_snapshot_path += _current_snapshot_name;
2244 this_snapshot_path += statefile_suffix;
2246 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2248 if (exclude_this_snapshot && **i == this_snapshot_path) {
2252 if (find_all_sources (**i, result) < 0) {
2260 struct RegionCounter {
2261 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2262 AudioSourceList::iterator iter;
2263 boost::shared_ptr<Region> region;
2266 RegionCounter() : count (0) {}
2270 Session::cleanup_sources (Session::cleanup_report& rep)
2272 // FIXME: needs adaptation to midi
2274 vector<boost::shared_ptr<Source> > dead_sources;
2275 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2276 PathScanner scanner;
2278 vector<space_and_path>::iterator i;
2279 vector<space_and_path>::iterator nexti;
2280 vector<string*>* soundfiles;
2281 vector<string> unused;
2282 set<string> all_sources;
2287 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2289 /* step 1: consider deleting all unused playlists */
2291 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2294 status = AskAboutPlaylistDeletion (*x);
2303 playlists_tbd.push_back (*x);
2307 /* leave it alone */
2312 /* now delete any that were marked for deletion */
2314 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2315 (*x)->drop_references ();
2318 playlists_tbd.clear ();
2320 /* step 2: find all un-used sources */
2325 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2327 SourceMap::iterator tmp;
2332 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2336 if (!i->second->used() && i->second->length() > 0) {
2337 dead_sources.push_back (i->second);
2338 i->second->GoingAway();
2344 /* build a list of all the possible sound directories for the session */
2346 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2351 SessionDirectory sdir ((*i).path);
2352 sound_path += sdir.sound_path().to_string();
2354 if (nexti != session_dirs.end()) {
2361 /* now do the same thing for the files that ended up in the sounds dir(s)
2362 but are not referenced as sources in any snapshot.
2365 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2367 if (soundfiles == 0) {
2371 /* find all sources, but don't use this snapshot because the
2372 state file on disk still references sources we may have already
2376 find_all_sources_across_snapshots (all_sources, true);
2378 /* add our current source list
2381 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2382 boost::shared_ptr<AudioFileSource> fs;
2384 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2385 all_sources.insert (fs->path());
2389 char tmppath1[PATH_MAX+1];
2390 char tmppath2[PATH_MAX+1];
2392 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2397 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2399 realpath(spath.c_str(), tmppath1);
2400 realpath((*i).c_str(), tmppath2);
2402 if (strcmp(tmppath1, tmppath2) == 0) {
2409 unused.push_back (spath);
2413 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2415 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2416 struct stat statbuf;
2418 rep.paths.push_back (*x);
2419 if (stat ((*x).c_str(), &statbuf) == 0) {
2420 rep.space += statbuf.st_size;
2425 /* don't move the file across filesystems, just
2426 stick it in the `dead_sound_dir_name' directory
2427 on whichever filesystem it was already on.
2430 if ((*x).find ("/sounds/") != string::npos) {
2432 /* old school, go up 1 level */
2434 newpath = Glib::path_get_dirname (*x); // "sounds"
2435 newpath = Glib::path_get_dirname (newpath); // "session-name"
2439 /* new school, go up 4 levels */
2441 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2442 newpath = Glib::path_get_dirname (newpath); // "session-name"
2443 newpath = Glib::path_get_dirname (newpath); // "interchange"
2444 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2448 newpath += dead_sound_dir_name;
2450 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2451 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2456 newpath += Glib::path_get_basename ((*x));
2458 if (access (newpath.c_str(), F_OK) == 0) {
2460 /* the new path already exists, try versioning */
2462 char buf[PATH_MAX+1];
2466 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2469 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2470 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2474 if (version == 999) {
2475 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2479 newpath = newpath_v;
2484 /* it doesn't exist, or we can't read it or something */
2488 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2489 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2490 (*x), newpath, strerror (errno))
2495 /* see if there an easy to find peakfile for this file, and remove it.
2498 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2499 peakpath += peakfile_suffix;
2501 if (access (peakpath.c_str(), W_OK) == 0) {
2502 if (::unlink (peakpath.c_str()) != 0) {
2503 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2504 peakpath, _path, strerror (errno))
2506 /* try to back out */
2507 rename (newpath.c_str(), _path.c_str());
2515 /* dump the history list */
2519 /* save state so we don't end up a session file
2520 referring to non-existent sources.
2526 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2531 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2533 // FIXME: needs adaptation for MIDI
2535 vector<space_and_path>::iterator i;
2536 string dead_sound_dir;
2537 struct dirent* dentry;
2538 struct stat statbuf;
2544 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2546 dead_sound_dir = (*i).path;
2547 dead_sound_dir += dead_sound_dir_name;
2549 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2553 while ((dentry = readdir (dead)) != 0) {
2555 /* avoid '.' and '..' */
2557 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2558 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2564 fullpath = dead_sound_dir;
2566 fullpath += dentry->d_name;
2568 if (stat (fullpath.c_str(), &statbuf)) {
2572 if (!S_ISREG (statbuf.st_mode)) {
2576 if (unlink (fullpath.c_str())) {
2577 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2578 fullpath, strerror (errno))
2582 rep.paths.push_back (dentry->d_name);
2583 rep.space += statbuf.st_size;
2594 Session::set_dirty ()
2596 bool was_dirty = dirty();
2598 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2601 DirtyChanged(); /* EMIT SIGNAL */
2607 Session::set_clean ()
2609 bool was_dirty = dirty();
2611 _state_of_the_state = Clean;
2614 DirtyChanged(); /* EMIT SIGNAL */
2619 Session::set_deletion_in_progress ()
2621 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2625 Session::add_controllable (boost::shared_ptr<Controllable> c)
2627 /* this adds a controllable to the list managed by the Session.
2628 this is a subset of those managed by the Controllable class
2629 itself, and represents the only ones whose state will be saved
2630 as part of the session.
2633 Glib::Mutex::Lock lm (controllables_lock);
2634 controllables.insert (c);
2637 struct null_deleter { void operator()(void const *) const {} };
2640 Session::remove_controllable (Controllable* c)
2642 if (_state_of_the_state | Deletion) {
2646 Glib::Mutex::Lock lm (controllables_lock);
2648 Controllables::iterator x = controllables.find(
2649 boost::shared_ptr<Controllable>(c, null_deleter()));
2651 if (x != controllables.end()) {
2652 controllables.erase (x);
2656 boost::shared_ptr<Controllable>
2657 Session::controllable_by_id (const PBD::ID& id)
2659 Glib::Mutex::Lock lm (controllables_lock);
2661 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2662 if ((*i)->id() == id) {
2667 return boost::shared_ptr<Controllable>();
2671 Session::add_instant_xml (XMLNode& node)
2673 Stateful::add_instant_xml (node, _path);
2674 Config->add_instant_xml (node);
2678 Session::instant_xml (const string& node_name)
2680 return Stateful::instant_xml (node_name, _path);
2684 Session::save_history (string snapshot_name)
2690 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2692 if (snapshot_name.empty()) {
2693 snapshot_name = _current_snapshot_name;
2696 xml_path = _path + snapshot_name + ".history";
2698 bak_path = xml_path + ".bak";
2700 if ((access (xml_path.c_str(), F_OK) == 0) &&
2701 (rename (xml_path.c_str(), bak_path.c_str())))
2703 error << _("could not backup old history file, current history not saved.") << endmsg;
2707 if (!tree.write (xml_path))
2709 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2711 /* don't leave a corrupt file lying around if it is
2715 if (unlink (xml_path.c_str())) {
2716 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2718 if (rename (bak_path.c_str(), xml_path.c_str()))
2720 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2731 Session::restore_history (string snapshot_name)
2736 if (snapshot_name.empty()) {
2737 snapshot_name = _current_snapshot_name;
2741 xmlpath = _path + snapshot_name + ".history";
2742 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2744 if (access (xmlpath.c_str(), F_OK)) {
2745 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2749 if (!tree.read (xmlpath)) {
2750 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2754 /* replace history */
2757 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2760 UndoTransaction* ut = new UndoTransaction ();
2763 ut->set_name(t->property("name")->value());
2764 stringstream ss(t->property("tv_sec")->value());
2766 ss.str(t->property("tv_usec")->value());
2768 ut->set_timestamp(tv);
2770 for (XMLNodeConstIterator child_it = t->children().begin();
2771 child_it != t->children().end();
2774 XMLNode *n = *child_it;
2777 if (n->name() == "MementoCommand" ||
2778 n->name() == "MementoUndoCommand" ||
2779 n->name() == "MementoRedoCommand") {
2781 if ((c = memento_command_factory(n))) {
2785 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2787 if ((c = global_state_command_factory (*n))) {
2788 ut->add_command (c);
2793 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2804 Session::config_changed (const char* parameter_name)
2806 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2808 if (PARAM_IS ("seamless-loop")) {
2810 } else if (PARAM_IS ("rf-speed")) {
2812 } else if (PARAM_IS ("auto-loop")) {
2814 } else if (PARAM_IS ("auto-input")) {
2816 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2817 /* auto-input only makes a difference if we're rolling */
2819 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2821 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2822 if ((*i)->record_enabled ()) {
2823 (*i)->monitor_input (!Config->get_auto_input());
2828 } else if (PARAM_IS ("punch-in")) {
2832 if ((location = _locations.auto_punch_location()) != 0) {
2834 if (Config->get_punch_in ()) {
2835 replace_event (Event::PunchIn, location->start());
2837 remove_event (location->start(), Event::PunchIn);
2841 } else if (PARAM_IS ("punch-out")) {
2845 if ((location = _locations.auto_punch_location()) != 0) {
2847 if (Config->get_punch_out()) {
2848 replace_event (Event::PunchOut, location->end());
2850 clear_events (Event::PunchOut);
2854 } else if (PARAM_IS ("edit-mode")) {
2856 Glib::Mutex::Lock lm (playlist_lock);
2858 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2859 (*i)->set_edit_mode (Config->get_edit_mode ());
2862 } else if (PARAM_IS ("use-video-sync")) {
2864 waiting_for_sync_offset = Config->get_use_video_sync();
2866 } else if (PARAM_IS ("mmc-control")) {
2868 //poke_midi_thread ();
2870 } else if (PARAM_IS ("mmc-device-id")) {
2873 mmc->set_device_id (Config->get_mmc_device_id());
2876 } else if (PARAM_IS ("midi-control")) {
2878 //poke_midi_thread ();
2880 } else if (PARAM_IS ("raid-path")) {
2882 setup_raid_path (Config->get_raid_path());
2884 } else if (PARAM_IS ("smpte-format")) {
2888 } else if (PARAM_IS ("video-pullup")) {
2892 } else if (PARAM_IS ("seamless-loop")) {
2894 if (play_loop && transport_rolling()) {
2895 // to reset diskstreams etc
2896 request_play_loop (true);
2899 } else if (PARAM_IS ("rf-speed")) {
2901 cumulative_rf_motion = 0;
2904 } else if (PARAM_IS ("click-sound")) {
2906 setup_click_sounds (1);
2908 } else if (PARAM_IS ("click-emphasis-sound")) {
2910 setup_click_sounds (-1);
2912 } else if (PARAM_IS ("clicking")) {
2914 if (Config->get_clicking()) {
2915 if (_click_io && click_data) { // don't require emphasis data
2922 } else if (PARAM_IS ("send-mtc")) {
2924 /* only set the internal flag if we have
2928 if (_mtc_port != 0) {
2929 session_send_mtc = Config->get_send_mtc();
2930 if (session_send_mtc) {
2931 /* mark us ready to send */
2932 next_quarter_frame_to_send = 0;
2935 session_send_mtc = false;
2938 } else if (PARAM_IS ("send-mmc")) {
2940 /* only set the internal flag if we have
2944 if (_mmc_port != 0) {
2945 session_send_mmc = Config->get_send_mmc();
2948 session_send_mmc = false;
2951 } else if (PARAM_IS ("midi-feedback")) {
2953 /* only set the internal flag if we have
2957 if (_mtc_port != 0) {
2958 session_midi_feedback = Config->get_midi_feedback();
2961 } else if (PARAM_IS ("jack-time-master")) {
2963 engine().reset_timebase ();
2965 } else if (PARAM_IS ("native-file-header-format")) {
2967 if (!first_file_header_format_reset) {
2968 reset_native_file_format ();
2971 first_file_header_format_reset = false;
2973 } else if (PARAM_IS ("native-file-data-format")) {
2975 if (!first_file_data_format_reset) {
2976 reset_native_file_format ();
2979 first_file_data_format_reset = false;
2981 } else if (PARAM_IS ("slave-source")) {
2982 set_slave_source (Config->get_slave_source());
2983 } else if (PARAM_IS ("remote-model")) {
2984 set_remote_control_ids ();
2985 } else if (PARAM_IS ("denormal-model")) {