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 (DataType type, string name, string identifier)
1507 char buf[PATH_MAX+1];
1509 SessionDirectory sdir(get_best_session_directory_for_new_source());
1510 string sound_dir = ((type == DataType::AUDIO)
1511 ? sdir.sound_path().to_string()
1512 : sdir.midi_path().to_string());
1514 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1516 for (n = 0; n < 999999; ++n) {
1517 if (identifier.length()) {
1518 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1519 identifier.c_str(), n, ext.c_str());
1521 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1525 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1530 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1539 Session::load_sources (const XMLNode& node)
1542 XMLNodeConstIterator niter;
1543 boost::shared_ptr<Source> source;
1545 nlist = node.children();
1549 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1552 if ((source = XMLSourceFactory (**niter)) == 0) {
1553 error << _("Session: cannot create Source from XML description.") << endmsg;
1557 catch (non_existent_source& err) {
1558 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1559 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1566 boost::shared_ptr<Source>
1567 Session::XMLSourceFactory (const XMLNode& node)
1569 if (node.name() != "Source") {
1570 return boost::shared_ptr<Source>();
1574 return SourceFactory::create (*this, node);
1577 catch (failed_constructor& err) {
1578 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1579 return boost::shared_ptr<Source>();
1584 Session::save_template (string template_name)
1587 string xml_path, bak_path, template_path;
1589 if (_state_of_the_state & CannotSave) {
1593 sys::path user_template_dir(user_template_directory());
1597 sys::create_directories (user_template_dir);
1599 catch(sys::filesystem_error& ex)
1601 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1602 user_template_dir.to_string(), ex.what()) << endmsg;
1606 tree.set_root (&get_template());
1608 sys::path template_file_path(user_template_dir);
1609 template_file_path /= template_name + template_suffix;
1611 if (sys::exists (template_file_path))
1613 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1614 template_file_path.to_string()) << endmsg;
1618 if (!tree.write (template_file_path.to_string())) {
1619 error << _("mix template not saved") << endmsg;
1627 Session::refresh_disk_space ()
1630 struct statfs statfsbuf;
1631 vector<space_and_path>::iterator i;
1632 Glib::Mutex::Lock lm (space_lock);
1635 /* get freespace on every FS that is part of the session path */
1637 _total_free_4k_blocks = 0;
1639 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1640 statfs ((*i).path.c_str(), &statfsbuf);
1642 scale = statfsbuf.f_bsize/4096.0;
1644 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1645 _total_free_4k_blocks += (*i).blocks;
1651 Session::get_best_session_directory_for_new_source ()
1653 vector<space_and_path>::iterator i;
1654 string result = _session_dir->root_path().to_string();
1656 /* handle common case without system calls */
1658 if (session_dirs.size() == 1) {
1662 /* OK, here's the algorithm we're following here:
1664 We want to select which directory to use for
1665 the next file source to be created. Ideally,
1666 we'd like to use a round-robin process so as to
1667 get maximum performance benefits from splitting
1668 the files across multiple disks.
1670 However, in situations without much diskspace, an
1671 RR approach may end up filling up a filesystem
1672 with new files while others still have space.
1673 Its therefore important to pay some attention to
1674 the freespace in the filesystem holding each
1675 directory as well. However, if we did that by
1676 itself, we'd keep creating new files in the file
1677 system with the most space until it was as full
1678 as all others, thus negating any performance
1679 benefits of this RAID-1 like approach.
1681 So, we use a user-configurable space threshold. If
1682 there are at least 2 filesystems with more than this
1683 much space available, we use RR selection between them.
1684 If not, then we pick the filesystem with the most space.
1686 This gets a good balance between the two
1690 refresh_disk_space ();
1692 int free_enough = 0;
1694 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1695 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1700 if (free_enough >= 2) {
1701 /* use RR selection process, ensuring that the one
1705 i = last_rr_session_dir;
1708 if (++i == session_dirs.end()) {
1709 i = session_dirs.begin();
1712 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1713 if (create_session_directory ((*i).path)) {
1715 last_rr_session_dir = i;
1720 } while (i != last_rr_session_dir);
1724 /* pick FS with the most freespace (and that
1725 seems to actually work ...)
1728 vector<space_and_path> sorted;
1729 space_and_path_ascending_cmp cmp;
1731 sorted = session_dirs;
1732 sort (sorted.begin(), sorted.end(), cmp);
1734 for (i = sorted.begin(); i != sorted.end(); ++i) {
1735 if (create_session_directory ((*i).path)) {
1737 last_rr_session_dir = i;
1747 Session::load_playlists (const XMLNode& node)
1750 XMLNodeConstIterator niter;
1751 boost::shared_ptr<Playlist> playlist;
1753 nlist = node.children();
1757 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1759 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1760 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1768 Session::load_unused_playlists (const XMLNode& node)
1771 XMLNodeConstIterator niter;
1772 boost::shared_ptr<Playlist> playlist;
1774 nlist = node.children();
1778 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1780 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1781 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1785 // now manually untrack it
1787 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1793 boost::shared_ptr<Playlist>
1794 Session::XMLPlaylistFactory (const XMLNode& node)
1797 return PlaylistFactory::create (*this, node);
1800 catch (failed_constructor& err) {
1801 return boost::shared_ptr<Playlist>();
1806 Session::load_named_selections (const XMLNode& node)
1809 XMLNodeConstIterator niter;
1812 nlist = node.children();
1816 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1818 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1819 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1827 Session::XMLNamedSelectionFactory (const XMLNode& node)
1830 return new NamedSelection (*this, node);
1833 catch (failed_constructor& err) {
1839 Session::automation_dir () const
1842 res += "automation/";
1847 Session::load_bundles (const XMLNode& node)
1849 XMLNodeList nlist = node.children();
1850 XMLNodeConstIterator niter;
1854 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1855 if ((*niter)->name() == "InputConnection") {
1856 add_bundle (new ARDOUR::InputBundle (**niter));
1857 } else if ((*niter)->name() == "OutputConnection") {
1858 add_bundle (new ARDOUR::OutputBundle (**niter));
1860 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1869 Session::load_edit_groups (const XMLNode& node)
1871 return load_route_groups (node, true);
1875 Session::load_mix_groups (const XMLNode& node)
1877 return load_route_groups (node, false);
1881 Session::load_route_groups (const XMLNode& node, bool edit)
1883 XMLNodeList nlist = node.children();
1884 XMLNodeConstIterator niter;
1889 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1890 if ((*niter)->name() == "RouteGroup") {
1892 rg = add_edit_group ("");
1893 rg->set_state (**niter);
1895 rg = add_mix_group ("");
1896 rg->set_state (**niter);
1905 state_file_filter (const string &str, void *arg)
1907 return (str.length() > strlen(statefile_suffix) &&
1908 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
1912 bool operator()(const string* a, const string* b) {
1918 remove_end(string* state)
1920 string statename(*state);
1922 string::size_type start,end;
1923 if ((start = statename.find_last_of ('/')) != string::npos) {
1924 statename = statename.substr (start+1);
1927 if ((end = statename.rfind(".ardour")) == string::npos) {
1928 end = statename.length();
1931 return new string(statename.substr (0, end));
1935 Session::possible_states (string path)
1937 PathScanner scanner;
1938 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
1940 transform(states->begin(), states->end(), states->begin(), remove_end);
1943 sort (states->begin(), states->end(), cmp);
1949 Session::possible_states () const
1951 return possible_states(_path);
1955 Session::auto_save()
1957 save_state (_current_snapshot_name);
1961 Session::add_edit_group (string name)
1963 RouteGroup* rg = new RouteGroup (*this, name);
1964 edit_groups.push_back (rg);
1965 edit_group_added (rg); /* EMIT SIGNAL */
1971 Session::add_mix_group (string name)
1973 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
1974 mix_groups.push_back (rg);
1975 mix_group_added (rg); /* EMIT SIGNAL */
1981 Session::remove_edit_group (RouteGroup& rg)
1983 list<RouteGroup*>::iterator i;
1985 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
1986 (*i)->apply (&Route::drop_edit_group, this);
1987 edit_groups.erase (i);
1988 edit_group_removed (); /* EMIT SIGNAL */
1995 Session::remove_mix_group (RouteGroup& rg)
1997 list<RouteGroup*>::iterator i;
1999 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2000 (*i)->apply (&Route::drop_mix_group, this);
2001 mix_groups.erase (i);
2002 mix_group_removed (); /* EMIT SIGNAL */
2009 Session::mix_group_by_name (string name)
2011 list<RouteGroup *>::iterator i;
2013 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2014 if ((*i)->name() == name) {
2022 Session::edit_group_by_name (string name)
2024 list<RouteGroup *>::iterator i;
2026 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2027 if ((*i)->name() == name) {
2035 Session::begin_reversible_command (const string& name)
2037 current_trans = new UndoTransaction;
2038 current_trans->set_name (name);
2042 Session::commit_reversible_command (Command *cmd)
2047 current_trans->add_command (cmd);
2050 gettimeofday (&now, 0);
2051 current_trans->set_timestamp (now);
2053 _history.add (current_trans);
2056 Session::GlobalRouteBooleanState
2057 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2059 GlobalRouteBooleanState s;
2060 boost::shared_ptr<RouteList> r = routes.reader ();
2062 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2063 if (!(*i)->is_hidden()) {
2064 RouteBooleanState v;
2067 Route* r = (*i).get();
2068 v.second = (r->*method)();
2077 Session::GlobalRouteMeterState
2078 Session::get_global_route_metering ()
2080 GlobalRouteMeterState s;
2081 boost::shared_ptr<RouteList> r = routes.reader ();
2083 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2084 if (!(*i)->is_hidden()) {
2088 v.second = (*i)->meter_point();
2098 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2100 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2102 boost::shared_ptr<Route> r = (i->first.lock());
2105 r->set_meter_point (i->second, arg);
2111 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2113 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2115 boost::shared_ptr<Route> r = (i->first.lock());
2118 Route* rp = r.get();
2119 (rp->*method) (i->second, arg);
2125 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2127 set_global_route_boolean (s, &Route::set_mute, src);
2131 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2133 set_global_route_boolean (s, &Route::set_solo, src);
2137 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2139 set_global_route_boolean (s, &Route::set_record_enable, src);
2144 Session::global_mute_memento (void* src)
2146 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2150 Session::global_metering_memento (void* src)
2152 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2156 Session::global_solo_memento (void* src)
2158 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2162 Session::global_record_enable_memento (void* src)
2164 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2169 accept_all_non_peak_files (const string& path, void *arg)
2171 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2175 accept_all_state_files (const string& path, void *arg)
2177 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2181 Session::find_all_sources (string path, set<string>& result)
2186 if (!tree.read (path)) {
2190 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2195 XMLNodeConstIterator niter;
2197 nlist = node->children();
2201 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2205 if ((prop = (*niter)->property (X_("name"))) == 0) {
2209 if (prop->value()[0] == '/') {
2210 /* external file, ignore */
2214 sys::path source_path = _session_dir->sound_path ();
2216 source_path /= prop->value ();
2218 result.insert (source_path.to_string ());
2225 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2227 PathScanner scanner;
2228 vector<string*>* state_files;
2230 string this_snapshot_path;
2236 if (ripped[ripped.length()-1] == '/') {
2237 ripped = ripped.substr (0, ripped.length() - 1);
2240 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2242 if (state_files == 0) {
2247 this_snapshot_path = _path;
2248 this_snapshot_path += _current_snapshot_name;
2249 this_snapshot_path += statefile_suffix;
2251 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2253 if (exclude_this_snapshot && **i == this_snapshot_path) {
2257 if (find_all_sources (**i, result) < 0) {
2265 struct RegionCounter {
2266 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2267 AudioSourceList::iterator iter;
2268 boost::shared_ptr<Region> region;
2271 RegionCounter() : count (0) {}
2275 Session::cleanup_sources (Session::cleanup_report& rep)
2277 // FIXME: needs adaptation to midi
2279 vector<boost::shared_ptr<Source> > dead_sources;
2280 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2281 PathScanner scanner;
2283 vector<space_and_path>::iterator i;
2284 vector<space_and_path>::iterator nexti;
2285 vector<string*>* soundfiles;
2286 vector<string> unused;
2287 set<string> all_sources;
2292 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2294 /* step 1: consider deleting all unused playlists */
2296 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2299 status = AskAboutPlaylistDeletion (*x);
2308 playlists_tbd.push_back (*x);
2312 /* leave it alone */
2317 /* now delete any that were marked for deletion */
2319 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2320 (*x)->drop_references ();
2323 playlists_tbd.clear ();
2325 /* step 2: find all un-used sources */
2330 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2332 SourceMap::iterator tmp;
2337 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2341 if (!i->second->used() && i->second->length() > 0) {
2342 dead_sources.push_back (i->second);
2343 i->second->GoingAway();
2349 /* build a list of all the possible sound directories for the session */
2351 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2356 SessionDirectory sdir ((*i).path);
2357 sound_path += sdir.sound_path().to_string();
2359 if (nexti != session_dirs.end()) {
2366 /* now do the same thing for the files that ended up in the sounds dir(s)
2367 but are not referenced as sources in any snapshot.
2370 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2372 if (soundfiles == 0) {
2376 /* find all sources, but don't use this snapshot because the
2377 state file on disk still references sources we may have already
2381 find_all_sources_across_snapshots (all_sources, true);
2383 /* add our current source list
2386 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2387 boost::shared_ptr<AudioFileSource> fs;
2389 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2390 all_sources.insert (fs->path());
2394 char tmppath1[PATH_MAX+1];
2395 char tmppath2[PATH_MAX+1];
2397 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2402 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2404 realpath(spath.c_str(), tmppath1);
2405 realpath((*i).c_str(), tmppath2);
2407 if (strcmp(tmppath1, tmppath2) == 0) {
2414 unused.push_back (spath);
2418 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2420 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2421 struct stat statbuf;
2423 rep.paths.push_back (*x);
2424 if (stat ((*x).c_str(), &statbuf) == 0) {
2425 rep.space += statbuf.st_size;
2430 /* don't move the file across filesystems, just
2431 stick it in the `dead_sound_dir_name' directory
2432 on whichever filesystem it was already on.
2435 if ((*x).find ("/sounds/") != string::npos) {
2437 /* old school, go up 1 level */
2439 newpath = Glib::path_get_dirname (*x); // "sounds"
2440 newpath = Glib::path_get_dirname (newpath); // "session-name"
2444 /* new school, go up 4 levels */
2446 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2447 newpath = Glib::path_get_dirname (newpath); // "session-name"
2448 newpath = Glib::path_get_dirname (newpath); // "interchange"
2449 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2453 newpath += dead_sound_dir_name;
2455 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2456 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2461 newpath += Glib::path_get_basename ((*x));
2463 if (access (newpath.c_str(), F_OK) == 0) {
2465 /* the new path already exists, try versioning */
2467 char buf[PATH_MAX+1];
2471 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2474 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2475 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2479 if (version == 999) {
2480 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2484 newpath = newpath_v;
2489 /* it doesn't exist, or we can't read it or something */
2493 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2494 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2495 (*x), newpath, strerror (errno))
2500 /* see if there an easy to find peakfile for this file, and remove it.
2503 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2504 peakpath += peakfile_suffix;
2506 if (access (peakpath.c_str(), W_OK) == 0) {
2507 if (::unlink (peakpath.c_str()) != 0) {
2508 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2509 peakpath, _path, strerror (errno))
2511 /* try to back out */
2512 rename (newpath.c_str(), _path.c_str());
2520 /* dump the history list */
2524 /* save state so we don't end up a session file
2525 referring to non-existent sources.
2531 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2536 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2538 // FIXME: needs adaptation for MIDI
2540 vector<space_and_path>::iterator i;
2541 string dead_sound_dir;
2542 struct dirent* dentry;
2543 struct stat statbuf;
2549 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2551 dead_sound_dir = (*i).path;
2552 dead_sound_dir += dead_sound_dir_name;
2554 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2558 while ((dentry = readdir (dead)) != 0) {
2560 /* avoid '.' and '..' */
2562 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2563 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2569 fullpath = dead_sound_dir;
2571 fullpath += dentry->d_name;
2573 if (stat (fullpath.c_str(), &statbuf)) {
2577 if (!S_ISREG (statbuf.st_mode)) {
2581 if (unlink (fullpath.c_str())) {
2582 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2583 fullpath, strerror (errno))
2587 rep.paths.push_back (dentry->d_name);
2588 rep.space += statbuf.st_size;
2599 Session::set_dirty ()
2601 bool was_dirty = dirty();
2603 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2606 DirtyChanged(); /* EMIT SIGNAL */
2612 Session::set_clean ()
2614 bool was_dirty = dirty();
2616 _state_of_the_state = Clean;
2619 DirtyChanged(); /* EMIT SIGNAL */
2624 Session::set_deletion_in_progress ()
2626 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2630 Session::add_controllable (boost::shared_ptr<Controllable> c)
2632 /* this adds a controllable to the list managed by the Session.
2633 this is a subset of those managed by the Controllable class
2634 itself, and represents the only ones whose state will be saved
2635 as part of the session.
2638 Glib::Mutex::Lock lm (controllables_lock);
2639 controllables.insert (c);
2642 struct null_deleter { void operator()(void const *) const {} };
2645 Session::remove_controllable (Controllable* c)
2647 if (_state_of_the_state | Deletion) {
2651 Glib::Mutex::Lock lm (controllables_lock);
2653 Controllables::iterator x = controllables.find(
2654 boost::shared_ptr<Controllable>(c, null_deleter()));
2656 if (x != controllables.end()) {
2657 controllables.erase (x);
2661 boost::shared_ptr<Controllable>
2662 Session::controllable_by_id (const PBD::ID& id)
2664 Glib::Mutex::Lock lm (controllables_lock);
2666 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2667 if ((*i)->id() == id) {
2672 return boost::shared_ptr<Controllable>();
2676 Session::add_instant_xml (XMLNode& node)
2678 Stateful::add_instant_xml (node, _path);
2679 Config->add_instant_xml (node);
2683 Session::instant_xml (const string& node_name)
2685 return Stateful::instant_xml (node_name, _path);
2689 Session::save_history (string snapshot_name)
2695 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2697 if (snapshot_name.empty()) {
2698 snapshot_name = _current_snapshot_name;
2701 xml_path = _path + snapshot_name + ".history";
2703 bak_path = xml_path + ".bak";
2705 if ((access (xml_path.c_str(), F_OK) == 0) &&
2706 (rename (xml_path.c_str(), bak_path.c_str())))
2708 error << _("could not backup old history file, current history not saved.") << endmsg;
2712 if (!tree.write (xml_path))
2714 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2716 /* don't leave a corrupt file lying around if it is
2720 if (unlink (xml_path.c_str())) {
2721 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2723 if (rename (bak_path.c_str(), xml_path.c_str()))
2725 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2736 Session::restore_history (string snapshot_name)
2741 if (snapshot_name.empty()) {
2742 snapshot_name = _current_snapshot_name;
2746 xmlpath = _path + snapshot_name + ".history";
2747 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2749 if (access (xmlpath.c_str(), F_OK)) {
2750 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2754 if (!tree.read (xmlpath)) {
2755 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2759 /* replace history */
2762 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2765 UndoTransaction* ut = new UndoTransaction ();
2768 ut->set_name(t->property("name")->value());
2769 stringstream ss(t->property("tv_sec")->value());
2771 ss.str(t->property("tv_usec")->value());
2773 ut->set_timestamp(tv);
2775 for (XMLNodeConstIterator child_it = t->children().begin();
2776 child_it != t->children().end();
2779 XMLNode *n = *child_it;
2782 if (n->name() == "MementoCommand" ||
2783 n->name() == "MementoUndoCommand" ||
2784 n->name() == "MementoRedoCommand") {
2786 if ((c = memento_command_factory(n))) {
2790 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2792 if ((c = global_state_command_factory (*n))) {
2793 ut->add_command (c);
2798 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2809 Session::config_changed (const char* parameter_name)
2811 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2813 if (PARAM_IS ("seamless-loop")) {
2815 } else if (PARAM_IS ("rf-speed")) {
2817 } else if (PARAM_IS ("auto-loop")) {
2819 } else if (PARAM_IS ("auto-input")) {
2821 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2822 /* auto-input only makes a difference if we're rolling */
2824 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2826 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2827 if ((*i)->record_enabled ()) {
2828 (*i)->monitor_input (!Config->get_auto_input());
2833 } else if (PARAM_IS ("punch-in")) {
2837 if ((location = _locations.auto_punch_location()) != 0) {
2839 if (Config->get_punch_in ()) {
2840 replace_event (Event::PunchIn, location->start());
2842 remove_event (location->start(), Event::PunchIn);
2846 } else if (PARAM_IS ("punch-out")) {
2850 if ((location = _locations.auto_punch_location()) != 0) {
2852 if (Config->get_punch_out()) {
2853 replace_event (Event::PunchOut, location->end());
2855 clear_events (Event::PunchOut);
2859 } else if (PARAM_IS ("edit-mode")) {
2861 Glib::Mutex::Lock lm (playlist_lock);
2863 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2864 (*i)->set_edit_mode (Config->get_edit_mode ());
2867 } else if (PARAM_IS ("use-video-sync")) {
2869 waiting_for_sync_offset = Config->get_use_video_sync();
2871 } else if (PARAM_IS ("mmc-control")) {
2873 //poke_midi_thread ();
2875 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
2878 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
2881 } else if (PARAM_IS ("mmc-send-id")) {
2884 mmc->set_send_device_id (Config->get_mmc_send_device_id());
2887 } else if (PARAM_IS ("midi-control")) {
2889 //poke_midi_thread ();
2891 } else if (PARAM_IS ("raid-path")) {
2893 setup_raid_path (Config->get_raid_path());
2895 } else if (PARAM_IS ("smpte-format")) {
2899 } else if (PARAM_IS ("video-pullup")) {
2903 } else if (PARAM_IS ("seamless-loop")) {
2905 if (play_loop && transport_rolling()) {
2906 // to reset diskstreams etc
2907 request_play_loop (true);
2910 } else if (PARAM_IS ("rf-speed")) {
2912 cumulative_rf_motion = 0;
2915 } else if (PARAM_IS ("click-sound")) {
2917 setup_click_sounds (1);
2919 } else if (PARAM_IS ("click-emphasis-sound")) {
2921 setup_click_sounds (-1);
2923 } else if (PARAM_IS ("clicking")) {
2925 if (Config->get_clicking()) {
2926 if (_click_io && click_data) { // don't require emphasis data
2933 } else if (PARAM_IS ("send-mtc")) {
2935 /* only set the internal flag if we have
2939 if (_mtc_port != 0) {
2940 session_send_mtc = Config->get_send_mtc();
2941 if (session_send_mtc) {
2942 /* mark us ready to send */
2943 next_quarter_frame_to_send = 0;
2946 session_send_mtc = false;
2949 } else if (PARAM_IS ("send-mmc")) {
2951 /* only set the internal flag if we have
2955 if (_mmc_port != 0) {
2956 session_send_mmc = Config->get_send_mmc();
2959 session_send_mmc = false;
2962 } else if (PARAM_IS ("midi-feedback")) {
2964 /* only set the internal flag if we have
2968 if (_mtc_port != 0) {
2969 session_midi_feedback = Config->get_midi_feedback();
2972 } else if (PARAM_IS ("jack-time-master")) {
2974 engine().reset_timebase ();
2976 } else if (PARAM_IS ("native-file-header-format")) {
2978 if (!first_file_header_format_reset) {
2979 reset_native_file_format ();
2982 first_file_header_format_reset = false;
2984 } else if (PARAM_IS ("native-file-data-format")) {
2986 if (!first_file_data_format_reset) {
2987 reset_native_file_format ();
2990 first_file_data_format_reset = false;
2992 } else if (PARAM_IS ("slave-source")) {
2993 set_slave_source (Config->get_slave_source());
2994 } else if (PARAM_IS ("remote-model")) {
2995 set_remote_control_ids ();
2996 } else if (PARAM_IS ("denormal-model")) {