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/strsplit.h>
59 #include <pbd/stacktrace.h>
60 #include <pbd/copyfile.h>
62 #include <ardour/audioengine.h>
63 #include <ardour/configuration.h>
64 #include <ardour/session.h>
65 #include <ardour/buffer.h>
66 #include <ardour/audio_diskstream.h>
67 #include <ardour/midi_diskstream.h>
68 #include <ardour/utils.h>
69 #include <ardour/audioplaylist.h>
70 #include <ardour/midi_playlist.h>
71 #include <ardour/smf_source.h>
72 #include <ardour/audiofilesource.h>
73 #include <ardour/silentfilesource.h>
74 #include <ardour/sndfilesource.h>
75 #include <ardour/midi_source.h>
76 #include <ardour/sndfile_helpers.h>
77 #include <ardour/auditioner.h>
78 #include <ardour/export.h>
79 #include <ardour/redirect.h>
80 #include <ardour/send.h>
81 #include <ardour/insert.h>
82 #include <ardour/bundle.h>
83 #include <ardour/slave.h>
84 #include <ardour/tempo.h>
85 #include <ardour/audio_track.h>
86 #include <ardour/midi_track.h>
87 #include <ardour/cycle_timer.h>
88 #include <ardour/utils.h>
89 #include <ardour/named_selection.h>
90 #include <ardour/version.h>
91 #include <ardour/location.h>
92 #include <ardour/audioregion.h>
93 #include <ardour/midi_region.h>
94 #include <ardour/crossfade.h>
95 #include <ardour/control_protocol_manager.h>
96 #include <ardour/region_factory.h>
97 #include <ardour/source_factory.h>
98 #include <ardour/playlist_factory.h>
99 #include <ardour/filename_extensions.h>
100 #include <ardour/directory_names.h>
101 #include <control_protocol/control_protocol.h>
107 using namespace ARDOUR;
111 Session::first_stage_init (string fullpath, string snapshot_name)
113 if (fullpath.length() == 0) {
115 throw failed_constructor();
118 char buf[PATH_MAX+1];
119 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
120 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
122 throw failed_constructor();
127 if (_path[_path.length()-1] != '/') {
131 /* these two are just provisional settings. set_state()
132 will likely override them.
135 _name = _current_snapshot_name = snapshot_name;
137 _current_frame_rate = _engine.frame_rate ();
138 _tempo_map = new TempoMap (_current_frame_rate);
139 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
141 g_atomic_int_set (&processing_prohibited, 0);
143 _transport_speed = 0;
144 _last_transport_speed = 0;
145 auto_play_legal = false;
146 transport_sub_state = 0;
147 _transport_frame = 0;
149 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
150 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
151 _end_location_is_free = true;
152 g_atomic_int_set (&_record_status, Disabled);
153 loop_changing = false;
155 _last_roll_location = 0;
156 _last_record_location = 0;
157 pending_locate_frame = 0;
158 pending_locate_roll = false;
159 pending_locate_flush = false;
160 dstream_buffer_size = 0;
162 state_was_pending = false;
164 outbound_mtc_smpte_frame = 0;
165 next_quarter_frame_to_send = -1;
166 current_block_size = 0;
167 solo_update_disabled = false;
168 currently_soloing = false;
169 _have_captured = false;
170 _worst_output_latency = 0;
171 _worst_input_latency = 0;
172 _worst_track_latency = 0;
173 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
175 butler_mixdown_buffer = 0;
176 butler_gain_buffer = 0;
178 session_send_mmc = false;
179 session_send_mtc = false;
180 post_transport_work = PostTransportWork (0);
181 g_atomic_int_set (&butler_should_do_transport_work, 0);
182 g_atomic_int_set (&butler_active, 0);
183 g_atomic_int_set (&_playback_load, 100);
184 g_atomic_int_set (&_capture_load, 100);
185 g_atomic_int_set (&_playback_load_min, 100);
186 g_atomic_int_set (&_capture_load_min, 100);
188 waiting_to_start = false;
190 _gain_automation_buffer = 0;
191 _pan_automation_buffer = 0;
193 pending_abort = false;
194 destructive_index = 0;
196 first_file_data_format_reset = true;
197 first_file_header_format_reset = true;
198 butler_thread = (pthread_t) 0;
199 //midi_thread = (pthread_t) 0;
201 AudioDiskstream::allocate_working_buffers();
203 /* default short fade = 15ms */
205 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
206 SndFileSource::setup_standard_crossfades (frame_rate());
208 last_mmc_step.tv_sec = 0;
209 last_mmc_step.tv_usec = 0;
212 /* click sounds are unset by default, which causes us to internal
213 waveforms for clicks.
217 click_emphasis_data = 0;
219 click_emphasis_length = 0;
222 process_function = &Session::process_with_events;
224 if (Config->get_use_video_sync()) {
225 waiting_for_sync_offset = true;
227 waiting_for_sync_offset = false;
230 _current_frame_rate = 48000;
231 _base_frame_rate = 48000;
235 _smpte_offset_negative = true;
236 last_smpte_valid = false;
240 last_rr_session_dir = session_dirs.begin();
241 refresh_disk_space ();
243 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
247 average_slave_delta = 1800;
248 have_first_delta_accumulator = false;
249 delta_accumulator_cnt = 0;
250 slave_state = Stopped;
252 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
254 /* These are all static "per-class" signals */
256 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
257 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
258 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
259 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
260 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
261 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
263 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
265 IO::MoreChannels.connect (mem_fun (*this, &Session::ensure_buffers));
267 /* stop IO objects from doing stuff until we're ready for them */
269 IO::disable_panners ();
270 IO::disable_ports ();
271 IO::disable_connecting ();
275 Session::second_stage_init (bool new_session)
277 AudioFileSource::set_peak_dir (peak_dir());
280 if (load_state (_current_snapshot_name)) {
283 remove_empty_sounds ();
286 if (start_butler_thread()) {
290 /*if (start_midi_thread ()) {
294 // set_state() will call setup_raid_path(), but if it's a new session we need
295 // to call setup_raid_path() here.
297 if (set_state (*state_tree->root())) {
301 setup_raid_path(_path);
304 /* we can't save till after ::when_engine_running() is called,
305 because otherwise we save state with no connections made.
306 therefore, we reset _state_of_the_state because ::set_state()
307 will have cleared it.
309 we also have to include Loading so that any events that get
310 generated between here and the end of ::when_engine_running()
311 will be processed directly rather than queued.
314 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
316 // set_auto_input (true);
317 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
318 _locations.added.connect (mem_fun (this, &Session::locations_added));
319 setup_click_sounds (0);
320 setup_midi_control ();
322 /* Pay attention ... */
324 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
325 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
328 when_engine_running();
331 /* handle this one in a different way than all others, so that its clear what happened */
333 catch (AudioEngine::PortRegistrationFailure& err) {
334 error << _("Unable to create all required ports")
343 //send_full_time_code ();
344 _engine.transport_locate (0);
345 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
346 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
348 ControlProtocolManager::instance().set_session (*this);
351 _end_location_is_free = true;
353 _end_location_is_free = false;
360 Session::raid_path () const
364 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
369 return path.substr (0, path.length() - 1); // drop final colon
373 Session::setup_raid_path (string path)
375 string::size_type colon;
379 string::size_type len = path.length();
384 if (path.length() == 0) {
388 session_dirs.clear ();
390 for (string::size_type n = 0; n < len; ++n) {
391 if (path[n] == ':') {
398 /* no multiple search path, just one location (common case) */
402 session_dirs.push_back (sp);
409 if (fspath[fspath.length()-1] != '/') {
413 fspath += sound_dir (false);
415 AudioFileSource::set_search_path (fspath);
416 SMFSource::set_search_path (fspath); // FIXME: should be different
423 while ((colon = remaining.find_first_of (':')) != string::npos) {
426 sp.path = remaining.substr (0, colon);
427 session_dirs.push_back (sp);
429 /* add sounds to file search path */
432 if (fspath[fspath.length()-1] != '/') {
435 fspath += sound_dir (false);
438 remaining = remaining.substr (colon+1);
441 if (remaining.length()) {
448 if (fspath[fspath.length()-1] != '/') {
451 fspath += sound_dir (false);
454 session_dirs.push_back (sp);
457 /* set the AudioFileSource search path */
459 AudioFileSource::set_search_path (fspath);
460 SMFSource::set_search_path (fspath); // FIXME: should be different
462 /* reset the round-robin soundfile path thingie */
464 last_rr_session_dir = session_dirs.begin();
468 Session::initialize_start_and_end_locations (nframes_t start, nframes_t end)
470 start_location->set_end (start);
471 _locations.add (start_location);
473 end_location->set_end (end);
474 _locations.add (end_location);
478 Session::create_session_file ()
480 _state_of_the_state = Clean;
482 if (save_state (_current_snapshot_name)) {
483 error << "Could not create new session file" << endmsg;
490 Session::create_session_file_from_template (const string& template_path)
492 string out_path = _path + _name + statefile_suffix;
494 if(!copy_file (template_path, out_path)) {
495 error << string_compose (_("Could not use session template %1 to create new session."), template_path)
503 Session::load_diskstreams (const XMLNode& node)
506 XMLNodeConstIterator citer;
508 clist = node.children();
510 for (citer = clist.begin(); citer != clist.end(); ++citer) {
513 /* diskstreams added automatically by DiskstreamCreated handler */
514 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
515 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
516 add_diskstream (dstream);
517 } else if ((*citer)->name() == "MidiDiskstream") {
518 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
519 add_diskstream (dstream);
521 error << _("Session: unknown diskstream type in XML") << endmsg;
525 catch (failed_constructor& err) {
526 error << _("Session: could not load diskstream via XML state") << endmsg;
535 Session::maybe_write_autosave()
537 if (dirty() && record_status() != Recording) {
538 save_state("", true);
543 Session::remove_pending_capture_state ()
548 xml_path += _current_snapshot_name;
549 xml_path += pending_suffix;
551 unlink (xml_path.c_str());
554 /** Rename a state file.
555 * @param snapshot_name Snapshot name.
558 Session::rename_state (string old_name, string new_name)
560 if (old_name == _current_snapshot_name || old_name == _name) {
561 /* refuse to rename the current snapshot or the "main" one */
565 const string old_xml_path = _path + old_name + statefile_suffix;
566 const string new_xml_path = _path + new_name + statefile_suffix;
568 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
569 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
573 /** Remove a state file.
574 * @param snapshot_name Snapshot name.
577 Session::remove_state (string snapshot_name)
579 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
580 /* refuse to remove the current snapshot or the "main" one */
584 const string xml_path = _path + snapshot_name + statefile_suffix;
586 /* make a backup copy of the state file */
587 const string bak_path = xml_path + ".bak";
588 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
589 copy_file (xml_path, bak_path);
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;
621 /* proper save: use statefile_suffix (.ardour in English) */
623 xml_path += snapshot_name;
624 xml_path += statefile_suffix;
626 /* make a backup copy of the old file */
630 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
631 copy_file (xml_path, bak_path);
636 /* pending save: use pending_suffix (.pending in English) */
638 xml_path += snapshot_name;
639 xml_path += pending_suffix;
646 tmp_path += snapshot_name;
649 // cerr << "actually writing state to " << xml_path << endl;
651 if (!tree.write (tmp_path)) {
652 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
653 unlink (tmp_path.c_str());
658 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
659 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
660 unlink (tmp_path.c_str());
667 save_history (snapshot_name);
669 bool was_dirty = dirty();
671 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
674 DirtyChanged (); /* EMIT SIGNAL */
677 StateSaved (snapshot_name); /* EMIT SIGNAL */
684 Session::restore_state (string snapshot_name)
686 if (load_state (snapshot_name) == 0) {
687 set_state (*state_tree->root());
694 Session::load_state (string snapshot_name)
703 state_was_pending = false;
705 /* check for leftover pending state from a crashed capture attempt */
708 xmlpath += snapshot_name;
709 xmlpath += pending_suffix;
711 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
713 /* there is pending state from a crashed capture attempt */
715 if (AskAboutPendingState()) {
716 state_was_pending = true;
720 if (!state_was_pending) {
723 xmlpath += snapshot_name;
724 xmlpath += statefile_suffix;
727 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
728 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
732 state_tree = new XMLTree;
736 if (!state_tree->read (xmlpath)) {
737 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
743 XMLNode& root (*state_tree->root());
745 if (root.name() != X_("Session")) {
746 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
752 const XMLProperty* prop;
755 if ((prop = root.property ("version")) == 0) {
756 /* no version implies very old version of Ardour */
760 major_version = atoi (prop->value()); // grab just the first number before the period
761 if (major_version < 2) {
770 backup_path += snapshot_name;
772 backup_path += statefile_suffix;
774 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
775 xmlpath, backup_path)
778 copy_file (xmlpath, backup_path);
780 /* if it fails, don't worry. right? */
787 Session::load_options (const XMLNode& node)
791 LocaleGuard lg (X_("POSIX"));
793 Config->set_variables (node, ConfigVariableBase::Session);
795 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
796 if ((prop = child->property ("val")) != 0) {
797 _end_location_is_free = (prop->value() == "yes");
805 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
807 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
808 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
810 return owner & modified_by_session_or_user;
814 Session::get_options () const
817 LocaleGuard lg (X_("POSIX"));
819 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
821 child = option_root.add_child ("end-marker-is-free");
822 child->add_property ("val", _end_location_is_free ? "yes" : "no");
834 Session::get_template()
836 /* if we don't disable rec-enable, diskstreams
837 will believe they need to store their capture
838 sources in their state node.
841 disable_record (false);
847 Session::state(bool full_state)
849 XMLNode* node = new XMLNode("Session");
852 // store libardour version, just in case
854 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
855 libardour_major_version, libardour_minor_version, libardour_micro_version);
856 node->add_property("version", string(buf));
858 /* store configuration settings */
863 node->add_property ("name", _name);
865 if (session_dirs.size() > 1) {
869 vector<space_and_path>::iterator i = session_dirs.begin();
870 vector<space_and_path>::iterator next;
872 ++i; /* skip the first one */
876 while (i != session_dirs.end()) {
880 if (next != session_dirs.end()) {
890 child = node->add_child ("Path");
891 child->add_content (p);
895 /* save the ID counter */
897 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
898 node->add_property ("id-counter", buf);
900 /* various options */
902 node->add_child_nocopy (get_options());
904 child = node->add_child ("Sources");
907 Glib::Mutex::Lock sl (source_lock);
909 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
911 /* Don't save information about AudioFileSources that are empty */
913 boost::shared_ptr<AudioFileSource> fs;
915 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
917 /* Don't save sources that are empty, unless they're destructive (which are OK
918 if they are empty, because we will re-use them every time.)
921 if (!fs->destructive()) {
922 if (fs->length() == 0) {
928 child->add_child_nocopy (siter->second->get_state());
932 child = node->add_child ("Regions");
935 Glib::Mutex::Lock rl (region_lock);
937 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
939 /* only store regions not attached to playlists */
941 if (i->second->playlist() == 0) {
942 child->add_child_nocopy (i->second->state (true));
947 child = node->add_child ("DiskStreams");
950 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
951 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
952 if (!(*i)->hidden()) {
953 child->add_child_nocopy ((*i)->get_state());
959 node->add_child_nocopy (_locations.get_state());
961 // for a template, just create a new Locations, populate it
962 // with the default start and end, and get the state for that.
964 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
965 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
968 end->set_end(compute_initial_length());
970 node->add_child_nocopy (loc.get_state());
973 child = node->add_child ("Connections");
975 Glib::Mutex::Lock lm (bundle_lock);
976 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
977 if (!(*i)->dynamic()) {
978 child->add_child_nocopy ((*i)->get_state());
983 child = node->add_child ("Routes");
985 boost::shared_ptr<RouteList> r = routes.reader ();
987 RoutePublicOrderSorter cmp;
988 RouteList public_order (*r);
989 public_order.sort (cmp);
991 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
992 if (!(*i)->hidden()) {
994 child->add_child_nocopy ((*i)->get_state());
996 child->add_child_nocopy ((*i)->get_template());
1003 child = node->add_child ("EditGroups");
1004 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1005 child->add_child_nocopy ((*i)->get_state());
1008 child = node->add_child ("MixGroups");
1009 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1010 child->add_child_nocopy ((*i)->get_state());
1013 child = node->add_child ("Playlists");
1014 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1015 if (!(*i)->hidden()) {
1016 if (!(*i)->empty()) {
1018 child->add_child_nocopy ((*i)->get_state());
1020 child->add_child_nocopy ((*i)->get_template());
1026 child = node->add_child ("UnusedPlaylists");
1027 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1028 if (!(*i)->hidden()) {
1029 if (!(*i)->empty()) {
1031 child->add_child_nocopy ((*i)->get_state());
1033 child->add_child_nocopy ((*i)->get_template());
1041 child = node->add_child ("Click");
1042 child->add_child_nocopy (_click_io->state (full_state));
1046 child = node->add_child ("NamedSelections");
1047 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1049 child->add_child_nocopy ((*i)->get_state());
1054 node->add_child_nocopy (_tempo_map->get_state());
1056 node->add_child_nocopy (get_control_protocol_state());
1059 node->add_child_copy (*_extra_xml);
1066 Session::get_control_protocol_state ()
1068 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1069 return cpm.get_state();
1073 Session::set_state (const XMLNode& node)
1077 const XMLProperty* prop;
1080 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1082 if (node.name() != X_("Session")){
1083 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1087 if ((prop = node.property ("name")) != 0) {
1088 _name = prop->value ();
1091 setup_raid_path(_path);
1093 if ((prop = node.property (X_("id-counter"))) != 0) {
1095 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1096 ID::init_counter (x);
1098 /* old sessions used a timebased counter, so fake
1099 the startup ID counter based on a standard
1104 ID::init_counter (now);
1108 IO::disable_ports ();
1109 IO::disable_connecting ();
1111 /* Object loading order:
1129 if (use_config_midi_ports ()) {
1132 if ((child = find_named_node (node, "extra")) != 0) {
1133 _extra_xml = new XMLNode (*child);
1136 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1137 load_options (*child);
1138 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1139 load_options (*child);
1141 error << _("Session: XML state has no options section") << endmsg;
1144 if ((child = find_named_node (node, "Locations")) == 0) {
1145 error << _("Session: XML state has no locations section") << endmsg;
1147 } else if (_locations.set_state (*child)) {
1153 if ((location = _locations.auto_loop_location()) != 0) {
1154 set_auto_loop_location (location);
1157 if ((location = _locations.auto_punch_location()) != 0) {
1158 set_auto_punch_location (location);
1161 if ((location = _locations.end_location()) == 0) {
1162 _locations.add (end_location);
1164 delete end_location;
1165 end_location = location;
1168 if ((location = _locations.start_location()) == 0) {
1169 _locations.add (start_location);
1171 delete start_location;
1172 start_location = location;
1175 AudioFileSource::set_header_position_offset (start_location->start());
1177 if ((child = find_named_node (node, "Sources")) == 0) {
1178 error << _("Session: XML state has no sources section") << endmsg;
1180 } else if (load_sources (*child)) {
1184 if ((child = find_named_node (node, "Regions")) == 0) {
1185 error << _("Session: XML state has no Regions section") << endmsg;
1187 } else if (load_regions (*child)) {
1191 if ((child = find_named_node (node, "Playlists")) == 0) {
1192 error << _("Session: XML state has no playlists section") << endmsg;
1194 } else if (load_playlists (*child)) {
1198 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1200 } else if (load_unused_playlists (*child)) {
1204 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1205 if (load_named_selections (*child)) {
1210 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1211 error << _("Session: XML state has no diskstreams section") << endmsg;
1213 } else if (load_diskstreams (*child)) {
1217 if ((child = find_named_node (node, "Connections")) == 0) {
1218 error << _("Session: XML state has no connections section") << endmsg;
1220 } else if (load_bundles (*child)) {
1224 if ((child = find_named_node (node, "EditGroups")) == 0) {
1225 error << _("Session: XML state has no edit groups section") << endmsg;
1227 } else if (load_edit_groups (*child)) {
1231 if ((child = find_named_node (node, "MixGroups")) == 0) {
1232 error << _("Session: XML state has no mix groups section") << endmsg;
1234 } else if (load_mix_groups (*child)) {
1238 if ((child = find_named_node (node, "TempoMap")) == 0) {
1239 error << _("Session: XML state has no Tempo Map section") << endmsg;
1241 } else if (_tempo_map->set_state (*child)) {
1245 if ((child = find_named_node (node, "Routes")) == 0) {
1246 error << _("Session: XML state has no routes section") << endmsg;
1248 } else if (load_routes (*child)) {
1252 if ((child = find_named_node (node, "Click")) == 0) {
1253 warning << _("Session: XML state has no click section") << endmsg;
1254 } else if (_click_io) {
1255 _click_io->set_state (*child);
1258 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1259 ControlProtocolManager::instance().set_protocol_states (*child);
1262 /* here beginneth the second phase ... */
1264 StateReady (); /* EMIT SIGNAL */
1266 _state_of_the_state = Clean;
1268 if (state_was_pending) {
1269 save_state (_current_snapshot_name);
1270 remove_pending_capture_state ();
1271 state_was_pending = false;
1281 Session::load_routes (const XMLNode& node)
1284 XMLNodeConstIterator niter;
1285 RouteList new_routes;
1287 nlist = node.children();
1291 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1293 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1296 error << _("Session: cannot create Route from XML description.") << endmsg;
1300 new_routes.push_back (route);
1303 add_routes (new_routes);
1308 boost::shared_ptr<Route>
1309 Session::XMLRouteFactory (const XMLNode& node)
1311 if (node.name() != "Route") {
1312 return boost::shared_ptr<Route> ((Route*) 0);
1315 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1317 DataType type = DataType::AUDIO;
1318 const XMLProperty* prop = node.property("default-type");
1320 type = DataType(prop->value());
1322 assert(type != DataType::NIL);
1324 if (has_diskstream) {
1325 if (type == DataType::AUDIO) {
1326 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1329 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1333 boost::shared_ptr<Route> ret (new Route (*this, node));
1339 Session::load_regions (const XMLNode& node)
1342 XMLNodeConstIterator niter;
1343 boost::shared_ptr<Region> region;
1345 nlist = node.children();
1349 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1350 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1351 error << _("Session: cannot create Region from XML description.") << endmsg;
1358 boost::shared_ptr<Region>
1359 Session::XMLRegionFactory (const XMLNode& node, bool full)
1361 const XMLProperty* type = node.property("type");
1365 if ( !type || type->value() == "audio" ) {
1367 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1369 } else if (type->value() == "midi") {
1371 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1375 } catch (failed_constructor& err) {
1376 return boost::shared_ptr<Region> ();
1379 return boost::shared_ptr<Region> ();
1382 boost::shared_ptr<AudioRegion>
1383 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1385 const XMLProperty* prop;
1386 boost::shared_ptr<Source> source;
1387 boost::shared_ptr<AudioSource> as;
1389 uint32_t nchans = 1;
1392 if (node.name() != X_("Region")) {
1393 return boost::shared_ptr<AudioRegion>();
1396 if ((prop = node.property (X_("channels"))) != 0) {
1397 nchans = atoi (prop->value().c_str());
1400 if ((prop = node.property ("name")) == 0) {
1401 cerr << "no name for this region\n";
1405 if ((prop = node.property (X_("source-0"))) == 0) {
1406 if ((prop = node.property ("source")) == 0) {
1407 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1408 return boost::shared_ptr<AudioRegion>();
1412 PBD::ID s_id (prop->value());
1414 if ((source = source_by_id (s_id)) == 0) {
1415 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1416 return boost::shared_ptr<AudioRegion>();
1419 as = boost::dynamic_pointer_cast<AudioSource>(source);
1421 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1422 return boost::shared_ptr<AudioRegion>();
1425 sources.push_back (as);
1427 /* pickup other channels */
1429 for (uint32_t n=1; n < nchans; ++n) {
1430 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1431 if ((prop = node.property (buf)) != 0) {
1433 PBD::ID id2 (prop->value());
1435 if ((source = source_by_id (id2)) == 0) {
1436 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1437 return boost::shared_ptr<AudioRegion>();
1440 as = boost::dynamic_pointer_cast<AudioSource>(source);
1442 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1443 return boost::shared_ptr<AudioRegion>();
1445 sources.push_back (as);
1450 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1452 /* a final detail: this is the one and only place that we know how long missing files are */
1454 if (region->whole_file()) {
1455 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1456 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1458 sfp->set_length (region->length());
1467 catch (failed_constructor& err) {
1468 return boost::shared_ptr<AudioRegion>();
1472 boost::shared_ptr<MidiRegion>
1473 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1475 const XMLProperty* prop;
1476 boost::shared_ptr<Source> source;
1477 boost::shared_ptr<MidiSource> ms;
1479 uint32_t nchans = 1;
1481 if (node.name() != X_("Region")) {
1482 return boost::shared_ptr<MidiRegion>();
1485 if ((prop = node.property (X_("channels"))) != 0) {
1486 nchans = atoi (prop->value().c_str());
1489 if ((prop = node.property ("name")) == 0) {
1490 cerr << "no name for this region\n";
1494 // Multiple midi channels? that's just crazy talk
1495 assert(nchans == 1);
1497 if ((prop = node.property (X_("source-0"))) == 0) {
1498 if ((prop = node.property ("source")) == 0) {
1499 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1500 return boost::shared_ptr<MidiRegion>();
1504 PBD::ID s_id (prop->value());
1506 if ((source = source_by_id (s_id)) == 0) {
1507 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1508 return boost::shared_ptr<MidiRegion>();
1511 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1513 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1514 return boost::shared_ptr<MidiRegion>();
1517 sources.push_back (ms);
1520 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1521 /* a final detail: this is the one and only place that we know how long missing files are */
1523 if (region->whole_file()) {
1524 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1525 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1527 sfp->set_length (region->length());
1535 catch (failed_constructor& err) {
1536 return boost::shared_ptr<MidiRegion>();
1541 Session::get_sources_as_xml ()
1544 XMLNode* node = new XMLNode (X_("Sources"));
1545 Glib::Mutex::Lock lm (source_lock);
1547 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1548 node->add_child_nocopy (i->second->get_state());
1555 Session::path_from_region_name (string name, string identifier)
1557 char buf[PATH_MAX+1];
1559 string dir = discover_best_sound_dir ();
1561 for (n = 0; n < 999999; ++n) {
1562 if (identifier.length()) {
1563 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1564 identifier.c_str(), n);
1566 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1569 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1574 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1583 Session::load_sources (const XMLNode& node)
1586 XMLNodeConstIterator niter;
1587 boost::shared_ptr<Source> source;
1589 nlist = node.children();
1593 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1596 if ((source = XMLSourceFactory (**niter)) == 0) {
1597 error << _("Session: cannot create Source from XML description.") << endmsg;
1601 catch (non_existent_source& err) {
1602 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1603 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1610 boost::shared_ptr<Source>
1611 Session::XMLSourceFactory (const XMLNode& node)
1613 if (node.name() != "Source") {
1614 return boost::shared_ptr<Source>();
1618 return SourceFactory::create (*this, node);
1621 catch (failed_constructor& err) {
1622 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1623 return boost::shared_ptr<Source>();
1628 Session::save_template (string template_name)
1631 string xml_path, bak_path, template_path;
1633 if (_state_of_the_state & CannotSave) {
1638 string dir = template_dir();
1640 if ((dp = opendir (dir.c_str()))) {
1643 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1644 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1649 tree.set_root (&get_template());
1652 xml_path += template_name;
1653 xml_path += template_suffix;
1655 ifstream in(xml_path.c_str());
1658 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1664 if (!tree.write (xml_path)) {
1665 error << _("mix template not saved") << endmsg;
1673 Session::rename_template (string old_name, string new_name)
1675 string old_path = template_dir() + old_name + template_suffix;
1676 string new_path = template_dir() + new_name + template_suffix;
1678 return rename (old_path.c_str(), new_path.c_str());
1682 Session::delete_template (string name)
1684 string template_path = template_dir();
1685 template_path += name;
1686 template_path += template_suffix;
1688 return remove (template_path.c_str());
1692 Session::refresh_disk_space ()
1695 struct statfs statfsbuf;
1696 vector<space_and_path>::iterator i;
1697 Glib::Mutex::Lock lm (space_lock);
1700 /* get freespace on every FS that is part of the session path */
1702 _total_free_4k_blocks = 0;
1704 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1705 statfs ((*i).path.c_str(), &statfsbuf);
1707 scale = statfsbuf.f_bsize/4096.0;
1709 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1710 _total_free_4k_blocks += (*i).blocks;
1716 Session::ensure_sound_dir (string path, string& result)
1721 /* Ensure that the parent directory exists */
1723 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1724 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1728 /* Ensure that the sounds directory exists */
1732 result += sound_dir_name;
1734 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1735 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1741 dead += dead_sound_dir_name;
1743 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1744 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1750 peak += peak_dir_name;
1752 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1753 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1757 /* callers expect this to be terminated ... */
1764 Session::discover_best_sound_dir (bool destructive)
1766 vector<space_and_path>::iterator i;
1769 /* handle common case without system calls */
1771 if (session_dirs.size() == 1) {
1775 /* OK, here's the algorithm we're following here:
1777 We want to select which directory to use for
1778 the next file source to be created. Ideally,
1779 we'd like to use a round-robin process so as to
1780 get maximum performance benefits from splitting
1781 the files across multiple disks.
1783 However, in situations without much diskspace, an
1784 RR approach may end up filling up a filesystem
1785 with new files while others still have space.
1786 Its therefore important to pay some attention to
1787 the freespace in the filesystem holding each
1788 directory as well. However, if we did that by
1789 itself, we'd keep creating new files in the file
1790 system with the most space until it was as full
1791 as all others, thus negating any performance
1792 benefits of this RAID-1 like approach.
1794 So, we use a user-configurable space threshold. If
1795 there are at least 2 filesystems with more than this
1796 much space available, we use RR selection between them.
1797 If not, then we pick the filesystem with the most space.
1799 This gets a good balance between the two
1803 refresh_disk_space ();
1805 int free_enough = 0;
1807 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1808 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1813 if (free_enough >= 2) {
1815 bool found_it = false;
1817 /* use RR selection process, ensuring that the one
1821 i = last_rr_session_dir;
1824 if (++i == session_dirs.end()) {
1825 i = session_dirs.begin();
1828 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1829 if (ensure_sound_dir ((*i).path, result) == 0) {
1830 last_rr_session_dir = i;
1836 } while (i != last_rr_session_dir);
1839 result = sound_dir();
1844 /* pick FS with the most freespace (and that
1845 seems to actually work ...)
1848 vector<space_and_path> sorted;
1849 space_and_path_ascending_cmp cmp;
1851 sorted = session_dirs;
1852 sort (sorted.begin(), sorted.end(), cmp);
1854 for (i = sorted.begin(); i != sorted.end(); ++i) {
1855 if (ensure_sound_dir ((*i).path, result) == 0) {
1856 last_rr_session_dir = i;
1861 /* if the above fails, fall back to the most simplistic solution */
1863 if (i == sorted.end()) {
1872 Session::load_playlists (const XMLNode& node)
1875 XMLNodeConstIterator niter;
1876 boost::shared_ptr<Playlist> playlist;
1878 nlist = node.children();
1882 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1884 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1885 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1893 Session::load_unused_playlists (const XMLNode& node)
1896 XMLNodeConstIterator niter;
1897 boost::shared_ptr<Playlist> playlist;
1899 nlist = node.children();
1903 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1905 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1906 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1910 // now manually untrack it
1912 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1918 boost::shared_ptr<Playlist>
1919 Session::XMLPlaylistFactory (const XMLNode& node)
1922 return PlaylistFactory::create (*this, node);
1925 catch (failed_constructor& err) {
1926 return boost::shared_ptr<Playlist>();
1931 Session::load_named_selections (const XMLNode& node)
1934 XMLNodeConstIterator niter;
1937 nlist = node.children();
1941 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1943 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1944 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1952 Session::XMLNamedSelectionFactory (const XMLNode& node)
1955 return new NamedSelection (*this, node);
1958 catch (failed_constructor& err) {
1964 Session::old_sound_dir (bool with_path) const
1972 res += old_sound_dir_name;
1978 Session::sound_dir (bool with_path) const
1989 res += interchange_dir_name;
1991 res += legalize_for_path (_name);
1993 res += sound_dir_name;
2001 /* if this already exists, don't check for the old session sound directory */
2003 if (Glib::file_test (full, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2007 /* possibly support old session structure */
2010 string old_withpath;
2012 old_nopath += old_sound_dir_name;
2015 old_withpath = _path;
2016 old_withpath += old_sound_dir_name;
2018 if (Glib::file_test (old_withpath.c_str(), Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2020 return old_withpath;
2025 /* ok, old "sounds" directory isn't there, return the new path */
2031 Session::peak_dir () const
2034 res += peak_dir_name;
2040 Session::automation_dir () const
2043 res += "automation/";
2048 Session::template_dir ()
2050 string path = get_user_ardour_path();
2051 path += "templates/";
2057 Session::export_dir () const
2060 res += export_dir_name;
2066 Session::suffixed_search_path (string suffix, bool data)
2070 path += get_user_ardour_path();
2071 if (path[path.length()-1] != ':') {
2076 path += get_system_data_path();
2078 path += get_system_module_path();
2081 vector<string> split_path;
2083 split (path, split_path, ':');
2086 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2091 if (distance (i, split_path.end()) != 1) {
2100 Session::template_path ()
2102 return suffixed_search_path (templates_dir_name, true);
2106 Session::control_protocol_path ()
2108 return suffixed_search_path (surfaces_dir_name, false);
2112 Session::load_bundles (const XMLNode& node)
2114 XMLNodeList nlist = node.children();
2115 XMLNodeConstIterator niter;
2119 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2120 if ((*niter)->name() == "InputConnection") {
2121 add_bundle (new ARDOUR::InputBundle (**niter));
2122 } else if ((*niter)->name() == "OutputConnection") {
2123 add_bundle (new ARDOUR::OutputBundle (**niter));
2125 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2134 Session::load_edit_groups (const XMLNode& node)
2136 return load_route_groups (node, true);
2140 Session::load_mix_groups (const XMLNode& node)
2142 return load_route_groups (node, false);
2146 Session::load_route_groups (const XMLNode& node, bool edit)
2148 XMLNodeList nlist = node.children();
2149 XMLNodeConstIterator niter;
2154 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2155 if ((*niter)->name() == "RouteGroup") {
2157 rg = add_edit_group ("");
2158 rg->set_state (**niter);
2160 rg = add_mix_group ("");
2161 rg->set_state (**niter);
2170 state_file_filter (const string &str, void *arg)
2172 return (str.length() > strlen(statefile_suffix) &&
2173 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2177 bool operator()(const string* a, const string* b) {
2183 remove_end(string* state)
2185 string statename(*state);
2187 string::size_type start,end;
2188 if ((start = statename.find_last_of ('/')) != string::npos) {
2189 statename = statename.substr (start+1);
2192 if ((end = statename.rfind(".ardour")) == string::npos) {
2193 end = statename.length();
2196 return new string(statename.substr (0, end));
2200 Session::possible_states (string path)
2202 PathScanner scanner;
2203 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2205 transform(states->begin(), states->end(), states->begin(), remove_end);
2208 sort (states->begin(), states->end(), cmp);
2214 Session::possible_states () const
2216 return possible_states(_path);
2220 Session::auto_save()
2222 save_state (_current_snapshot_name);
2226 Session::add_edit_group (string name)
2228 RouteGroup* rg = new RouteGroup (*this, name);
2229 edit_groups.push_back (rg);
2230 edit_group_added (rg); /* EMIT SIGNAL */
2236 Session::add_mix_group (string name)
2238 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2239 mix_groups.push_back (rg);
2240 mix_group_added (rg); /* EMIT SIGNAL */
2246 Session::remove_edit_group (RouteGroup& rg)
2248 list<RouteGroup*>::iterator i;
2250 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2251 (*i)->apply (&Route::drop_edit_group, this);
2252 edit_groups.erase (i);
2253 edit_group_removed (); /* EMIT SIGNAL */
2260 Session::remove_mix_group (RouteGroup& rg)
2262 list<RouteGroup*>::iterator i;
2264 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2265 (*i)->apply (&Route::drop_mix_group, this);
2266 mix_groups.erase (i);
2267 mix_group_removed (); /* EMIT SIGNAL */
2274 Session::mix_group_by_name (string name)
2276 list<RouteGroup *>::iterator i;
2278 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2279 if ((*i)->name() == name) {
2287 Session::edit_group_by_name (string name)
2289 list<RouteGroup *>::iterator i;
2291 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2292 if ((*i)->name() == name) {
2300 Session::begin_reversible_command (string name)
2302 current_trans = new UndoTransaction;
2303 current_trans->set_name (name);
2307 Session::commit_reversible_command (Command *cmd)
2312 current_trans->add_command (cmd);
2315 gettimeofday (&now, 0);
2316 current_trans->set_timestamp (now);
2318 _history.add (current_trans);
2321 Session::GlobalRouteBooleanState
2322 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2324 GlobalRouteBooleanState s;
2325 boost::shared_ptr<RouteList> r = routes.reader ();
2327 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2328 if (!(*i)->hidden()) {
2329 RouteBooleanState v;
2332 Route* r = (*i).get();
2333 v.second = (r->*method)();
2342 Session::GlobalRouteMeterState
2343 Session::get_global_route_metering ()
2345 GlobalRouteMeterState s;
2346 boost::shared_ptr<RouteList> r = routes.reader ();
2348 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2349 if (!(*i)->hidden()) {
2353 v.second = (*i)->meter_point();
2363 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2365 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2367 boost::shared_ptr<Route> r = (i->first.lock());
2370 r->set_meter_point (i->second, arg);
2376 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2378 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2380 boost::shared_ptr<Route> r = (i->first.lock());
2383 Route* rp = r.get();
2384 (rp->*method) (i->second, arg);
2390 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2392 set_global_route_boolean (s, &Route::set_mute, src);
2396 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2398 set_global_route_boolean (s, &Route::set_solo, src);
2402 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2404 set_global_route_boolean (s, &Route::set_record_enable, src);
2409 Session::global_mute_memento (void* src)
2411 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2415 Session::global_metering_memento (void* src)
2417 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2421 Session::global_solo_memento (void* src)
2423 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2427 Session::global_record_enable_memento (void* src)
2429 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2434 template_filter (const string &str, void *arg)
2436 return (str.length() > strlen(template_suffix) &&
2437 str.find (template_suffix) == (str.length() - strlen (template_suffix)));
2441 Session::get_template_list (list<string> &template_names)
2443 vector<string *> *templates;
2444 PathScanner scanner;
2447 path = template_path ();
2449 templates = scanner (path, template_filter, 0, false, true);
2451 vector<string*>::iterator i;
2452 for (i = templates->begin(); i != templates->end(); ++i) {
2453 string fullpath = *(*i);
2456 start = fullpath.find_last_of ('/') + 1;
2457 if ((end = fullpath.find_last_of ('.')) <0) {
2458 end = fullpath.length();
2461 template_names.push_back(fullpath.substr(start, (end-start)));
2466 Session::read_favorite_dirs (FavoriteDirs & favs)
2468 string path = get_user_ardour_path();
2469 path += "/favorite_dirs";
2471 ifstream fav (path.c_str());
2476 if (errno != ENOENT) {
2477 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2488 getline(fav, newfav);
2494 favs.push_back (newfav);
2501 Session::write_favorite_dirs (FavoriteDirs & favs)
2503 string path = get_user_ardour_path();
2504 path += "/favorite_dirs";
2506 ofstream fav (path.c_str());
2512 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2513 fav << (*i) << endl;
2520 accept_all_non_peak_files (const string& path, void *arg)
2522 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2526 accept_all_state_files (const string& path, void *arg)
2528 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2532 Session::find_all_sources (string path, set<string>& result)
2537 if (!tree.read (path)) {
2541 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2546 XMLNodeConstIterator niter;
2548 nlist = node->children();
2552 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2556 if ((prop = (*niter)->property (X_("name"))) == 0) {
2560 if (prop->value()[0] == '/') {
2561 /* external file, ignore */
2565 string path = _path; /* /-terminated */
2566 path += sound_dir_name;
2568 path += prop->value();
2570 result.insert (path);
2577 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2579 PathScanner scanner;
2580 vector<string*>* state_files;
2582 string this_snapshot_path;
2588 if (ripped[ripped.length()-1] == '/') {
2589 ripped = ripped.substr (0, ripped.length() - 1);
2592 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2594 if (state_files == 0) {
2599 this_snapshot_path = _path;
2600 this_snapshot_path += _current_snapshot_name;
2601 this_snapshot_path += statefile_suffix;
2603 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2605 if (exclude_this_snapshot && **i == this_snapshot_path) {
2609 if (find_all_sources (**i, result) < 0) {
2617 struct RegionCounter {
2618 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2619 AudioSourceList::iterator iter;
2620 boost::shared_ptr<Region> region;
2623 RegionCounter() : count (0) {}
2627 Session::cleanup_sources (Session::cleanup_report& rep)
2629 vector<boost::shared_ptr<Source> > dead_sources;
2630 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2631 PathScanner scanner;
2633 vector<space_and_path>::iterator i;
2634 vector<space_and_path>::iterator nexti;
2635 vector<string*>* soundfiles;
2636 vector<string> unused;
2637 set<string> all_sources;
2642 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2644 /* step 1: consider deleting all unused playlists */
2646 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2649 status = AskAboutPlaylistDeletion (*x);
2658 playlists_tbd.push_back (*x);
2662 /* leave it alone */
2667 /* now delete any that were marked for deletion */
2669 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2670 (*x)->drop_references ();
2673 playlists_tbd.clear ();
2675 /* step 2: find all un-used sources */
2680 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2682 SourceMap::iterator tmp;
2687 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2691 if (!i->second->used() && i->second->length() > 0) {
2692 dead_sources.push_back (i->second);
2693 i->second->GoingAway();
2699 /* build a list of all the possible sound directories for the session */
2701 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2706 sound_path += (*i).path;
2707 sound_path += sound_dir (false);
2709 if (nexti != session_dirs.end()) {
2716 /* now do the same thing for the files that ended up in the sounds dir(s)
2717 but are not referenced as sources in any snapshot.
2720 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2722 if (soundfiles == 0) {
2726 /* find all sources, but don't use this snapshot because the
2727 state file on disk still references sources we may have already
2731 find_all_sources_across_snapshots (all_sources, true);
2733 /* add our current source list
2736 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2737 boost::shared_ptr<AudioFileSource> fs;
2739 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2740 all_sources.insert (fs->path());
2744 char tmppath1[PATH_MAX+1];
2745 char tmppath2[PATH_MAX+1];
2747 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2752 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2754 realpath(spath.c_str(), tmppath1);
2755 realpath((*i).c_str(), tmppath2);
2757 if (strcmp(tmppath1, tmppath2) == 0) {
2764 unused.push_back (spath);
2768 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2770 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2771 struct stat statbuf;
2773 rep.paths.push_back (*x);
2774 if (stat ((*x).c_str(), &statbuf) == 0) {
2775 rep.space += statbuf.st_size;
2780 /* don't move the file across filesystems, just
2781 stick it in the `dead_sound_dir_name' directory
2782 on whichever filesystem it was already on.
2785 if ((*x).find ("/sounds/") != string::npos) {
2787 /* old school, go up 1 level */
2789 newpath = Glib::path_get_dirname (*x); // "sounds"
2790 newpath = Glib::path_get_dirname (newpath); // "session-name"
2794 /* new school, go up 4 levels */
2796 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2797 newpath = Glib::path_get_dirname (newpath); // "session-name"
2798 newpath = Glib::path_get_dirname (newpath); // "interchange"
2799 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2803 newpath += dead_sound_dir_name;
2805 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2806 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2811 newpath += Glib::path_get_basename ((*x));
2813 if (access (newpath.c_str(), F_OK) == 0) {
2815 /* the new path already exists, try versioning */
2817 char buf[PATH_MAX+1];
2821 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2824 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2825 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2829 if (version == 999) {
2830 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2834 newpath = newpath_v;
2839 /* it doesn't exist, or we can't read it or something */
2843 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2844 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2845 (*x), newpath, strerror (errno))
2850 /* see if there an easy to find peakfile for this file, and remove it.
2853 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2854 peakpath += peakfile_suffix;
2856 if (access (peakpath.c_str(), W_OK) == 0) {
2857 if (::unlink (peakpath.c_str()) != 0) {
2858 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2859 peakpath, _path, strerror (errno))
2861 /* try to back out */
2862 rename (newpath.c_str(), _path.c_str());
2870 /* dump the history list */
2874 /* save state so we don't end up a session file
2875 referring to non-existent sources.
2881 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2886 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2888 vector<space_and_path>::iterator i;
2889 string dead_sound_dir;
2890 struct dirent* dentry;
2891 struct stat statbuf;
2897 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2899 dead_sound_dir = (*i).path;
2900 dead_sound_dir += dead_sound_dir_name;
2902 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2906 while ((dentry = readdir (dead)) != 0) {
2908 /* avoid '.' and '..' */
2910 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2911 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2917 fullpath = dead_sound_dir;
2919 fullpath += dentry->d_name;
2921 if (stat (fullpath.c_str(), &statbuf)) {
2925 if (!S_ISREG (statbuf.st_mode)) {
2929 if (unlink (fullpath.c_str())) {
2930 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2931 fullpath, strerror (errno))
2935 rep.paths.push_back (dentry->d_name);
2936 rep.space += statbuf.st_size;
2947 Session::set_dirty ()
2949 bool was_dirty = dirty();
2951 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2954 DirtyChanged(); /* EMIT SIGNAL */
2960 Session::set_clean ()
2962 bool was_dirty = dirty();
2964 _state_of_the_state = Clean;
2967 DirtyChanged(); /* EMIT SIGNAL */
2972 Session::set_deletion_in_progress ()
2974 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2978 Session::add_controllable (Controllable* c)
2980 /* this adds a controllable to the list managed by the Session.
2981 this is a subset of those managed by the Controllable class
2982 itself, and represents the only ones whose state will be saved
2983 as part of the session.
2986 Glib::Mutex::Lock lm (controllables_lock);
2987 controllables.insert (c);
2991 Session::remove_controllable (Controllable* c)
2993 if (_state_of_the_state | Deletion) {
2997 Glib::Mutex::Lock lm (controllables_lock);
2999 Controllables::iterator x = controllables.find (c);
3001 if (x != controllables.end()) {
3002 controllables.erase (x);
3007 Session::controllable_by_id (const PBD::ID& id)
3009 Glib::Mutex::Lock lm (controllables_lock);
3011 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3012 if ((*i)->id() == id) {
3021 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3023 Stateful::add_instant_xml (node, dir);
3024 Config->add_instant_xml (node, get_user_ardour_path());
3029 Session::save_history (string snapshot_name)
3035 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3037 if (snapshot_name.empty()) {
3038 snapshot_name = _current_snapshot_name;
3041 xml_path = _path + snapshot_name + ".history";
3043 bak_path = xml_path + ".bak";
3045 if ((access (xml_path.c_str(), F_OK) == 0) &&
3046 (rename (xml_path.c_str(), bak_path.c_str())))
3048 error << _("could not backup old history file, current history not saved.") << endmsg;
3052 if (!tree.write (xml_path))
3054 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3056 /* don't leave a corrupt file lying around if it is
3060 if (unlink (xml_path.c_str())) {
3061 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
3063 if (rename (bak_path.c_str(), xml_path.c_str()))
3065 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
3076 Session::restore_history (string snapshot_name)
3081 if (snapshot_name.empty()) {
3082 snapshot_name = _current_snapshot_name;
3086 xmlpath = _path + snapshot_name + ".history";
3087 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
3089 if (access (xmlpath.c_str(), F_OK)) {
3090 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
3094 if (!tree.read (xmlpath)) {
3095 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
3099 /* replace history */
3102 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3105 UndoTransaction* ut = new UndoTransaction ();
3108 ut->set_name(t->property("name")->value());
3109 stringstream ss(t->property("tv_sec")->value());
3111 ss.str(t->property("tv_usec")->value());
3113 ut->set_timestamp(tv);
3115 for (XMLNodeConstIterator child_it = t->children().begin();
3116 child_it != t->children().end();
3119 XMLNode *n = *child_it;
3122 if (n->name() == "MementoCommand" ||
3123 n->name() == "MementoUndoCommand" ||
3124 n->name() == "MementoRedoCommand") {
3126 if ((c = memento_command_factory(n))) {
3130 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3132 if ((c = global_state_command_factory (*n))) {
3133 ut->add_command (c);
3138 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3149 Session::config_changed (const char* parameter_name)
3151 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3153 if (PARAM_IS ("seamless-loop")) {
3155 } else if (PARAM_IS ("rf-speed")) {
3157 } else if (PARAM_IS ("auto-loop")) {
3159 } else if (PARAM_IS ("auto-input")) {
3161 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3162 /* auto-input only makes a difference if we're rolling */
3164 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3166 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3167 if ((*i)->record_enabled ()) {
3168 (*i)->monitor_input (!Config->get_auto_input());
3173 } else if (PARAM_IS ("punch-in")) {
3177 if ((location = _locations.auto_punch_location()) != 0) {
3179 if (Config->get_punch_in ()) {
3180 replace_event (Event::PunchIn, location->start());
3182 remove_event (location->start(), Event::PunchIn);
3186 } else if (PARAM_IS ("punch-out")) {
3190 if ((location = _locations.auto_punch_location()) != 0) {
3192 if (Config->get_punch_out()) {
3193 replace_event (Event::PunchOut, location->end());
3195 clear_events (Event::PunchOut);
3199 } else if (PARAM_IS ("edit-mode")) {
3201 Glib::Mutex::Lock lm (playlist_lock);
3203 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3204 (*i)->set_edit_mode (Config->get_edit_mode ());
3207 } else if (PARAM_IS ("use-video-sync")) {
3209 waiting_for_sync_offset = Config->get_use_video_sync();
3211 } else if (PARAM_IS ("mmc-control")) {
3213 //poke_midi_thread ();
3215 } else if (PARAM_IS ("mmc-device-id")) {
3218 mmc->set_device_id (Config->get_mmc_device_id());
3221 } else if (PARAM_IS ("midi-control")) {
3223 //poke_midi_thread ();
3225 } else if (PARAM_IS ("raid-path")) {
3227 setup_raid_path (Config->get_raid_path());
3229 } else if (PARAM_IS ("smpte-format")) {
3233 } else if (PARAM_IS ("video-pullup")) {
3237 } else if (PARAM_IS ("seamless-loop")) {
3239 if (play_loop && transport_rolling()) {
3240 // to reset diskstreams etc
3241 request_play_loop (true);
3244 } else if (PARAM_IS ("rf-speed")) {
3246 cumulative_rf_motion = 0;
3249 } else if (PARAM_IS ("click-sound")) {
3251 setup_click_sounds (1);
3253 } else if (PARAM_IS ("click-emphasis-sound")) {
3255 setup_click_sounds (-1);
3257 } else if (PARAM_IS ("clicking")) {
3259 if (Config->get_clicking()) {
3260 if (_click_io && click_data) { // don't require emphasis data
3267 } else if (PARAM_IS ("send-mtc")) {
3269 /* only set the internal flag if we have
3273 if (_mtc_port != 0) {
3274 session_send_mtc = Config->get_send_mtc();
3275 if (session_send_mtc) {
3276 /* mark us ready to send */
3277 next_quarter_frame_to_send = 0;
3280 session_send_mtc = false;
3283 } else if (PARAM_IS ("send-mmc")) {
3285 /* only set the internal flag if we have
3289 if (_mmc_port != 0) {
3290 session_send_mmc = Config->get_send_mmc();
3293 session_send_mmc = false;
3296 } else if (PARAM_IS ("midi-feedback")) {
3298 /* only set the internal flag if we have
3302 if (_mtc_port != 0) {
3303 session_midi_feedback = Config->get_midi_feedback();
3306 } else if (PARAM_IS ("jack-time-master")) {
3308 engine().reset_timebase ();
3310 } else if (PARAM_IS ("native-file-header-format")) {
3312 if (!first_file_header_format_reset) {
3313 reset_native_file_format ();
3316 first_file_header_format_reset = false;
3318 } else if (PARAM_IS ("native-file-data-format")) {
3320 if (!first_file_data_format_reset) {
3321 reset_native_file_format ();
3324 first_file_data_format_reset = false;
3326 } else if (PARAM_IS ("slave-source")) {
3327 set_slave_source (Config->get_slave_source());
3328 } else if (PARAM_IS ("remote-model")) {
3329 set_remote_control_ids ();
3330 } else if (PARAM_IS ("denormal-model")) {