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/strsplit.h>
60 #include <pbd/stacktrace.h>
61 #include <pbd/copyfile.h>
63 #include <ardour/audioengine.h>
64 #include <ardour/configuration.h>
65 #include <ardour/session.h>
66 #include <ardour/session_directory.h>
67 #include <ardour/session_utils.h>
68 #include <ardour/buffer.h>
69 #include <ardour/audio_diskstream.h>
70 #include <ardour/midi_diskstream.h>
71 #include <ardour/utils.h>
72 #include <ardour/audioplaylist.h>
73 #include <ardour/midi_playlist.h>
74 #include <ardour/smf_source.h>
75 #include <ardour/audiofilesource.h>
76 #include <ardour/silentfilesource.h>
77 #include <ardour/sndfilesource.h>
78 #include <ardour/midi_source.h>
79 #include <ardour/sndfile_helpers.h>
80 #include <ardour/auditioner.h>
81 #include <ardour/export.h>
82 #include <ardour/redirect.h>
83 #include <ardour/send.h>
84 #include <ardour/insert.h>
85 #include <ardour/bundle.h>
86 #include <ardour/slave.h>
87 #include <ardour/tempo.h>
88 #include <ardour/audio_track.h>
89 #include <ardour/midi_track.h>
90 #include <ardour/cycle_timer.h>
91 #include <ardour/utils.h>
92 #include <ardour/named_selection.h>
93 #include <ardour/version.h>
94 #include <ardour/location.h>
95 #include <ardour/audioregion.h>
96 #include <ardour/midi_region.h>
97 #include <ardour/crossfade.h>
98 #include <ardour/control_protocol_manager.h>
99 #include <ardour/region_factory.h>
100 #include <ardour/source_factory.h>
101 #include <ardour/playlist_factory.h>
102 #include <ardour/filename_extensions.h>
103 #include <ardour/directory_names.h>
104 #include <ardour/template_utils.h>
106 #include <control_protocol/control_protocol.h>
112 using namespace ARDOUR;
116 Session::first_stage_init (string fullpath, string snapshot_name)
118 if (fullpath.length() == 0) {
120 throw failed_constructor();
123 char buf[PATH_MAX+1];
124 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
125 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
127 throw failed_constructor();
132 if (_path[_path.length()-1] != '/') {
136 /* these two are just provisional settings. set_state()
137 will likely override them.
140 _name = _current_snapshot_name = snapshot_name;
142 _current_frame_rate = _engine.frame_rate ();
143 _tempo_map = new TempoMap (_current_frame_rate);
144 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
146 g_atomic_int_set (&processing_prohibited, 0);
148 _transport_speed = 0;
149 _last_transport_speed = 0;
150 auto_play_legal = false;
151 transport_sub_state = 0;
152 _transport_frame = 0;
154 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
155 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
156 _end_location_is_free = true;
157 g_atomic_int_set (&_record_status, Disabled);
158 loop_changing = false;
160 _last_roll_location = 0;
161 _last_record_location = 0;
162 pending_locate_frame = 0;
163 pending_locate_roll = false;
164 pending_locate_flush = false;
165 dstream_buffer_size = 0;
167 state_was_pending = false;
169 outbound_mtc_smpte_frame = 0;
170 next_quarter_frame_to_send = -1;
171 current_block_size = 0;
172 solo_update_disabled = false;
173 currently_soloing = false;
174 _have_captured = false;
175 _worst_output_latency = 0;
176 _worst_input_latency = 0;
177 _worst_track_latency = 0;
178 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
180 butler_mixdown_buffer = 0;
181 butler_gain_buffer = 0;
183 session_send_mmc = false;
184 session_send_mtc = false;
185 post_transport_work = PostTransportWork (0);
186 g_atomic_int_set (&butler_should_do_transport_work, 0);
187 g_atomic_int_set (&butler_active, 0);
188 g_atomic_int_set (&_playback_load, 100);
189 g_atomic_int_set (&_capture_load, 100);
190 g_atomic_int_set (&_playback_load_min, 100);
191 g_atomic_int_set (&_capture_load_min, 100);
193 waiting_to_start = false;
195 _gain_automation_buffer = 0;
196 _pan_automation_buffer = 0;
198 pending_abort = false;
199 destructive_index = 0;
201 first_file_data_format_reset = true;
202 first_file_header_format_reset = true;
203 butler_thread = (pthread_t) 0;
204 //midi_thread = (pthread_t) 0;
206 AudioDiskstream::allocate_working_buffers();
208 /* default short fade = 15ms */
210 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
211 SndFileSource::setup_standard_crossfades (frame_rate());
213 last_mmc_step.tv_sec = 0;
214 last_mmc_step.tv_usec = 0;
217 /* click sounds are unset by default, which causes us to internal
218 waveforms for clicks.
222 click_emphasis_data = 0;
224 click_emphasis_length = 0;
227 process_function = &Session::process_with_events;
229 if (Config->get_use_video_sync()) {
230 waiting_for_sync_offset = true;
232 waiting_for_sync_offset = false;
235 _current_frame_rate = 48000;
236 _base_frame_rate = 48000;
240 _smpte_offset_negative = true;
241 last_smpte_valid = false;
245 last_rr_session_dir = session_dirs.begin();
246 refresh_disk_space ();
248 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
252 average_slave_delta = 1800;
253 have_first_delta_accumulator = false;
254 delta_accumulator_cnt = 0;
255 slave_state = Stopped;
257 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
259 /* These are all static "per-class" signals */
261 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
262 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
263 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
264 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
265 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
266 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
268 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
270 IO::MoreChannels.connect (mem_fun (*this, &Session::ensure_buffers));
272 /* stop IO objects from doing stuff until we're ready for them */
274 IO::disable_panners ();
275 IO::disable_ports ();
276 IO::disable_connecting ();
280 Session::second_stage_init (bool new_session)
282 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
285 if (load_state (_current_snapshot_name)) {
288 remove_empty_sounds ();
291 if (start_butler_thread()) {
295 /*if (start_midi_thread ()) {
299 // set_state() will call setup_raid_path(), but if it's a new session we need
300 // to call setup_raid_path() here.
302 if (set_state (*state_tree->root())) {
306 setup_raid_path(_path);
309 /* we can't save till after ::when_engine_running() is called,
310 because otherwise we save state with no connections made.
311 therefore, we reset _state_of_the_state because ::set_state()
312 will have cleared it.
314 we also have to include Loading so that any events that get
315 generated between here and the end of ::when_engine_running()
316 will be processed directly rather than queued.
319 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
321 // set_auto_input (true);
322 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
323 _locations.added.connect (mem_fun (this, &Session::locations_added));
324 setup_click_sounds (0);
325 setup_midi_control ();
327 /* Pay attention ... */
329 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
330 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
333 when_engine_running();
336 /* handle this one in a different way than all others, so that its clear what happened */
338 catch (AudioEngine::PortRegistrationFailure& err) {
339 error << _("Unable to create all required ports")
348 //send_full_time_code ();
349 _engine.transport_locate (0);
350 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
351 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
353 ControlProtocolManager::instance().set_session (*this);
356 _end_location_is_free = true;
358 _end_location_is_free = false;
365 Session::raid_path () const
367 SearchPath raid_search_path;
369 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
370 raid_search_path += sys::path((*i).path);
373 return raid_search_path.get_string ();
377 Session::setup_raid_path (string path)
386 session_dirs.clear ();
388 SearchPath search_path(path);
389 SearchPath sound_search_path;
390 SearchPath midi_search_path;
393 SearchPath::const_iterator i = search_path.begin();
394 i != search_path.end();
398 sp.path = (*i).to_string ();
399 sp.blocks = 0; // not needed
400 session_dirs.push_back (sp);
402 SessionDirectory sdir(sp.path);
404 sound_search_path += sdir.sound_path ();
405 midi_search_path += sdir.midi_path ();
408 // set the AudioFileSource and SMFSource search path
410 AudioFileSource::set_search_path (sound_search_path.get_string ());
411 SMFSource::set_search_path (midi_search_path.get_string ());
413 // reset the round-robin soundfile path thingie
415 last_rr_session_dir = session_dirs.begin();
419 Session::initialize_start_and_end_locations (nframes_t start, nframes_t end)
421 start_location->set_end (start);
422 _locations.add (start_location);
424 end_location->set_end (end);
425 _locations.add (end_location);
429 Session::create_session_file ()
431 _state_of_the_state = Clean;
433 if (save_state (_current_snapshot_name)) {
434 error << "Could not create new session file" << endmsg;
441 Session::create_session_file_from_template (const string& template_path)
443 string out_path = _path + _name + statefile_suffix;
445 if(!copy_file (template_path, out_path)) {
446 error << string_compose (_("Could not use session template %1 to create new session."), template_path)
454 Session::load_diskstreams (const XMLNode& node)
457 XMLNodeConstIterator citer;
459 clist = node.children();
461 for (citer = clist.begin(); citer != clist.end(); ++citer) {
464 /* diskstreams added automatically by DiskstreamCreated handler */
465 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
466 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
467 add_diskstream (dstream);
468 } else if ((*citer)->name() == "MidiDiskstream") {
469 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
470 add_diskstream (dstream);
472 error << _("Session: unknown diskstream type in XML") << endmsg;
476 catch (failed_constructor& err) {
477 error << _("Session: could not load diskstream via XML state") << endmsg;
486 Session::maybe_write_autosave()
488 if (dirty() && record_status() != Recording) {
489 save_state("", true);
494 Session::remove_pending_capture_state ()
499 xml_path += _current_snapshot_name;
500 xml_path += pending_suffix;
502 unlink (xml_path.c_str());
505 /** Rename a state file.
506 * @param snapshot_name Snapshot name.
509 Session::rename_state (string old_name, string new_name)
511 if (old_name == _current_snapshot_name || old_name == _name) {
512 /* refuse to rename the current snapshot or the "main" one */
516 const string old_xml_path = _path + old_name + statefile_suffix;
517 const string new_xml_path = _path + new_name + statefile_suffix;
519 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
520 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
524 /** Remove a state file.
525 * @param snapshot_name Snapshot name.
528 Session::remove_state (string snapshot_name)
530 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
531 /* refuse to remove the current snapshot or the "main" one */
535 const string xml_path = _path + snapshot_name + statefile_suffix;
537 /* make a backup copy of the state file */
538 const string bak_path = xml_path + ".bak";
539 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
540 copy_file (xml_path, bak_path);
544 unlink (xml_path.c_str());
548 Session::save_state (string snapshot_name, bool pending)
554 if (_state_of_the_state & CannotSave) {
558 if (!_engine.connected ()) {
559 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
564 tree.set_root (&get_state());
566 if (snapshot_name.empty()) {
567 snapshot_name = _current_snapshot_name;
572 /* proper save: use statefile_suffix (.ardour in English) */
574 xml_path += snapshot_name;
575 xml_path += statefile_suffix;
577 /* make a backup copy of the old file */
581 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
582 copy_file (xml_path, bak_path);
587 /* pending save: use pending_suffix (.pending in English) */
589 xml_path += snapshot_name;
590 xml_path += pending_suffix;
597 tmp_path += snapshot_name;
600 // cerr << "actually writing state to " << xml_path << endl;
602 if (!tree.write (tmp_path)) {
603 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
604 unlink (tmp_path.c_str());
609 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
610 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
611 unlink (tmp_path.c_str());
618 save_history (snapshot_name);
620 bool was_dirty = dirty();
622 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
625 DirtyChanged (); /* EMIT SIGNAL */
628 StateSaved (snapshot_name); /* EMIT SIGNAL */
635 Session::restore_state (string snapshot_name)
637 if (load_state (snapshot_name) == 0) {
638 set_state (*state_tree->root());
645 Session::load_state (string snapshot_name)
654 state_was_pending = false;
656 /* check for leftover pending state from a crashed capture attempt */
659 xmlpath += snapshot_name;
660 xmlpath += pending_suffix;
662 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
664 /* there is pending state from a crashed capture attempt */
666 if (AskAboutPendingState()) {
667 state_was_pending = true;
671 if (!state_was_pending) {
674 xmlpath += snapshot_name;
675 xmlpath += statefile_suffix;
678 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
679 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
683 state_tree = new XMLTree;
687 if (!state_tree->read (xmlpath)) {
688 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
694 XMLNode& root (*state_tree->root());
696 if (root.name() != X_("Session")) {
697 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
703 const XMLProperty* prop;
706 if ((prop = root.property ("version")) == 0) {
707 /* no version implies very old version of Ardour */
711 major_version = atoi (prop->value()); // grab just the first number before the period
712 if (major_version < 2) {
721 backup_path += snapshot_name;
723 backup_path += statefile_suffix;
725 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
726 xmlpath, backup_path)
729 copy_file (xmlpath, backup_path);
731 /* if it fails, don't worry. right? */
738 Session::load_options (const XMLNode& node)
742 LocaleGuard lg (X_("POSIX"));
744 Config->set_variables (node, ConfigVariableBase::Session);
746 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
747 if ((prop = child->property ("val")) != 0) {
748 _end_location_is_free = (prop->value() == "yes");
756 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
758 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
759 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
761 return owner & modified_by_session_or_user;
765 Session::get_options () const
768 LocaleGuard lg (X_("POSIX"));
770 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
772 child = option_root.add_child ("end-marker-is-free");
773 child->add_property ("val", _end_location_is_free ? "yes" : "no");
785 Session::get_template()
787 /* if we don't disable rec-enable, diskstreams
788 will believe they need to store their capture
789 sources in their state node.
792 disable_record (false);
798 Session::state(bool full_state)
800 XMLNode* node = new XMLNode("Session");
803 // store libardour version, just in case
805 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
806 libardour_major_version, libardour_minor_version, libardour_micro_version);
807 node->add_property("version", string(buf));
809 /* store configuration settings */
814 node->add_property ("name", _name);
816 if (session_dirs.size() > 1) {
820 vector<space_and_path>::iterator i = session_dirs.begin();
821 vector<space_and_path>::iterator next;
823 ++i; /* skip the first one */
827 while (i != session_dirs.end()) {
831 if (next != session_dirs.end()) {
841 child = node->add_child ("Path");
842 child->add_content (p);
846 /* save the ID counter */
848 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
849 node->add_property ("id-counter", buf);
851 /* various options */
853 node->add_child_nocopy (get_options());
855 child = node->add_child ("Sources");
858 Glib::Mutex::Lock sl (source_lock);
860 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
862 /* Don't save information about AudioFileSources that are empty */
864 boost::shared_ptr<AudioFileSource> fs;
866 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
868 /* Don't save sources that are empty, unless they're destructive (which are OK
869 if they are empty, because we will re-use them every time.)
872 if (!fs->destructive()) {
873 if (fs->length() == 0) {
879 child->add_child_nocopy (siter->second->get_state());
883 child = node->add_child ("Regions");
886 Glib::Mutex::Lock rl (region_lock);
888 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
890 /* only store regions not attached to playlists */
892 if (i->second->playlist() == 0) {
893 child->add_child_nocopy (i->second->state (true));
898 child = node->add_child ("DiskStreams");
901 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
902 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
903 if (!(*i)->hidden()) {
904 child->add_child_nocopy ((*i)->get_state());
910 node->add_child_nocopy (_locations.get_state());
912 // for a template, just create a new Locations, populate it
913 // with the default start and end, and get the state for that.
915 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
916 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
919 end->set_end(compute_initial_length());
921 node->add_child_nocopy (loc.get_state());
924 child = node->add_child ("Connections");
926 Glib::Mutex::Lock lm (bundle_lock);
927 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
928 if (!(*i)->dynamic()) {
929 child->add_child_nocopy ((*i)->get_state());
934 child = node->add_child ("Routes");
936 boost::shared_ptr<RouteList> r = routes.reader ();
938 RoutePublicOrderSorter cmp;
939 RouteList public_order (*r);
940 public_order.sort (cmp);
942 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
943 if (!(*i)->hidden()) {
945 child->add_child_nocopy ((*i)->get_state());
947 child->add_child_nocopy ((*i)->get_template());
954 child = node->add_child ("EditGroups");
955 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
956 child->add_child_nocopy ((*i)->get_state());
959 child = node->add_child ("MixGroups");
960 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
961 child->add_child_nocopy ((*i)->get_state());
964 child = node->add_child ("Playlists");
965 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
966 if (!(*i)->hidden()) {
967 if (!(*i)->empty()) {
969 child->add_child_nocopy ((*i)->get_state());
971 child->add_child_nocopy ((*i)->get_template());
977 child = node->add_child ("UnusedPlaylists");
978 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
979 if (!(*i)->hidden()) {
980 if (!(*i)->empty()) {
982 child->add_child_nocopy ((*i)->get_state());
984 child->add_child_nocopy ((*i)->get_template());
992 child = node->add_child ("Click");
993 child->add_child_nocopy (_click_io->state (full_state));
997 child = node->add_child ("NamedSelections");
998 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1000 child->add_child_nocopy ((*i)->get_state());
1005 node->add_child_nocopy (_tempo_map->get_state());
1007 node->add_child_nocopy (get_control_protocol_state());
1010 node->add_child_copy (*_extra_xml);
1017 Session::get_control_protocol_state ()
1019 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1020 return cpm.get_state();
1024 Session::set_state (const XMLNode& node)
1028 const XMLProperty* prop;
1031 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1033 if (node.name() != X_("Session")){
1034 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1038 if ((prop = node.property ("name")) != 0) {
1039 _name = prop->value ();
1042 setup_raid_path(_path);
1044 if ((prop = node.property (X_("id-counter"))) != 0) {
1046 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1047 ID::init_counter (x);
1049 /* old sessions used a timebased counter, so fake
1050 the startup ID counter based on a standard
1055 ID::init_counter (now);
1059 IO::disable_ports ();
1060 IO::disable_connecting ();
1062 /* Object loading order:
1080 if (use_config_midi_ports ()) {
1083 if ((child = find_named_node (node, "extra")) != 0) {
1084 _extra_xml = new XMLNode (*child);
1087 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1088 load_options (*child);
1089 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1090 load_options (*child);
1092 error << _("Session: XML state has no options section") << endmsg;
1095 if ((child = find_named_node (node, "Locations")) == 0) {
1096 error << _("Session: XML state has no locations section") << endmsg;
1098 } else if (_locations.set_state (*child)) {
1104 if ((location = _locations.auto_loop_location()) != 0) {
1105 set_auto_loop_location (location);
1108 if ((location = _locations.auto_punch_location()) != 0) {
1109 set_auto_punch_location (location);
1112 if ((location = _locations.end_location()) == 0) {
1113 _locations.add (end_location);
1115 delete end_location;
1116 end_location = location;
1119 if ((location = _locations.start_location()) == 0) {
1120 _locations.add (start_location);
1122 delete start_location;
1123 start_location = location;
1126 AudioFileSource::set_header_position_offset (start_location->start());
1128 if ((child = find_named_node (node, "Sources")) == 0) {
1129 error << _("Session: XML state has no sources section") << endmsg;
1131 } else if (load_sources (*child)) {
1135 if ((child = find_named_node (node, "Regions")) == 0) {
1136 error << _("Session: XML state has no Regions section") << endmsg;
1138 } else if (load_regions (*child)) {
1142 if ((child = find_named_node (node, "Playlists")) == 0) {
1143 error << _("Session: XML state has no playlists section") << endmsg;
1145 } else if (load_playlists (*child)) {
1149 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1151 } else if (load_unused_playlists (*child)) {
1155 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1156 if (load_named_selections (*child)) {
1161 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1162 error << _("Session: XML state has no diskstreams section") << endmsg;
1164 } else if (load_diskstreams (*child)) {
1168 if ((child = find_named_node (node, "Connections")) == 0) {
1169 error << _("Session: XML state has no connections section") << endmsg;
1171 } else if (load_bundles (*child)) {
1175 if ((child = find_named_node (node, "EditGroups")) == 0) {
1176 error << _("Session: XML state has no edit groups section") << endmsg;
1178 } else if (load_edit_groups (*child)) {
1182 if ((child = find_named_node (node, "MixGroups")) == 0) {
1183 error << _("Session: XML state has no mix groups section") << endmsg;
1185 } else if (load_mix_groups (*child)) {
1189 if ((child = find_named_node (node, "TempoMap")) == 0) {
1190 error << _("Session: XML state has no Tempo Map section") << endmsg;
1192 } else if (_tempo_map->set_state (*child)) {
1196 if ((child = find_named_node (node, "Routes")) == 0) {
1197 error << _("Session: XML state has no routes section") << endmsg;
1199 } else if (load_routes (*child)) {
1203 if ((child = find_named_node (node, "Click")) == 0) {
1204 warning << _("Session: XML state has no click section") << endmsg;
1205 } else if (_click_io) {
1206 _click_io->set_state (*child);
1209 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1210 ControlProtocolManager::instance().set_protocol_states (*child);
1213 /* here beginneth the second phase ... */
1215 StateReady (); /* EMIT SIGNAL */
1217 _state_of_the_state = Clean;
1219 if (state_was_pending) {
1220 save_state (_current_snapshot_name);
1221 remove_pending_capture_state ();
1222 state_was_pending = false;
1232 Session::load_routes (const XMLNode& node)
1235 XMLNodeConstIterator niter;
1236 RouteList new_routes;
1238 nlist = node.children();
1242 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1244 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1247 error << _("Session: cannot create Route from XML description.") << endmsg;
1251 new_routes.push_back (route);
1254 add_routes (new_routes);
1259 boost::shared_ptr<Route>
1260 Session::XMLRouteFactory (const XMLNode& node)
1262 if (node.name() != "Route") {
1263 return boost::shared_ptr<Route> ((Route*) 0);
1266 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1268 DataType type = DataType::AUDIO;
1269 const XMLProperty* prop = node.property("default-type");
1271 type = DataType(prop->value());
1273 assert(type != DataType::NIL);
1275 if (has_diskstream) {
1276 if (type == DataType::AUDIO) {
1277 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1280 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1284 boost::shared_ptr<Route> ret (new Route (*this, node));
1290 Session::load_regions (const XMLNode& node)
1293 XMLNodeConstIterator niter;
1294 boost::shared_ptr<Region> region;
1296 nlist = node.children();
1300 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1301 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1302 error << _("Session: cannot create Region from XML description.") << endmsg;
1309 boost::shared_ptr<Region>
1310 Session::XMLRegionFactory (const XMLNode& node, bool full)
1312 const XMLProperty* type = node.property("type");
1316 if ( !type || type->value() == "audio" ) {
1318 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1320 } else if (type->value() == "midi") {
1322 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1326 } catch (failed_constructor& err) {
1327 return boost::shared_ptr<Region> ();
1330 return boost::shared_ptr<Region> ();
1333 boost::shared_ptr<AudioRegion>
1334 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1336 const XMLProperty* prop;
1337 boost::shared_ptr<Source> source;
1338 boost::shared_ptr<AudioSource> as;
1340 uint32_t nchans = 1;
1343 if (node.name() != X_("Region")) {
1344 return boost::shared_ptr<AudioRegion>();
1347 if ((prop = node.property (X_("channels"))) != 0) {
1348 nchans = atoi (prop->value().c_str());
1351 if ((prop = node.property ("name")) == 0) {
1352 cerr << "no name for this region\n";
1356 if ((prop = node.property (X_("source-0"))) == 0) {
1357 if ((prop = node.property ("source")) == 0) {
1358 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1359 return boost::shared_ptr<AudioRegion>();
1363 PBD::ID s_id (prop->value());
1365 if ((source = source_by_id (s_id)) == 0) {
1366 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1367 return boost::shared_ptr<AudioRegion>();
1370 as = boost::dynamic_pointer_cast<AudioSource>(source);
1372 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1373 return boost::shared_ptr<AudioRegion>();
1376 sources.push_back (as);
1378 /* pickup other channels */
1380 for (uint32_t n=1; n < nchans; ++n) {
1381 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1382 if ((prop = node.property (buf)) != 0) {
1384 PBD::ID id2 (prop->value());
1386 if ((source = source_by_id (id2)) == 0) {
1387 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1388 return boost::shared_ptr<AudioRegion>();
1391 as = boost::dynamic_pointer_cast<AudioSource>(source);
1393 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1394 return boost::shared_ptr<AudioRegion>();
1396 sources.push_back (as);
1401 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1403 /* a final detail: this is the one and only place that we know how long missing files are */
1405 if (region->whole_file()) {
1406 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1407 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1409 sfp->set_length (region->length());
1418 catch (failed_constructor& err) {
1419 return boost::shared_ptr<AudioRegion>();
1423 boost::shared_ptr<MidiRegion>
1424 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1426 const XMLProperty* prop;
1427 boost::shared_ptr<Source> source;
1428 boost::shared_ptr<MidiSource> ms;
1430 uint32_t nchans = 1;
1432 if (node.name() != X_("Region")) {
1433 return boost::shared_ptr<MidiRegion>();
1436 if ((prop = node.property (X_("channels"))) != 0) {
1437 nchans = atoi (prop->value().c_str());
1440 if ((prop = node.property ("name")) == 0) {
1441 cerr << "no name for this region\n";
1445 // Multiple midi channels? that's just crazy talk
1446 assert(nchans == 1);
1448 if ((prop = node.property (X_("source-0"))) == 0) {
1449 if ((prop = node.property ("source")) == 0) {
1450 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1451 return boost::shared_ptr<MidiRegion>();
1455 PBD::ID s_id (prop->value());
1457 if ((source = source_by_id (s_id)) == 0) {
1458 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1459 return boost::shared_ptr<MidiRegion>();
1462 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1464 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1465 return boost::shared_ptr<MidiRegion>();
1468 sources.push_back (ms);
1471 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1472 /* a final detail: this is the one and only place that we know how long missing files are */
1474 if (region->whole_file()) {
1475 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1476 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1478 sfp->set_length (region->length());
1486 catch (failed_constructor& err) {
1487 return boost::shared_ptr<MidiRegion>();
1492 Session::get_sources_as_xml ()
1495 XMLNode* node = new XMLNode (X_("Sources"));
1496 Glib::Mutex::Lock lm (source_lock);
1498 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1499 node->add_child_nocopy (i->second->get_state());
1506 Session::path_from_region_name (string name, string identifier)
1508 char buf[PATH_MAX+1];
1510 SessionDirectory sdir(get_best_session_directory_for_new_source());
1511 string sound_dir = sdir.sound_path().to_string();
1513 for (n = 0; n < 999999; ++n) {
1514 if (identifier.length()) {
1515 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", sound_dir.c_str(), name.c_str(),
1516 identifier.c_str(), n);
1518 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", sound_dir.c_str(), name.c_str(), n);
1521 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1526 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1535 Session::load_sources (const XMLNode& node)
1538 XMLNodeConstIterator niter;
1539 boost::shared_ptr<Source> source;
1541 nlist = node.children();
1545 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1548 if ((source = XMLSourceFactory (**niter)) == 0) {
1549 error << _("Session: cannot create Source from XML description.") << endmsg;
1553 catch (non_existent_source& err) {
1554 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1555 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1562 boost::shared_ptr<Source>
1563 Session::XMLSourceFactory (const XMLNode& node)
1565 if (node.name() != "Source") {
1566 return boost::shared_ptr<Source>();
1570 return SourceFactory::create (*this, node);
1573 catch (failed_constructor& err) {
1574 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1575 return boost::shared_ptr<Source>();
1580 Session::save_template (string template_name)
1583 string xml_path, bak_path, template_path;
1585 if (_state_of_the_state & CannotSave) {
1589 sys::path user_template_dir(user_template_directory());
1593 sys::create_directories (user_template_dir);
1595 catch(sys::filesystem_error& ex)
1597 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1598 user_template_dir.to_string(), ex.what()) << endmsg;
1602 tree.set_root (&get_template());
1604 sys::path template_file_path(user_template_dir);
1605 template_file_path /= template_name + template_suffix;
1607 if (sys::exists (template_file_path))
1609 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1610 template_file_path.to_string()) << endmsg;
1614 if (!tree.write (template_file_path.to_string())) {
1615 error << _("mix template not saved") << endmsg;
1623 Session::refresh_disk_space ()
1626 struct statfs statfsbuf;
1627 vector<space_and_path>::iterator i;
1628 Glib::Mutex::Lock lm (space_lock);
1631 /* get freespace on every FS that is part of the session path */
1633 _total_free_4k_blocks = 0;
1635 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1636 statfs ((*i).path.c_str(), &statfsbuf);
1638 scale = statfsbuf.f_bsize/4096.0;
1640 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1641 _total_free_4k_blocks += (*i).blocks;
1647 Session::get_best_session_directory_for_new_source ()
1649 vector<space_and_path>::iterator i;
1650 string result = _session_dir->root_path().to_string();
1652 /* handle common case without system calls */
1654 if (session_dirs.size() == 1) {
1658 /* OK, here's the algorithm we're following here:
1660 We want to select which directory to use for
1661 the next file source to be created. Ideally,
1662 we'd like to use a round-robin process so as to
1663 get maximum performance benefits from splitting
1664 the files across multiple disks.
1666 However, in situations without much diskspace, an
1667 RR approach may end up filling up a filesystem
1668 with new files while others still have space.
1669 Its therefore important to pay some attention to
1670 the freespace in the filesystem holding each
1671 directory as well. However, if we did that by
1672 itself, we'd keep creating new files in the file
1673 system with the most space until it was as full
1674 as all others, thus negating any performance
1675 benefits of this RAID-1 like approach.
1677 So, we use a user-configurable space threshold. If
1678 there are at least 2 filesystems with more than this
1679 much space available, we use RR selection between them.
1680 If not, then we pick the filesystem with the most space.
1682 This gets a good balance between the two
1686 refresh_disk_space ();
1688 int free_enough = 0;
1690 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1691 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1696 if (free_enough >= 2) {
1697 /* use RR selection process, ensuring that the one
1701 i = last_rr_session_dir;
1704 if (++i == session_dirs.end()) {
1705 i = session_dirs.begin();
1708 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1709 if (create_session_directory ((*i).path)) {
1711 last_rr_session_dir = i;
1716 } while (i != last_rr_session_dir);
1720 /* pick FS with the most freespace (and that
1721 seems to actually work ...)
1724 vector<space_and_path> sorted;
1725 space_and_path_ascending_cmp cmp;
1727 sorted = session_dirs;
1728 sort (sorted.begin(), sorted.end(), cmp);
1730 for (i = sorted.begin(); i != sorted.end(); ++i) {
1731 if (create_session_directory ((*i).path)) {
1733 last_rr_session_dir = i;
1743 Session::load_playlists (const XMLNode& node)
1746 XMLNodeConstIterator niter;
1747 boost::shared_ptr<Playlist> playlist;
1749 nlist = node.children();
1753 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1755 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1756 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1764 Session::load_unused_playlists (const XMLNode& node)
1767 XMLNodeConstIterator niter;
1768 boost::shared_ptr<Playlist> playlist;
1770 nlist = node.children();
1774 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1776 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1777 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1781 // now manually untrack it
1783 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1789 boost::shared_ptr<Playlist>
1790 Session::XMLPlaylistFactory (const XMLNode& node)
1793 return PlaylistFactory::create (*this, node);
1796 catch (failed_constructor& err) {
1797 return boost::shared_ptr<Playlist>();
1802 Session::load_named_selections (const XMLNode& node)
1805 XMLNodeConstIterator niter;
1808 nlist = node.children();
1812 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1814 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1815 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1823 Session::XMLNamedSelectionFactory (const XMLNode& node)
1826 return new NamedSelection (*this, node);
1829 catch (failed_constructor& err) {
1835 Session::automation_dir () const
1838 res += "automation/";
1843 Session::template_dir ()
1845 string path = get_user_ardour_path();
1846 path += "templates/";
1852 Session::suffixed_search_path (string suffix, bool data)
1856 path += get_user_ardour_path();
1857 if (path[path.length()-1] != ':') {
1862 path += get_system_data_path();
1864 path += get_system_module_path();
1867 vector<string> split_path;
1869 split (path, split_path, ':');
1872 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
1877 if (distance (i, split_path.end()) != 1) {
1886 Session::control_protocol_path ()
1888 return suffixed_search_path (surfaces_dir_name, false);
1892 Session::load_bundles (const XMLNode& node)
1894 XMLNodeList nlist = node.children();
1895 XMLNodeConstIterator niter;
1899 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1900 if ((*niter)->name() == "InputConnection") {
1901 add_bundle (new ARDOUR::InputBundle (**niter));
1902 } else if ((*niter)->name() == "OutputConnection") {
1903 add_bundle (new ARDOUR::OutputBundle (**niter));
1905 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1914 Session::load_edit_groups (const XMLNode& node)
1916 return load_route_groups (node, true);
1920 Session::load_mix_groups (const XMLNode& node)
1922 return load_route_groups (node, false);
1926 Session::load_route_groups (const XMLNode& node, bool edit)
1928 XMLNodeList nlist = node.children();
1929 XMLNodeConstIterator niter;
1934 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1935 if ((*niter)->name() == "RouteGroup") {
1937 rg = add_edit_group ("");
1938 rg->set_state (**niter);
1940 rg = add_mix_group ("");
1941 rg->set_state (**niter);
1950 state_file_filter (const string &str, void *arg)
1952 return (str.length() > strlen(statefile_suffix) &&
1953 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
1957 bool operator()(const string* a, const string* b) {
1963 remove_end(string* state)
1965 string statename(*state);
1967 string::size_type start,end;
1968 if ((start = statename.find_last_of ('/')) != string::npos) {
1969 statename = statename.substr (start+1);
1972 if ((end = statename.rfind(".ardour")) == string::npos) {
1973 end = statename.length();
1976 return new string(statename.substr (0, end));
1980 Session::possible_states (string path)
1982 PathScanner scanner;
1983 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
1985 transform(states->begin(), states->end(), states->begin(), remove_end);
1988 sort (states->begin(), states->end(), cmp);
1994 Session::possible_states () const
1996 return possible_states(_path);
2000 Session::auto_save()
2002 save_state (_current_snapshot_name);
2006 Session::add_edit_group (string name)
2008 RouteGroup* rg = new RouteGroup (*this, name);
2009 edit_groups.push_back (rg);
2010 edit_group_added (rg); /* EMIT SIGNAL */
2016 Session::add_mix_group (string name)
2018 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2019 mix_groups.push_back (rg);
2020 mix_group_added (rg); /* EMIT SIGNAL */
2026 Session::remove_edit_group (RouteGroup& rg)
2028 list<RouteGroup*>::iterator i;
2030 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2031 (*i)->apply (&Route::drop_edit_group, this);
2032 edit_groups.erase (i);
2033 edit_group_removed (); /* EMIT SIGNAL */
2040 Session::remove_mix_group (RouteGroup& rg)
2042 list<RouteGroup*>::iterator i;
2044 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2045 (*i)->apply (&Route::drop_mix_group, this);
2046 mix_groups.erase (i);
2047 mix_group_removed (); /* EMIT SIGNAL */
2054 Session::mix_group_by_name (string name)
2056 list<RouteGroup *>::iterator i;
2058 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2059 if ((*i)->name() == name) {
2067 Session::edit_group_by_name (string name)
2069 list<RouteGroup *>::iterator i;
2071 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2072 if ((*i)->name() == name) {
2080 Session::begin_reversible_command (string name)
2082 current_trans = new UndoTransaction;
2083 current_trans->set_name (name);
2087 Session::commit_reversible_command (Command *cmd)
2092 current_trans->add_command (cmd);
2095 gettimeofday (&now, 0);
2096 current_trans->set_timestamp (now);
2098 _history.add (current_trans);
2101 Session::GlobalRouteBooleanState
2102 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2104 GlobalRouteBooleanState s;
2105 boost::shared_ptr<RouteList> r = routes.reader ();
2107 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2108 if (!(*i)->hidden()) {
2109 RouteBooleanState v;
2112 Route* r = (*i).get();
2113 v.second = (r->*method)();
2122 Session::GlobalRouteMeterState
2123 Session::get_global_route_metering ()
2125 GlobalRouteMeterState s;
2126 boost::shared_ptr<RouteList> r = routes.reader ();
2128 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2129 if (!(*i)->hidden()) {
2133 v.second = (*i)->meter_point();
2143 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2145 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2147 boost::shared_ptr<Route> r = (i->first.lock());
2150 r->set_meter_point (i->second, arg);
2156 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2158 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2160 boost::shared_ptr<Route> r = (i->first.lock());
2163 Route* rp = r.get();
2164 (rp->*method) (i->second, arg);
2170 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2172 set_global_route_boolean (s, &Route::set_mute, src);
2176 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2178 set_global_route_boolean (s, &Route::set_solo, src);
2182 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2184 set_global_route_boolean (s, &Route::set_record_enable, src);
2189 Session::global_mute_memento (void* src)
2191 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2195 Session::global_metering_memento (void* src)
2197 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2201 Session::global_solo_memento (void* src)
2203 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2207 Session::global_record_enable_memento (void* src)
2209 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2214 accept_all_non_peak_files (const string& path, void *arg)
2216 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2220 accept_all_state_files (const string& path, void *arg)
2222 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2226 Session::find_all_sources (string path, set<string>& result)
2231 if (!tree.read (path)) {
2235 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2240 XMLNodeConstIterator niter;
2242 nlist = node->children();
2246 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2250 if ((prop = (*niter)->property (X_("name"))) == 0) {
2254 if (prop->value()[0] == '/') {
2255 /* external file, ignore */
2259 sys::path source_path = _session_dir->sound_path ();
2261 source_path /= prop->value ();
2263 result.insert (source_path.to_string ());
2270 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2272 PathScanner scanner;
2273 vector<string*>* state_files;
2275 string this_snapshot_path;
2281 if (ripped[ripped.length()-1] == '/') {
2282 ripped = ripped.substr (0, ripped.length() - 1);
2285 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2287 if (state_files == 0) {
2292 this_snapshot_path = _path;
2293 this_snapshot_path += _current_snapshot_name;
2294 this_snapshot_path += statefile_suffix;
2296 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2298 if (exclude_this_snapshot && **i == this_snapshot_path) {
2302 if (find_all_sources (**i, result) < 0) {
2310 struct RegionCounter {
2311 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2312 AudioSourceList::iterator iter;
2313 boost::shared_ptr<Region> region;
2316 RegionCounter() : count (0) {}
2320 Session::cleanup_sources (Session::cleanup_report& rep)
2322 // FIXME: needs adaptation to midi
2324 vector<boost::shared_ptr<Source> > dead_sources;
2325 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2326 PathScanner scanner;
2328 vector<space_and_path>::iterator i;
2329 vector<space_and_path>::iterator nexti;
2330 vector<string*>* soundfiles;
2331 vector<string> unused;
2332 set<string> all_sources;
2337 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2339 /* step 1: consider deleting all unused playlists */
2341 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2344 status = AskAboutPlaylistDeletion (*x);
2353 playlists_tbd.push_back (*x);
2357 /* leave it alone */
2362 /* now delete any that were marked for deletion */
2364 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2365 (*x)->drop_references ();
2368 playlists_tbd.clear ();
2370 /* step 2: find all un-used sources */
2375 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2377 SourceMap::iterator tmp;
2382 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2386 if (!i->second->used() && i->second->length() > 0) {
2387 dead_sources.push_back (i->second);
2388 i->second->GoingAway();
2394 /* build a list of all the possible sound directories for the session */
2396 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2401 SessionDirectory sdir ((*i).path);
2402 sound_path += sdir.sound_path().to_string();
2404 if (nexti != session_dirs.end()) {
2411 /* now do the same thing for the files that ended up in the sounds dir(s)
2412 but are not referenced as sources in any snapshot.
2415 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2417 if (soundfiles == 0) {
2421 /* find all sources, but don't use this snapshot because the
2422 state file on disk still references sources we may have already
2426 find_all_sources_across_snapshots (all_sources, true);
2428 /* add our current source list
2431 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2432 boost::shared_ptr<AudioFileSource> fs;
2434 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2435 all_sources.insert (fs->path());
2439 char tmppath1[PATH_MAX+1];
2440 char tmppath2[PATH_MAX+1];
2442 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2447 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2449 realpath(spath.c_str(), tmppath1);
2450 realpath((*i).c_str(), tmppath2);
2452 if (strcmp(tmppath1, tmppath2) == 0) {
2459 unused.push_back (spath);
2463 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2465 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2466 struct stat statbuf;
2468 rep.paths.push_back (*x);
2469 if (stat ((*x).c_str(), &statbuf) == 0) {
2470 rep.space += statbuf.st_size;
2475 /* don't move the file across filesystems, just
2476 stick it in the `dead_sound_dir_name' directory
2477 on whichever filesystem it was already on.
2480 if ((*x).find ("/sounds/") != string::npos) {
2482 /* old school, go up 1 level */
2484 newpath = Glib::path_get_dirname (*x); // "sounds"
2485 newpath = Glib::path_get_dirname (newpath); // "session-name"
2489 /* new school, go up 4 levels */
2491 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2492 newpath = Glib::path_get_dirname (newpath); // "session-name"
2493 newpath = Glib::path_get_dirname (newpath); // "interchange"
2494 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2498 newpath += dead_sound_dir_name;
2500 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2501 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2506 newpath += Glib::path_get_basename ((*x));
2508 if (access (newpath.c_str(), F_OK) == 0) {
2510 /* the new path already exists, try versioning */
2512 char buf[PATH_MAX+1];
2516 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2519 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2520 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2524 if (version == 999) {
2525 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2529 newpath = newpath_v;
2534 /* it doesn't exist, or we can't read it or something */
2538 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2539 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2540 (*x), newpath, strerror (errno))
2545 /* see if there an easy to find peakfile for this file, and remove it.
2548 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2549 peakpath += peakfile_suffix;
2551 if (access (peakpath.c_str(), W_OK) == 0) {
2552 if (::unlink (peakpath.c_str()) != 0) {
2553 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2554 peakpath, _path, strerror (errno))
2556 /* try to back out */
2557 rename (newpath.c_str(), _path.c_str());
2565 /* dump the history list */
2569 /* save state so we don't end up a session file
2570 referring to non-existent sources.
2576 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2581 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2583 // FIXME: needs adaptation for MIDI
2585 vector<space_and_path>::iterator i;
2586 string dead_sound_dir;
2587 struct dirent* dentry;
2588 struct stat statbuf;
2594 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2596 dead_sound_dir = (*i).path;
2597 dead_sound_dir += dead_sound_dir_name;
2599 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2603 while ((dentry = readdir (dead)) != 0) {
2605 /* avoid '.' and '..' */
2607 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2608 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2614 fullpath = dead_sound_dir;
2616 fullpath += dentry->d_name;
2618 if (stat (fullpath.c_str(), &statbuf)) {
2622 if (!S_ISREG (statbuf.st_mode)) {
2626 if (unlink (fullpath.c_str())) {
2627 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2628 fullpath, strerror (errno))
2632 rep.paths.push_back (dentry->d_name);
2633 rep.space += statbuf.st_size;
2644 Session::set_dirty ()
2646 bool was_dirty = dirty();
2648 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2651 DirtyChanged(); /* EMIT SIGNAL */
2657 Session::set_clean ()
2659 bool was_dirty = dirty();
2661 _state_of_the_state = Clean;
2664 DirtyChanged(); /* EMIT SIGNAL */
2669 Session::set_deletion_in_progress ()
2671 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2675 Session::add_controllable (Controllable* c)
2677 /* this adds a controllable to the list managed by the Session.
2678 this is a subset of those managed by the Controllable class
2679 itself, and represents the only ones whose state will be saved
2680 as part of the session.
2683 Glib::Mutex::Lock lm (controllables_lock);
2684 controllables.insert (c);
2688 Session::remove_controllable (Controllable* c)
2690 if (_state_of_the_state | Deletion) {
2694 Glib::Mutex::Lock lm (controllables_lock);
2696 Controllables::iterator x = controllables.find (c);
2698 if (x != controllables.end()) {
2699 controllables.erase (x);
2704 Session::controllable_by_id (const PBD::ID& id)
2706 Glib::Mutex::Lock lm (controllables_lock);
2708 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2709 if ((*i)->id() == id) {
2718 Session::add_instant_xml (XMLNode& node)
2720 Stateful::add_instant_xml (node, _path);
2721 Config->add_instant_xml (node);
2725 Session::instant_xml (const string& node_name)
2727 return Stateful::instant_xml (node_name, _path);
2731 Session::save_history (string snapshot_name)
2737 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2739 if (snapshot_name.empty()) {
2740 snapshot_name = _current_snapshot_name;
2743 xml_path = _path + snapshot_name + ".history";
2745 bak_path = xml_path + ".bak";
2747 if ((access (xml_path.c_str(), F_OK) == 0) &&
2748 (rename (xml_path.c_str(), bak_path.c_str())))
2750 error << _("could not backup old history file, current history not saved.") << endmsg;
2754 if (!tree.write (xml_path))
2756 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2758 /* don't leave a corrupt file lying around if it is
2762 if (unlink (xml_path.c_str())) {
2763 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2765 if (rename (bak_path.c_str(), xml_path.c_str()))
2767 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2778 Session::restore_history (string snapshot_name)
2783 if (snapshot_name.empty()) {
2784 snapshot_name = _current_snapshot_name;
2788 xmlpath = _path + snapshot_name + ".history";
2789 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2791 if (access (xmlpath.c_str(), F_OK)) {
2792 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2796 if (!tree.read (xmlpath)) {
2797 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2801 /* replace history */
2804 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2807 UndoTransaction* ut = new UndoTransaction ();
2810 ut->set_name(t->property("name")->value());
2811 stringstream ss(t->property("tv_sec")->value());
2813 ss.str(t->property("tv_usec")->value());
2815 ut->set_timestamp(tv);
2817 for (XMLNodeConstIterator child_it = t->children().begin();
2818 child_it != t->children().end();
2821 XMLNode *n = *child_it;
2824 if (n->name() == "MementoCommand" ||
2825 n->name() == "MementoUndoCommand" ||
2826 n->name() == "MementoRedoCommand") {
2828 if ((c = memento_command_factory(n))) {
2832 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2834 if ((c = global_state_command_factory (*n))) {
2835 ut->add_command (c);
2840 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2851 Session::config_changed (const char* parameter_name)
2853 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2855 if (PARAM_IS ("seamless-loop")) {
2857 } else if (PARAM_IS ("rf-speed")) {
2859 } else if (PARAM_IS ("auto-loop")) {
2861 } else if (PARAM_IS ("auto-input")) {
2863 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2864 /* auto-input only makes a difference if we're rolling */
2866 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2868 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2869 if ((*i)->record_enabled ()) {
2870 (*i)->monitor_input (!Config->get_auto_input());
2875 } else if (PARAM_IS ("punch-in")) {
2879 if ((location = _locations.auto_punch_location()) != 0) {
2881 if (Config->get_punch_in ()) {
2882 replace_event (Event::PunchIn, location->start());
2884 remove_event (location->start(), Event::PunchIn);
2888 } else if (PARAM_IS ("punch-out")) {
2892 if ((location = _locations.auto_punch_location()) != 0) {
2894 if (Config->get_punch_out()) {
2895 replace_event (Event::PunchOut, location->end());
2897 clear_events (Event::PunchOut);
2901 } else if (PARAM_IS ("edit-mode")) {
2903 Glib::Mutex::Lock lm (playlist_lock);
2905 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2906 (*i)->set_edit_mode (Config->get_edit_mode ());
2909 } else if (PARAM_IS ("use-video-sync")) {
2911 waiting_for_sync_offset = Config->get_use_video_sync();
2913 } else if (PARAM_IS ("mmc-control")) {
2915 //poke_midi_thread ();
2917 } else if (PARAM_IS ("mmc-device-id")) {
2920 mmc->set_device_id (Config->get_mmc_device_id());
2923 } else if (PARAM_IS ("midi-control")) {
2925 //poke_midi_thread ();
2927 } else if (PARAM_IS ("raid-path")) {
2929 setup_raid_path (Config->get_raid_path());
2931 } else if (PARAM_IS ("smpte-format")) {
2935 } else if (PARAM_IS ("video-pullup")) {
2939 } else if (PARAM_IS ("seamless-loop")) {
2941 if (play_loop && transport_rolling()) {
2942 // to reset diskstreams etc
2943 request_play_loop (true);
2946 } else if (PARAM_IS ("rf-speed")) {
2948 cumulative_rf_motion = 0;
2951 } else if (PARAM_IS ("click-sound")) {
2953 setup_click_sounds (1);
2955 } else if (PARAM_IS ("click-emphasis-sound")) {
2957 setup_click_sounds (-1);
2959 } else if (PARAM_IS ("clicking")) {
2961 if (Config->get_clicking()) {
2962 if (_click_io && click_data) { // don't require emphasis data
2969 } else if (PARAM_IS ("send-mtc")) {
2971 /* only set the internal flag if we have
2975 if (_mtc_port != 0) {
2976 session_send_mtc = Config->get_send_mtc();
2977 if (session_send_mtc) {
2978 /* mark us ready to send */
2979 next_quarter_frame_to_send = 0;
2982 session_send_mtc = false;
2985 } else if (PARAM_IS ("send-mmc")) {
2987 /* only set the internal flag if we have
2991 if (_mmc_port != 0) {
2992 session_send_mmc = Config->get_send_mmc();
2995 session_send_mmc = false;
2998 } else if (PARAM_IS ("midi-feedback")) {
3000 /* only set the internal flag if we have
3004 if (_mtc_port != 0) {
3005 session_midi_feedback = Config->get_midi_feedback();
3008 } else if (PARAM_IS ("jack-time-master")) {
3010 engine().reset_timebase ();
3012 } else if (PARAM_IS ("native-file-header-format")) {
3014 if (!first_file_header_format_reset) {
3015 reset_native_file_format ();
3018 first_file_header_format_reset = false;
3020 } else if (PARAM_IS ("native-file-data-format")) {
3022 if (!first_file_data_format_reset) {
3023 reset_native_file_format ();
3026 first_file_data_format_reset = false;
3028 } else if (PARAM_IS ("slave-source")) {
3029 set_slave_source (Config->get_slave_source());
3030 } else if (PARAM_IS ("remote-model")) {
3031 set_remote_control_ids ();
3032 } else if (PARAM_IS ("denormal-model")) {