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.
25 #include <sigc++/bind.h>
27 #include <cstdio> /* snprintf(3) ... grrr */
42 #include <sys/param.h>
43 #include <sys/mount.h>
48 #include <midi++/mmc.h>
49 #include <midi++/port.h>
50 #include <pbd/error.h>
52 #include <glibmm/thread.h>
53 #include <pbd/pathscanner.h>
54 #include <pbd/pthread_utils.h>
55 #include <pbd/strsplit.h>
56 #include <pbd/stacktrace.h>
57 #include <pbd/copyfile.h>
59 #include <ardour/audioengine.h>
60 #include <ardour/configuration.h>
61 #include <ardour/session.h>
62 #include <ardour/audio_diskstream.h>
63 #include <ardour/utils.h>
64 #include <ardour/audioplaylist.h>
65 #include <ardour/audiofilesource.h>
66 #include <ardour/silentfilesource.h>
67 #include <ardour/sndfilesource.h>
68 #include <ardour/sndfile_helpers.h>
69 #include <ardour/auditioner.h>
70 #include <ardour/export.h>
71 #include <ardour/redirect.h>
72 #include <ardour/send.h>
73 #include <ardour/insert.h>
74 #include <ardour/connection.h>
75 #include <ardour/slave.h>
76 #include <ardour/tempo.h>
77 #include <ardour/audio_track.h>
78 #include <ardour/cycle_timer.h>
79 #include <ardour/utils.h>
80 #include <ardour/named_selection.h>
81 #include <ardour/version.h>
82 #include <ardour/location.h>
83 #include <ardour/audioregion.h>
84 #include <ardour/crossfade.h>
85 #include <ardour/control_protocol_manager.h>
86 #include <ardour/region_factory.h>
87 #include <ardour/source_factory.h>
88 #include <ardour/playlist_factory.h>
90 #include <control_protocol/control_protocol.h>
96 using namespace ARDOUR;
100 Session::first_stage_init (string fullpath, string snapshot_name)
102 if (fullpath.length() == 0) {
104 throw failed_constructor();
107 char buf[PATH_MAX+1];
108 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
109 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
111 throw failed_constructor();
116 if (_path[_path.length()-1] != '/') {
120 /* these two are just provisional settings. set_state()
121 will likely override them.
124 _name = _current_snapshot_name = snapshot_name;
126 _current_frame_rate = _engine.frame_rate ();
127 _tempo_map = new TempoMap (_current_frame_rate);
128 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
130 g_atomic_int_set (&processing_prohibited, 0);
132 _transport_speed = 0;
133 _last_transport_speed = 0;
134 auto_play_legal = false;
135 transport_sub_state = 0;
136 _transport_frame = 0;
138 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
139 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
140 _end_location_is_free = true;
141 g_atomic_int_set (&_record_status, Disabled);
142 loop_changing = false;
144 _last_roll_location = 0;
145 _last_record_location = 0;
146 pending_locate_frame = 0;
147 pending_locate_roll = false;
148 pending_locate_flush = false;
149 dstream_buffer_size = 0;
151 state_was_pending = false;
153 outbound_mtc_smpte_frame = 0;
154 next_quarter_frame_to_send = -1;
155 current_block_size = 0;
156 solo_update_disabled = false;
157 currently_soloing = false;
158 _have_captured = false;
159 _worst_output_latency = 0;
160 _worst_input_latency = 0;
161 _worst_track_latency = 0;
162 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
164 butler_mixdown_buffer = 0;
165 butler_gain_buffer = 0;
167 session_send_mmc = false;
168 session_send_mtc = false;
169 post_transport_work = PostTransportWork (0);
170 g_atomic_int_set (&butler_should_do_transport_work, 0);
171 g_atomic_int_set (&butler_active, 0);
172 g_atomic_int_set (&_playback_load, 100);
173 g_atomic_int_set (&_capture_load, 100);
174 g_atomic_int_set (&_playback_load_min, 100);
175 g_atomic_int_set (&_capture_load_min, 100);
177 waiting_to_start = false;
179 _gain_automation_buffer = 0;
180 _pan_automation_buffer = 0;
182 pending_abort = false;
183 destructive_index = 0;
185 first_file_data_format_reset = true;
186 first_file_header_format_reset = true;
187 butler_thread = (pthread_t) 0;
188 midi_thread = (pthread_t) 0;
190 AudioDiskstream::allocate_working_buffers();
192 /* default short fade = 15ms */
194 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
195 SndFileSource::setup_standard_crossfades (frame_rate());
197 last_mmc_step.tv_sec = 0;
198 last_mmc_step.tv_usec = 0;
201 /* click sounds are unset by default, which causes us to internal
202 waveforms for clicks.
206 click_emphasis_data = 0;
208 click_emphasis_length = 0;
211 process_function = &Session::process_with_events;
213 if (Config->get_use_video_sync()) {
214 waiting_for_sync_offset = true;
216 waiting_for_sync_offset = false;
219 _current_frame_rate = 48000;
220 _base_frame_rate = 48000;
224 _smpte_offset_negative = true;
225 last_smpte_valid = false;
229 last_rr_session_dir = session_dirs.begin();
230 refresh_disk_space ();
232 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
236 average_slave_delta = 1800;
237 have_first_delta_accumulator = false;
238 delta_accumulator_cnt = 0;
239 slave_state = Stopped;
241 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
243 /* These are all static "per-class" signals */
245 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
246 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
247 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
248 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
249 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
250 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
252 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
254 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
256 /* stop IO objects from doing stuff until we're ready for them */
258 IO::disable_panners ();
259 IO::disable_ports ();
260 IO::disable_connecting ();
264 Session::second_stage_init (bool new_session)
266 AudioFileSource::set_peak_dir (peak_dir());
269 if (load_state (_current_snapshot_name)) {
272 remove_empty_sounds ();
275 if (start_butler_thread()) {
279 if (start_midi_thread ()) {
283 // set_state() will call setup_raid_path(), but if it's a new session we need
284 // to call setup_raid_path() here.
286 if (set_state (*state_tree->root())) {
290 setup_raid_path(_path);
293 /* we can't save till after ::when_engine_running() is called,
294 because otherwise we save state with no connections made.
295 therefore, we reset _state_of_the_state because ::set_state()
296 will have cleared it.
298 we also have to include Loading so that any events that get
299 generated between here and the end of ::when_engine_running()
300 will be processed directly rather than queued.
303 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
305 // set_auto_input (true);
306 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
307 _locations.added.connect (mem_fun (this, &Session::locations_added));
308 setup_click_sounds (0);
309 setup_midi_control ();
311 /* Pay attention ... */
313 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
314 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
317 when_engine_running();
320 /* handle this one in a different way than all others, so that its clear what happened */
322 catch (AudioEngine::PortRegistrationFailure& err) {
323 error << _("Unable to create all required ports")
332 send_full_time_code ();
333 _engine.transport_locate (0);
334 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
335 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
337 ControlProtocolManager::instance().set_session (*this);
340 _end_location_is_free = true;
342 _end_location_is_free = false;
349 Session::raid_path () const
353 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
358 return path.substr (0, path.length() - 1); // drop final colon
362 Session::setup_raid_path (string path)
364 string::size_type colon;
368 string::size_type len = path.length();
373 if (path.length() == 0) {
377 session_dirs.clear ();
379 for (string::size_type n = 0; n < len; ++n) {
380 if (path[n] == ':') {
387 /* no multiple search path, just one location (common case) */
391 session_dirs.push_back (sp);
398 if (fspath[fspath.length()-1] != '/') {
402 fspath += sound_dir (false);
404 AudioFileSource::set_search_path (fspath);
411 while ((colon = remaining.find_first_of (':')) != string::npos) {
414 sp.path = remaining.substr (0, colon);
415 session_dirs.push_back (sp);
417 /* add sounds to file search path */
420 if (fspath[fspath.length()-1] != '/') {
423 fspath += sound_dir (false);
426 remaining = remaining.substr (colon+1);
429 if (remaining.length()) {
436 if (fspath[fspath.length()-1] != '/') {
439 fspath += sound_dir (false);
442 session_dirs.push_back (sp);
445 /* set the AudioFileSource search path */
447 AudioFileSource::set_search_path (fspath);
449 /* reset the round-robin soundfile path thingie */
451 last_rr_session_dir = session_dirs.begin();
455 Session::create (bool& new_session, string* mix_template, nframes_t initial_length)
459 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
460 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
466 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
467 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
471 /* if this is is an existing session with an old "sounds" directory, just use it. see Session::sound_dir() for more details */
473 if (!Glib::file_test (old_sound_dir(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
477 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
478 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
483 dir = dead_sound_dir ();
485 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
486 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
490 dir = automation_dir ();
492 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
493 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
499 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
500 error << string_compose(_("Session: cannot create session export dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
505 /* check new_session so we don't overwrite an existing one */
508 std::string in_path = *mix_template;
510 ifstream in(in_path.c_str());
513 string out_path = _path;
515 out_path += _statefile_suffix;
517 ofstream out(out_path.c_str());
522 // okay, session is set up. Treat like normal saved
523 // session from now on.
529 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
535 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
542 /* set initial start + end point */
544 start_location->set_end (0);
545 _locations.add (start_location);
547 end_location->set_end (initial_length);
548 _locations.add (end_location);
550 _state_of_the_state = Clean;
552 if (save_state (_current_snapshot_name)) {
560 Session::load_diskstreams (const XMLNode& node)
563 XMLNodeConstIterator citer;
565 clist = node.children();
567 for (citer = clist.begin(); citer != clist.end(); ++citer) {
571 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
572 add_diskstream (dstream);
575 catch (failed_constructor& err) {
576 error << _("Session: could not load diskstream via XML state") << endmsg;
585 Session::remove_pending_capture_state ()
590 xml_path += _current_snapshot_name;
591 xml_path += _pending_suffix;
593 unlink (xml_path.c_str());
597 Session::save_state (string snapshot_name, bool pending)
603 if (_state_of_the_state & CannotSave) {
607 if (!_engine.connected ()) {
608 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
613 tree.set_root (&get_state());
615 if (snapshot_name.empty()) {
616 snapshot_name = _current_snapshot_name;
622 xml_path += snapshot_name;
623 xml_path += _statefile_suffix;
628 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
629 copy_file (xml_path, bak_path);
635 xml_path += snapshot_name;
636 xml_path += _pending_suffix;
643 tmp_path += snapshot_name;
646 cerr << "actually writing state\n";
648 if (!tree.write (tmp_path)) {
649 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
650 unlink (tmp_path.c_str());
655 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
656 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
657 unlink (tmp_path.c_str());
664 save_history (snapshot_name);
666 bool was_dirty = dirty();
668 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
671 DirtyChanged (); /* EMIT SIGNAL */
674 StateSaved (snapshot_name); /* EMIT SIGNAL */
681 Session::restore_state (string snapshot_name)
683 if (load_state (snapshot_name) == 0) {
684 set_state (*state_tree->root());
691 Session::load_state (string snapshot_name)
700 state_was_pending = false;
702 /* check for leftover pending state from a crashed capture attempt */
705 xmlpath += snapshot_name;
706 xmlpath += _pending_suffix;
708 if (!access (xmlpath.c_str(), F_OK)) {
710 /* there is pending state from a crashed capture attempt */
712 if (AskAboutPendingState()) {
713 state_was_pending = true;
717 if (!state_was_pending) {
720 xmlpath += snapshot_name;
721 xmlpath += _statefile_suffix;
724 if (access (xmlpath.c_str(), F_OK)) {
725 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
729 state_tree = new XMLTree;
733 if (!state_tree->read (xmlpath)) {
734 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
740 XMLNode& root (*state_tree->root());
742 if (root.name() != X_("Session")) {
743 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
749 const XMLProperty* prop;
752 if ((prop = root.property ("version")) == 0) {
753 /* no version implies very old version of Ardour */
757 major_version = atoi (prop->value()); // grab just the first number before the period
758 if (major_version < 2) {
766 backup_path = xmlpath;
769 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
770 xmlpath, backup_path)
773 copy_file (xmlpath, backup_path);
775 /* if it fails, don't worry. right? */
782 Session::load_options (const XMLNode& node)
786 LocaleGuard lg (X_("POSIX"));
788 Config->set_variables (node, ConfigVariableBase::Session);
790 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
791 if ((prop = child->property ("val")) != 0) {
792 _end_location_is_free = (prop->value() == "yes");
800 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
802 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
803 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
805 return owner & modified_by_session_or_user;
809 Session::get_options () const
812 LocaleGuard lg (X_("POSIX"));
814 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
816 child = option_root.add_child ("end-marker-is-free");
817 child->add_property ("val", _end_location_is_free ? "yes" : "no");
829 Session::get_template()
831 /* if we don't disable rec-enable, diskstreams
832 will believe they need to store their capture
833 sources in their state node.
836 disable_record (false);
842 Session::state(bool full_state)
844 XMLNode* node = new XMLNode("Session");
847 // store libardour version, just in case
849 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
850 libardour_major_version, libardour_minor_version, libardour_micro_version);
851 node->add_property("version", string(buf));
853 /* store configuration settings */
858 node->add_property ("name", _name);
860 if (session_dirs.size() > 1) {
864 vector<space_and_path>::iterator i = session_dirs.begin();
865 vector<space_and_path>::iterator next;
867 ++i; /* skip the first one */
871 while (i != session_dirs.end()) {
875 if (next != session_dirs.end()) {
885 child = node->add_child ("Path");
886 child->add_content (p);
890 /* save the ID counter */
892 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
893 node->add_property ("id-counter", buf);
895 /* various options */
897 node->add_child_nocopy (get_options());
899 child = node->add_child ("Sources");
902 Glib::Mutex::Lock sl (audio_source_lock);
904 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
906 /* Don't save information about AudioFileSources that are empty */
908 boost::shared_ptr<AudioFileSource> fs;
910 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
912 /* destructive file sources are OK if they are empty, because
913 we will re-use them every time.
916 if (!fs->destructive()) {
917 if (fs->length() == 0) {
923 child->add_child_nocopy (siter->second->get_state());
927 child = node->add_child ("Regions");
930 Glib::Mutex::Lock rl (region_lock);
932 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
934 /* only store regions not attached to playlists */
936 if (i->second->playlist() == 0) {
937 child->add_child_nocopy (i->second->state (true));
942 child = node->add_child ("DiskStreams");
945 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
946 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
947 if (!(*i)->hidden()) {
948 child->add_child_nocopy ((*i)->get_state());
954 node->add_child_nocopy (_locations.get_state());
956 // for a template, just create a new Locations, populate it
957 // with the default start and end, and get the state for that.
959 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
960 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
963 end->set_end(compute_initial_length());
965 node->add_child_nocopy (loc.get_state());
968 child = node->add_child ("Connections");
970 Glib::Mutex::Lock lm (connection_lock);
971 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
972 if (!(*i)->system_dependent()) {
973 child->add_child_nocopy ((*i)->get_state());
978 child = node->add_child ("Routes");
980 boost::shared_ptr<RouteList> r = routes.reader ();
982 RoutePublicOrderSorter cmp;
983 RouteList public_order (*r);
984 public_order.sort (cmp);
986 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
987 if (!(*i)->hidden()) {
989 child->add_child_nocopy ((*i)->get_state());
991 child->add_child_nocopy ((*i)->get_template());
998 child = node->add_child ("EditGroups");
999 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1000 child->add_child_nocopy ((*i)->get_state());
1003 child = node->add_child ("MixGroups");
1004 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1005 child->add_child_nocopy ((*i)->get_state());
1008 child = node->add_child ("Playlists");
1009 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1010 if (!(*i)->hidden()) {
1011 if (!(*i)->empty()) {
1013 child->add_child_nocopy ((*i)->get_state());
1015 child->add_child_nocopy ((*i)->get_template());
1021 child = node->add_child ("UnusedPlaylists");
1022 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1023 if (!(*i)->hidden()) {
1024 if (!(*i)->empty()) {
1026 child->add_child_nocopy ((*i)->get_state());
1028 child->add_child_nocopy ((*i)->get_template());
1036 child = node->add_child ("Click");
1037 child->add_child_nocopy (_click_io->state (full_state));
1041 child = node->add_child ("NamedSelections");
1042 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1044 child->add_child_nocopy ((*i)->get_state());
1049 node->add_child_nocopy (_tempo_map->get_state());
1051 node->add_child_nocopy (get_control_protocol_state());
1054 node->add_child_copy (*_extra_xml);
1061 Session::get_control_protocol_state ()
1063 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1064 return cpm.get_state();
1068 Session::set_state (const XMLNode& node)
1072 const XMLProperty* prop;
1075 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1077 if (node.name() != X_("Session")){
1078 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1082 if ((prop = node.property ("name")) != 0) {
1083 _name = prop->value ();
1086 setup_raid_path(_path);
1088 if ((prop = node.property (X_("id-counter"))) != 0) {
1090 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1091 ID::init_counter (x);
1093 /* old sessions used a timebased counter, so fake
1094 the startup ID counter based on a standard
1099 ID::init_counter (now);
1103 IO::disable_ports ();
1104 IO::disable_connecting ();
1106 /* Object loading order:
1124 if (use_config_midi_ports ()) {
1127 if ((child = find_named_node (node, "extra")) != 0) {
1128 _extra_xml = new XMLNode (*child);
1131 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1132 load_options (*child);
1133 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1134 load_options (*child);
1136 error << _("Session: XML state has no options section") << endmsg;
1139 if ((child = find_named_node (node, "Locations")) == 0) {
1140 error << _("Session: XML state has no locations section") << endmsg;
1142 } else if (_locations.set_state (*child)) {
1148 if ((location = _locations.auto_loop_location()) != 0) {
1149 set_auto_loop_location (location);
1152 if ((location = _locations.auto_punch_location()) != 0) {
1153 set_auto_punch_location (location);
1156 if ((location = _locations.end_location()) == 0) {
1157 _locations.add (end_location);
1159 delete end_location;
1160 end_location = location;
1163 if ((location = _locations.start_location()) == 0) {
1164 _locations.add (start_location);
1166 delete start_location;
1167 start_location = location;
1170 AudioFileSource::set_header_position_offset (start_location->start());
1172 if ((child = find_named_node (node, "Sources")) == 0) {
1173 error << _("Session: XML state has no sources section") << endmsg;
1175 } else if (load_sources (*child)) {
1179 if ((child = find_named_node (node, "Regions")) == 0) {
1180 error << _("Session: XML state has no Regions section") << endmsg;
1182 } else if (load_regions (*child)) {
1186 if ((child = find_named_node (node, "Playlists")) == 0) {
1187 error << _("Session: XML state has no playlists section") << endmsg;
1189 } else if (load_playlists (*child)) {
1193 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1195 } else if (load_unused_playlists (*child)) {
1199 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1200 if (load_named_selections (*child)) {
1205 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1206 error << _("Session: XML state has no diskstreams section") << endmsg;
1208 } else if (load_diskstreams (*child)) {
1212 if ((child = find_named_node (node, "Connections")) == 0) {
1213 error << _("Session: XML state has no connections section") << endmsg;
1215 } else if (load_connections (*child)) {
1219 if ((child = find_named_node (node, "EditGroups")) == 0) {
1220 error << _("Session: XML state has no edit groups section") << endmsg;
1222 } else if (load_edit_groups (*child)) {
1226 if ((child = find_named_node (node, "MixGroups")) == 0) {
1227 error << _("Session: XML state has no mix groups section") << endmsg;
1229 } else if (load_mix_groups (*child)) {
1233 if ((child = find_named_node (node, "TempoMap")) == 0) {
1234 error << _("Session: XML state has no Tempo Map section") << endmsg;
1236 } else if (_tempo_map->set_state (*child)) {
1240 if ((child = find_named_node (node, "Routes")) == 0) {
1241 error << _("Session: XML state has no routes section") << endmsg;
1243 } else if (load_routes (*child)) {
1247 if ((child = find_named_node (node, "Click")) == 0) {
1248 warning << _("Session: XML state has no click section") << endmsg;
1249 } else if (_click_io) {
1250 _click_io->set_state (*child);
1253 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1254 ControlProtocolManager::instance().set_protocol_states (*child);
1257 /* here beginneth the second phase ... */
1259 StateReady (); /* EMIT SIGNAL */
1261 _state_of_the_state = Clean;
1263 if (state_was_pending) {
1264 save_state (_current_snapshot_name);
1265 remove_pending_capture_state ();
1266 state_was_pending = false;
1276 Session::load_routes (const XMLNode& node)
1279 XMLNodeConstIterator niter;
1280 RouteList new_routes;
1282 nlist = node.children();
1286 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1288 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1291 error << _("Session: cannot create Route from XML description.") << endmsg;
1295 new_routes.push_back (route);
1298 add_routes (new_routes);
1303 boost::shared_ptr<Route>
1304 Session::XMLRouteFactory (const XMLNode& node)
1306 if (node.name() != "Route") {
1307 return boost::shared_ptr<Route> ((Route*) 0);
1310 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1311 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1314 boost::shared_ptr<Route> x (new Route (*this, node));
1320 Session::load_regions (const XMLNode& node)
1323 XMLNodeConstIterator niter;
1324 boost::shared_ptr<AudioRegion> region;
1326 nlist = node.children();
1330 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1331 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1332 error << _("Session: cannot create Region from XML description.") << endmsg;
1339 boost::shared_ptr<AudioRegion>
1340 Session::XMLRegionFactory (const XMLNode& node, bool full)
1342 const XMLProperty* prop;
1343 boost::shared_ptr<Source> source;
1344 boost::shared_ptr<AudioSource> as;
1346 uint32_t nchans = 1;
1349 if (node.name() != X_("Region")) {
1350 return boost::shared_ptr<AudioRegion>();
1353 if ((prop = node.property (X_("channels"))) != 0) {
1354 nchans = atoi (prop->value().c_str());
1358 if ((prop = node.property ("name")) == 0) {
1359 cerr << "no name for this region\n";
1363 if ((prop = node.property (X_("source-0"))) == 0) {
1364 if ((prop = node.property ("source")) == 0) {
1365 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1366 return boost::shared_ptr<AudioRegion>();
1370 PBD::ID s_id (prop->value());
1372 if ((source = source_by_id (s_id)) == 0) {
1373 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1374 return boost::shared_ptr<AudioRegion>();
1377 as = boost::dynamic_pointer_cast<AudioSource>(source);
1379 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1380 return boost::shared_ptr<AudioRegion>();
1383 sources.push_back (as);
1385 /* pickup other channels */
1387 for (uint32_t n=1; n < nchans; ++n) {
1388 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1389 if ((prop = node.property (buf)) != 0) {
1391 PBD::ID id2 (prop->value());
1393 if ((source = source_by_id (id2)) == 0) {
1394 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1395 return boost::shared_ptr<AudioRegion>();
1398 as = boost::dynamic_pointer_cast<AudioSource>(source);
1400 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1401 return boost::shared_ptr<AudioRegion>();
1403 sources.push_back (as);
1408 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1410 /* a final detail: this is the one and only place that we know how long missing files are */
1412 if (region->whole_file()) {
1413 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1414 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1416 sfp->set_length (region->length());
1426 catch (failed_constructor& err) {
1427 return boost::shared_ptr<AudioRegion>();
1432 Session::get_sources_as_xml ()
1435 XMLNode* node = new XMLNode (X_("Sources"));
1436 Glib::Mutex::Lock lm (audio_source_lock);
1438 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1439 node->add_child_nocopy (i->second->get_state());
1442 /* XXX get MIDI and other sources here */
1448 Session::path_from_region_name (string name, string identifier)
1450 char buf[PATH_MAX+1];
1452 string dir = discover_best_sound_dir ();
1454 for (n = 0; n < 999999; ++n) {
1455 if (identifier.length()) {
1456 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1457 identifier.c_str(), n);
1459 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1462 if (!g_file_test (buf, G_FILE_TEST_EXISTS)) {
1467 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1476 Session::load_sources (const XMLNode& node)
1479 XMLNodeConstIterator niter;
1480 boost::shared_ptr<Source> source;
1482 nlist = node.children();
1486 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1489 if ((source = XMLSourceFactory (**niter)) == 0) {
1490 error << _("Session: cannot create Source from XML description.") << endmsg;
1494 catch (non_existent_source& err) {
1495 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1496 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1503 boost::shared_ptr<Source>
1504 Session::XMLSourceFactory (const XMLNode& node)
1506 if (node.name() != "Source") {
1507 return boost::shared_ptr<Source>();
1511 return SourceFactory::create (*this, node);
1514 catch (failed_constructor& err) {
1515 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1516 return boost::shared_ptr<Source>();
1521 Session::save_template (string template_name)
1524 string xml_path, bak_path, template_path;
1526 if (_state_of_the_state & CannotSave) {
1531 string dir = template_dir();
1533 if ((dp = opendir (dir.c_str()))) {
1536 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1537 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1542 tree.set_root (&get_template());
1545 xml_path += template_name;
1546 xml_path += _template_suffix;
1548 ifstream in(xml_path.c_str());
1551 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1557 if (!tree.write (xml_path)) {
1558 error << _("mix template not saved") << endmsg;
1566 Session::rename_template (string old_name, string new_name)
1568 string old_path = template_dir() + old_name + _template_suffix;
1569 string new_path = template_dir() + new_name + _template_suffix;
1571 return rename (old_path.c_str(), new_path.c_str());
1575 Session::delete_template (string name)
1577 string template_path = template_dir();
1578 template_path += name;
1579 template_path += _template_suffix;
1581 return remove (template_path.c_str());
1585 Session::refresh_disk_space ()
1588 struct statfs statfsbuf;
1589 vector<space_and_path>::iterator i;
1590 Glib::Mutex::Lock lm (space_lock);
1593 /* get freespace on every FS that is part of the session path */
1595 _total_free_4k_blocks = 0;
1597 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1598 statfs ((*i).path.c_str(), &statfsbuf);
1600 scale = statfsbuf.f_bsize/4096.0;
1602 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1603 _total_free_4k_blocks += (*i).blocks;
1609 Session::ensure_sound_dir (string path, string& result)
1614 /* Ensure that the parent directory exists */
1616 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1617 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1621 /* Ensure that the sounds directory exists */
1625 result += sound_dir_name;
1627 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1628 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1634 dead += dead_sound_dir_name;
1636 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1637 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1643 peak += peak_dir_name;
1645 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1646 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1650 /* callers expect this to be terminated ... */
1657 Session::discover_best_sound_dir (bool destructive)
1659 vector<space_and_path>::iterator i;
1662 /* handle common case without system calls */
1664 if (session_dirs.size() == 1) {
1668 /* OK, here's the algorithm we're following here:
1670 We want to select which directory to use for
1671 the next file source to be created. Ideally,
1672 we'd like to use a round-robin process so as to
1673 get maximum performance benefits from splitting
1674 the files across multiple disks.
1676 However, in situations without much diskspace, an
1677 RR approach may end up filling up a filesystem
1678 with new files while others still have space.
1679 Its therefore important to pay some attention to
1680 the freespace in the filesystem holding each
1681 directory as well. However, if we did that by
1682 itself, we'd keep creating new files in the file
1683 system with the most space until it was as full
1684 as all others, thus negating any performance
1685 benefits of this RAID-1 like approach.
1687 So, we use a user-configurable space threshold. If
1688 there are at least 2 filesystems with more than this
1689 much space available, we use RR selection between them.
1690 If not, then we pick the filesystem with the most space.
1692 This gets a good balance between the two
1696 refresh_disk_space ();
1698 int free_enough = 0;
1700 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1701 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1706 if (free_enough >= 2) {
1708 bool found_it = false;
1710 /* use RR selection process, ensuring that the one
1714 i = last_rr_session_dir;
1717 if (++i == session_dirs.end()) {
1718 i = session_dirs.begin();
1721 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1722 if (ensure_sound_dir ((*i).path, result) == 0) {
1723 last_rr_session_dir = i;
1729 } while (i != last_rr_session_dir);
1732 result = sound_dir();
1737 /* pick FS with the most freespace (and that
1738 seems to actually work ...)
1741 vector<space_and_path> sorted;
1742 space_and_path_ascending_cmp cmp;
1744 sorted = session_dirs;
1745 sort (sorted.begin(), sorted.end(), cmp);
1747 for (i = sorted.begin(); i != sorted.end(); ++i) {
1748 if (ensure_sound_dir ((*i).path, result) == 0) {
1749 last_rr_session_dir = i;
1754 /* if the above fails, fall back to the most simplistic solution */
1756 if (i == sorted.end()) {
1765 Session::load_playlists (const XMLNode& node)
1768 XMLNodeConstIterator niter;
1769 boost::shared_ptr<Playlist> playlist;
1771 nlist = node.children();
1775 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1777 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1778 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1786 Session::load_unused_playlists (const XMLNode& node)
1789 XMLNodeConstIterator niter;
1790 boost::shared_ptr<Playlist> playlist;
1792 nlist = node.children();
1796 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1798 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1799 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1803 // now manually untrack it
1805 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1812 boost::shared_ptr<Playlist>
1813 Session::XMLPlaylistFactory (const XMLNode& node)
1816 return PlaylistFactory::create (*this, node);
1819 catch (failed_constructor& err) {
1820 return boost::shared_ptr<Playlist>();
1825 Session::load_named_selections (const XMLNode& node)
1828 XMLNodeConstIterator niter;
1831 nlist = node.children();
1835 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1837 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1838 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1846 Session::XMLNamedSelectionFactory (const XMLNode& node)
1849 return new NamedSelection (*this, node);
1852 catch (failed_constructor& err) {
1858 Session::dead_sound_dir () const
1861 res += dead_sound_dir_name;
1867 Session::old_sound_dir (bool with_path) const
1875 res += old_sound_dir_name;
1881 Session::sound_dir (bool with_path) const
1892 res += interchange_dir_name;
1894 res += legalize_for_path (_name);
1896 res += sound_dir_name;
1904 /* if this already exists, don't check for the old session sound directory */
1906 if (Glib::file_test (full, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
1910 /* possibly support old session structure */
1913 string old_withpath;
1915 old_nopath += old_sound_dir_name;
1918 old_withpath = _path;
1919 old_withpath += old_sound_dir_name;
1921 if (Glib::file_test (old_withpath.c_str(), Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
1923 return old_withpath;
1928 /* ok, old "sounds" directory isn't there, return the new path */
1934 Session::peak_dir () const
1937 res += peak_dir_name;
1943 Session::automation_dir () const
1946 res += "automation/";
1951 Session::template_dir ()
1953 string path = get_user_ardour_path();
1954 path += "templates/";
1960 Session::export_dir () const
1963 res += export_dir_name;
1969 Session::suffixed_search_path (string suffix, bool data)
1973 path += get_user_ardour_path();
1974 if (path[path.length()-1] != ':') {
1979 path += get_system_data_path();
1981 path += get_system_module_path();
1984 vector<string> split_path;
1986 split (path, split_path, ':');
1989 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
1994 if (distance (i, split_path.end()) != 1) {
2003 Session::template_path ()
2005 return suffixed_search_path (X_("templates"), true);
2009 Session::control_protocol_path ()
2011 return suffixed_search_path (X_("surfaces"), false);
2015 Session::load_connections (const XMLNode& node)
2017 XMLNodeList nlist = node.children();
2018 XMLNodeConstIterator niter;
2022 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2023 if ((*niter)->name() == "InputConnection") {
2024 add_connection (new ARDOUR::InputConnection (**niter));
2025 } else if ((*niter)->name() == "OutputConnection") {
2026 add_connection (new ARDOUR::OutputConnection (**niter));
2028 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2037 Session::load_edit_groups (const XMLNode& node)
2039 return load_route_groups (node, true);
2043 Session::load_mix_groups (const XMLNode& node)
2045 return load_route_groups (node, false);
2049 Session::load_route_groups (const XMLNode& node, bool edit)
2051 XMLNodeList nlist = node.children();
2052 XMLNodeConstIterator niter;
2057 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2058 if ((*niter)->name() == "RouteGroup") {
2060 rg = add_edit_group ("");
2061 rg->set_state (**niter);
2063 rg = add_mix_group ("");
2064 rg->set_state (**niter);
2073 state_file_filter (const string &str, void *arg)
2075 return (str.length() > strlen(Session::statefile_suffix()) &&
2076 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2080 bool operator()(const string* a, const string* b) {
2086 remove_end(string* state)
2088 string statename(*state);
2090 string::size_type start,end;
2091 if ((start = statename.find_last_of ('/')) != string::npos) {
2092 statename = statename.substr (start+1);
2095 if ((end = statename.rfind(".ardour")) == string::npos) {
2096 end = statename.length();
2099 return new string(statename.substr (0, end));
2103 Session::possible_states (string path)
2105 PathScanner scanner;
2106 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2108 transform(states->begin(), states->end(), states->begin(), remove_end);
2111 sort (states->begin(), states->end(), cmp);
2117 Session::possible_states () const
2119 return possible_states(_path);
2123 Session::auto_save()
2125 save_state (_current_snapshot_name);
2129 Session::add_edit_group (string name)
2131 RouteGroup* rg = new RouteGroup (*this, name);
2132 edit_groups.push_back (rg);
2133 edit_group_added (rg); /* EMIT SIGNAL */
2139 Session::add_mix_group (string name)
2141 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2142 mix_groups.push_back (rg);
2143 mix_group_added (rg); /* EMIT SIGNAL */
2149 Session::remove_edit_group (RouteGroup& rg)
2151 list<RouteGroup*>::iterator i;
2153 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2154 (*i)->apply (&Route::drop_edit_group, this);
2155 edit_groups.erase (i);
2156 edit_group_removed (); /* EMIT SIGNAL */
2163 Session::remove_mix_group (RouteGroup& rg)
2165 list<RouteGroup*>::iterator i;
2167 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2168 (*i)->apply (&Route::drop_mix_group, this);
2169 mix_groups.erase (i);
2170 mix_group_removed (); /* EMIT SIGNAL */
2177 Session::mix_group_by_name (string name)
2179 list<RouteGroup *>::iterator i;
2181 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2182 if ((*i)->name() == name) {
2190 Session::edit_group_by_name (string name)
2192 list<RouteGroup *>::iterator i;
2194 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2195 if ((*i)->name() == name) {
2203 Session::begin_reversible_command (string name)
2205 current_trans = new UndoTransaction;
2206 current_trans->set_name (name);
2210 Session::commit_reversible_command (Command *cmd)
2215 current_trans->add_command (cmd);
2218 gettimeofday (&now, 0);
2219 current_trans->set_timestamp (now);
2221 _history.add (current_trans);
2224 Session::GlobalRouteBooleanState
2225 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2227 GlobalRouteBooleanState s;
2228 boost::shared_ptr<RouteList> r = routes.reader ();
2230 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2231 if (!(*i)->hidden()) {
2232 RouteBooleanState v;
2235 Route* r = (*i).get();
2236 v.second = (r->*method)();
2245 Session::GlobalRouteMeterState
2246 Session::get_global_route_metering ()
2248 GlobalRouteMeterState s;
2249 boost::shared_ptr<RouteList> r = routes.reader ();
2251 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2252 if (!(*i)->hidden()) {
2256 v.second = (*i)->meter_point();
2266 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2268 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2270 boost::shared_ptr<Route> r = (i->first.lock());
2273 r->set_meter_point (i->second, arg);
2279 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2281 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2283 boost::shared_ptr<Route> r = (i->first.lock());
2286 Route* rp = r.get();
2287 (rp->*method) (i->second, arg);
2293 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2295 set_global_route_boolean (s, &Route::set_mute, src);
2299 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2301 set_global_route_boolean (s, &Route::set_solo, src);
2305 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2307 set_global_route_boolean (s, &Route::set_record_enable, src);
2312 Session::global_mute_memento (void* src)
2314 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2318 Session::global_metering_memento (void* src)
2320 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2324 Session::global_solo_memento (void* src)
2326 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2330 Session::global_record_enable_memento (void* src)
2332 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2337 template_filter (const string &str, void *arg)
2339 return (str.length() > strlen(Session::template_suffix()) &&
2340 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2344 Session::get_template_list (list<string> &template_names)
2346 vector<string *> *templates;
2347 PathScanner scanner;
2350 path = template_path ();
2352 templates = scanner (path, template_filter, 0, false, true);
2354 vector<string*>::iterator i;
2355 for (i = templates->begin(); i != templates->end(); ++i) {
2356 string fullpath = *(*i);
2359 start = fullpath.find_last_of ('/') + 1;
2360 if ((end = fullpath.find_last_of ('.')) <0) {
2361 end = fullpath.length();
2364 template_names.push_back(fullpath.substr(start, (end-start)));
2369 Session::read_favorite_dirs (FavoriteDirs & favs)
2371 string path = get_user_ardour_path();
2372 path += "/favorite_dirs";
2374 ifstream fav (path.c_str());
2379 if (errno != ENOENT) {
2380 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2391 getline(fav, newfav);
2397 favs.push_back (newfav);
2404 Session::write_favorite_dirs (FavoriteDirs & favs)
2406 string path = get_user_ardour_path();
2407 path += "/favorite_dirs";
2409 ofstream fav (path.c_str());
2415 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2416 fav << (*i) << endl;
2423 accept_all_non_peak_files (const string& path, void *arg)
2425 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2429 accept_all_state_files (const string& path, void *arg)
2431 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2435 Session::find_all_sources (string path, set<string>& result)
2440 if (!tree.read (path)) {
2444 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2449 XMLNodeConstIterator niter;
2451 nlist = node->children();
2455 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2459 if ((prop = (*niter)->property (X_("name"))) == 0) {
2463 if (prop->value()[0] == '/') {
2464 /* external file, ignore */
2468 string path = _path; /* /-terminated */
2469 path += sound_dir_name;
2471 path += prop->value();
2473 result.insert (path);
2480 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2482 PathScanner scanner;
2483 vector<string*>* state_files;
2485 string this_snapshot_path;
2491 if (ripped[ripped.length()-1] == '/') {
2492 ripped = ripped.substr (0, ripped.length() - 1);
2495 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2497 if (state_files == 0) {
2502 this_snapshot_path = _path;
2503 this_snapshot_path += _current_snapshot_name;
2504 this_snapshot_path += _statefile_suffix;
2506 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2508 if (exclude_this_snapshot && **i == this_snapshot_path) {
2512 if (find_all_sources (**i, result) < 0) {
2520 struct RegionCounter {
2521 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2522 AudioSourceList::iterator iter;
2523 boost::shared_ptr<Region> region;
2526 RegionCounter() : count (0) {}
2530 Session::cleanup_sources (Session::cleanup_report& rep)
2532 vector<boost::shared_ptr<Source> > dead_sources;
2533 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2534 PathScanner scanner;
2536 vector<space_and_path>::iterator i;
2537 vector<space_and_path>::iterator nexti;
2538 vector<string*>* soundfiles;
2539 vector<string> unused;
2540 set<string> all_sources;
2545 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2547 /* step 1: consider deleting all unused playlists */
2549 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2552 status = AskAboutPlaylistDeletion (*x);
2561 playlists_tbd.push_back (*x);
2565 /* leave it alone */
2570 /* now delete any that were marked for deletion */
2572 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2573 (*x)->drop_references ();
2576 playlists_tbd.clear ();
2578 /* step 2: find all un-used sources */
2583 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2585 AudioSourceList::iterator tmp;
2590 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2594 if (!i->second->used() && i->second->length() > 0) {
2595 dead_sources.push_back (i->second);
2596 i->second->GoingAway();
2602 /* build a list of all the possible sound directories for the session */
2604 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2609 sound_path += (*i).path;
2610 sound_path += sound_dir (false);
2612 if (nexti != session_dirs.end()) {
2619 /* now do the same thing for the files that ended up in the sounds dir(s)
2620 but are not referenced as sources in any snapshot.
2623 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2625 if (soundfiles == 0) {
2629 /* find all sources, but don't use this snapshot because the
2630 state file on disk still references sources we may have already
2634 find_all_sources_across_snapshots (all_sources, true);
2636 /* add our current source list
2639 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2640 boost::shared_ptr<AudioFileSource> fs;
2642 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2643 all_sources.insert (fs->path());
2647 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2652 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2661 unused.push_back (spath);
2665 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2667 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2668 struct stat statbuf;
2670 rep.paths.push_back (*x);
2671 if (stat ((*x).c_str(), &statbuf) == 0) {
2672 rep.space += statbuf.st_size;
2677 /* don't move the file across filesystems, just
2678 stick it in the `dead_sound_dir_name' directory
2679 on whichever filesystem it was already on.
2682 if ((*x).find ("/sounds/") != string::npos) {
2684 /* old school, go up 1 level */
2686 newpath = Glib::path_get_dirname (*x); // "sounds"
2687 newpath = Glib::path_get_dirname (newpath); // "session-name"
2691 /* new school, go up 4 levels */
2693 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2694 newpath = Glib::path_get_dirname (newpath); // "session-name"
2695 newpath = Glib::path_get_dirname (newpath); // "interchange"
2696 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2700 newpath += dead_sound_dir_name;
2702 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2703 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2708 newpath += Glib::path_get_basename ((*x));
2710 if (access (newpath.c_str(), F_OK) == 0) {
2712 /* the new path already exists, try versioning */
2714 char buf[PATH_MAX+1];
2718 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2721 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2722 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2726 if (version == 999) {
2727 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2731 newpath = newpath_v;
2736 /* it doesn't exist, or we can't read it or something */
2740 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2741 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2742 (*x), newpath, strerror (errno))
2747 /* see if there an easy to find peakfile for this file, and remove it.
2750 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2751 peakpath += ".peak";
2753 if (access (peakpath.c_str(), W_OK) == 0) {
2754 if (::unlink (peakpath.c_str()) != 0) {
2755 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2756 peakpath, _path, strerror (errno))
2758 /* try to back out */
2759 rename (newpath.c_str(), _path.c_str());
2767 /* dump the history list */
2771 /* save state so we don't end up a session file
2772 referring to non-existent sources.
2778 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2783 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2785 vector<space_and_path>::iterator i;
2786 string dead_sound_dir;
2787 struct dirent* dentry;
2788 struct stat statbuf;
2794 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2796 dead_sound_dir = (*i).path;
2797 dead_sound_dir += dead_sound_dir_name;
2799 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2803 while ((dentry = readdir (dead)) != 0) {
2805 /* avoid '.' and '..' */
2807 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2808 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2814 fullpath = dead_sound_dir;
2816 fullpath += dentry->d_name;
2818 if (stat (fullpath.c_str(), &statbuf)) {
2822 if (!S_ISREG (statbuf.st_mode)) {
2826 if (unlink (fullpath.c_str())) {
2827 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2828 fullpath, strerror (errno))
2832 rep.paths.push_back (dentry->d_name);
2833 rep.space += statbuf.st_size;
2844 Session::set_dirty ()
2846 bool was_dirty = dirty();
2848 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2851 DirtyChanged(); /* EMIT SIGNAL */
2857 Session::set_clean ()
2859 bool was_dirty = dirty();
2861 _state_of_the_state = Clean;
2864 DirtyChanged(); /* EMIT SIGNAL */
2869 Session::set_deletion_in_progress ()
2871 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2875 Session::add_controllable (Controllable* c)
2877 /* this adds a controllable to the list managed by the Session.
2878 this is a subset of those managed by the Controllable class
2879 itself, and represents the only ones whose state will be saved
2880 as part of the session.
2883 Glib::Mutex::Lock lm (controllables_lock);
2884 controllables.insert (c);
2888 Session::remove_controllable (Controllable* c)
2890 if (_state_of_the_state | Deletion) {
2894 Glib::Mutex::Lock lm (controllables_lock);
2896 Controllables::iterator x = controllables.find (c);
2898 if (x != controllables.end()) {
2899 controllables.erase (x);
2904 Session::controllable_by_id (const PBD::ID& id)
2906 Glib::Mutex::Lock lm (controllables_lock);
2908 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2909 if ((*i)->id() == id) {
2918 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2920 Stateful::add_instant_xml (node, dir);
2921 Config->add_instant_xml (node, get_user_ardour_path());
2926 Session::save_history (string snapshot_name)
2932 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2934 if (snapshot_name.empty()) {
2935 snapshot_name = _current_snapshot_name;
2938 xml_path = _path + snapshot_name + ".history";
2940 bak_path = xml_path + ".bak";
2942 if ((access (xml_path.c_str(), F_OK) == 0) &&
2943 (rename (xml_path.c_str(), bak_path.c_str())))
2945 error << _("could not backup old history file, current history not saved.") << endmsg;
2949 if (!tree.write (xml_path))
2951 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2953 /* don't leave a corrupt file lying around if it is
2957 if (unlink (xml_path.c_str())) {
2958 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2960 if (rename (bak_path.c_str(), xml_path.c_str()))
2962 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2973 Session::restore_history (string snapshot_name)
2978 if (snapshot_name.empty()) {
2979 snapshot_name = _current_snapshot_name;
2983 xmlpath = _path + snapshot_name + ".history";
2984 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2986 if (access (xmlpath.c_str(), F_OK)) {
2987 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2991 if (!tree.read (xmlpath)) {
2992 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2996 /* replace history */
2999 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3002 UndoTransaction* ut = new UndoTransaction ();
3005 ut->set_name(t->property("name")->value());
3006 stringstream ss(t->property("tv_sec")->value());
3008 ss.str(t->property("tv_usec")->value());
3010 ut->set_timestamp(tv);
3012 for (XMLNodeConstIterator child_it = t->children().begin();
3013 child_it != t->children().end();
3016 XMLNode *n = *child_it;
3019 if (n->name() == "MementoCommand" ||
3020 n->name() == "MementoUndoCommand" ||
3021 n->name() == "MementoRedoCommand") {
3023 if ((c = memento_command_factory(n))) {
3027 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3029 if ((c = global_state_command_factory (*n))) {
3030 ut->add_command (c);
3035 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3046 Session::config_changed (const char* parameter_name)
3048 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3050 if (PARAM_IS ("seamless-loop")) {
3052 } else if (PARAM_IS ("rf-speed")) {
3054 } else if (PARAM_IS ("auto-loop")) {
3056 } else if (PARAM_IS ("auto-input")) {
3058 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3059 /* auto-input only makes a difference if we're rolling */
3061 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3063 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3064 if ((*i)->record_enabled ()) {
3065 (*i)->monitor_input (!Config->get_auto_input());
3070 } else if (PARAM_IS ("punch-in")) {
3074 if ((location = _locations.auto_punch_location()) != 0) {
3076 if (Config->get_punch_in ()) {
3077 replace_event (Event::PunchIn, location->start());
3079 remove_event (location->start(), Event::PunchIn);
3083 } else if (PARAM_IS ("punch-out")) {
3087 if ((location = _locations.auto_punch_location()) != 0) {
3089 if (Config->get_punch_out()) {
3090 replace_event (Event::PunchOut, location->end());
3092 clear_events (Event::PunchOut);
3096 } else if (PARAM_IS ("edit-mode")) {
3098 Glib::Mutex::Lock lm (playlist_lock);
3100 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3101 (*i)->set_edit_mode (Config->get_edit_mode ());
3104 } else if (PARAM_IS ("use-video-sync")) {
3106 if (transport_stopped()) {
3107 if (Config->get_use_video_sync()) {
3108 waiting_for_sync_offset = true;
3112 } else if (PARAM_IS ("mmc-control")) {
3114 poke_midi_thread ();
3116 } else if (PARAM_IS ("mmc-device-id")) {
3119 mmc->set_device_id (Config->get_mmc_device_id());
3122 } else if (PARAM_IS ("midi-control")) {
3124 poke_midi_thread ();
3126 } else if (PARAM_IS ("raid-path")) {
3128 setup_raid_path (Config->get_raid_path());
3130 } else if (PARAM_IS ("smpte-format")) {
3134 } else if (PARAM_IS ("video-pullup")) {
3138 } else if (PARAM_IS ("seamless-loop")) {
3140 if (play_loop && transport_rolling()) {
3141 // to reset diskstreams etc
3142 request_play_loop (true);
3145 } else if (PARAM_IS ("rf-speed")) {
3147 cumulative_rf_motion = 0;
3150 } else if (PARAM_IS ("click-sound")) {
3152 setup_click_sounds (1);
3154 } else if (PARAM_IS ("click-emphasis-sound")) {
3156 setup_click_sounds (-1);
3158 } else if (PARAM_IS ("clicking")) {
3160 if (Config->get_clicking()) {
3161 if (_click_io && click_data) { // don't require emphasis data
3168 } else if (PARAM_IS ("send-mtc")) {
3170 /* only set the internal flag if we have
3174 if (_mtc_port != 0) {
3175 session_send_mtc = Config->get_send_mtc();
3176 if (session_send_mtc) {
3177 /* mark us ready to send */
3178 next_quarter_frame_to_send = 0;
3182 } else if (PARAM_IS ("send-mmc")) {
3184 /* only set the internal flag if we have
3188 if (_mmc_port != 0) {
3189 session_send_mmc = Config->get_send_mmc();
3192 } else if (PARAM_IS ("midi-feedback")) {
3194 /* only set the internal flag if we have
3198 if (_mtc_port != 0) {
3199 session_midi_feedback = Config->get_midi_feedback();
3202 } else if (PARAM_IS ("jack-time-master")) {
3204 engine().reset_timebase ();
3206 } else if (PARAM_IS ("native-file-header-format")) {
3208 if (!first_file_header_format_reset) {
3209 reset_native_file_format ();
3212 first_file_header_format_reset = false;
3214 } else if (PARAM_IS ("native-file-data-format")) {
3216 if (!first_file_data_format_reset) {
3217 reset_native_file_format ();
3220 first_file_data_format_reset = false;
3222 } else if (PARAM_IS ("slave-source")) {
3223 set_slave_source (Config->get_slave_source());
3224 } else if (PARAM_IS ("remote-model")) {
3225 set_remote_control_ids ();