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::dead_sound_dir () const
1967 res += dead_sound_dir_name;
1973 Session::old_sound_dir (bool with_path) const
1981 res += old_sound_dir_name;
1987 Session::sound_dir (bool with_path) const
1998 res += interchange_dir_name;
2000 res += legalize_for_path (_name);
2002 res += sound_dir_name;
2010 /* if this already exists, don't check for the old session sound directory */
2012 if (Glib::file_test (full, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2016 /* possibly support old session structure */
2019 string old_withpath;
2021 old_nopath += old_sound_dir_name;
2024 old_withpath = _path;
2025 old_withpath += old_sound_dir_name;
2027 if (Glib::file_test (old_withpath.c_str(), Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2029 return old_withpath;
2034 /* ok, old "sounds" directory isn't there, return the new path */
2040 Session::peak_dir () const
2043 res += peak_dir_name;
2049 Session::automation_dir () const
2052 res += "automation/";
2057 Session::template_dir ()
2059 string path = get_user_ardour_path();
2060 path += "templates/";
2066 Session::export_dir () const
2069 res += export_dir_name;
2075 Session::suffixed_search_path (string suffix, bool data)
2079 path += get_user_ardour_path();
2080 if (path[path.length()-1] != ':') {
2085 path += get_system_data_path();
2087 path += get_system_module_path();
2090 vector<string> split_path;
2092 split (path, split_path, ':');
2095 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2100 if (distance (i, split_path.end()) != 1) {
2109 Session::template_path ()
2111 return suffixed_search_path (X_("templates"), true);
2115 Session::control_protocol_path ()
2117 return suffixed_search_path (X_("surfaces"), false);
2121 Session::load_bundles (const XMLNode& node)
2123 XMLNodeList nlist = node.children();
2124 XMLNodeConstIterator niter;
2128 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2129 if ((*niter)->name() == "InputConnection") {
2130 add_bundle (new ARDOUR::InputBundle (**niter));
2131 } else if ((*niter)->name() == "OutputConnection") {
2132 add_bundle (new ARDOUR::OutputBundle (**niter));
2134 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2143 Session::load_edit_groups (const XMLNode& node)
2145 return load_route_groups (node, true);
2149 Session::load_mix_groups (const XMLNode& node)
2151 return load_route_groups (node, false);
2155 Session::load_route_groups (const XMLNode& node, bool edit)
2157 XMLNodeList nlist = node.children();
2158 XMLNodeConstIterator niter;
2163 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2164 if ((*niter)->name() == "RouteGroup") {
2166 rg = add_edit_group ("");
2167 rg->set_state (**niter);
2169 rg = add_mix_group ("");
2170 rg->set_state (**niter);
2179 state_file_filter (const string &str, void *arg)
2181 return (str.length() > strlen(statefile_suffix) &&
2182 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2186 bool operator()(const string* a, const string* b) {
2192 remove_end(string* state)
2194 string statename(*state);
2196 string::size_type start,end;
2197 if ((start = statename.find_last_of ('/')) != string::npos) {
2198 statename = statename.substr (start+1);
2201 if ((end = statename.rfind(".ardour")) == string::npos) {
2202 end = statename.length();
2205 return new string(statename.substr (0, end));
2209 Session::possible_states (string path)
2211 PathScanner scanner;
2212 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2214 transform(states->begin(), states->end(), states->begin(), remove_end);
2217 sort (states->begin(), states->end(), cmp);
2223 Session::possible_states () const
2225 return possible_states(_path);
2229 Session::auto_save()
2231 save_state (_current_snapshot_name);
2235 Session::add_edit_group (string name)
2237 RouteGroup* rg = new RouteGroup (*this, name);
2238 edit_groups.push_back (rg);
2239 edit_group_added (rg); /* EMIT SIGNAL */
2245 Session::add_mix_group (string name)
2247 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2248 mix_groups.push_back (rg);
2249 mix_group_added (rg); /* EMIT SIGNAL */
2255 Session::remove_edit_group (RouteGroup& rg)
2257 list<RouteGroup*>::iterator i;
2259 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2260 (*i)->apply (&Route::drop_edit_group, this);
2261 edit_groups.erase (i);
2262 edit_group_removed (); /* EMIT SIGNAL */
2269 Session::remove_mix_group (RouteGroup& rg)
2271 list<RouteGroup*>::iterator i;
2273 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2274 (*i)->apply (&Route::drop_mix_group, this);
2275 mix_groups.erase (i);
2276 mix_group_removed (); /* EMIT SIGNAL */
2283 Session::mix_group_by_name (string name)
2285 list<RouteGroup *>::iterator i;
2287 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2288 if ((*i)->name() == name) {
2296 Session::edit_group_by_name (string name)
2298 list<RouteGroup *>::iterator i;
2300 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2301 if ((*i)->name() == name) {
2309 Session::begin_reversible_command (string name)
2311 current_trans = new UndoTransaction;
2312 current_trans->set_name (name);
2316 Session::commit_reversible_command (Command *cmd)
2321 current_trans->add_command (cmd);
2324 gettimeofday (&now, 0);
2325 current_trans->set_timestamp (now);
2327 _history.add (current_trans);
2330 Session::GlobalRouteBooleanState
2331 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2333 GlobalRouteBooleanState s;
2334 boost::shared_ptr<RouteList> r = routes.reader ();
2336 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2337 if (!(*i)->hidden()) {
2338 RouteBooleanState v;
2341 Route* r = (*i).get();
2342 v.second = (r->*method)();
2351 Session::GlobalRouteMeterState
2352 Session::get_global_route_metering ()
2354 GlobalRouteMeterState s;
2355 boost::shared_ptr<RouteList> r = routes.reader ();
2357 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2358 if (!(*i)->hidden()) {
2362 v.second = (*i)->meter_point();
2372 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2374 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2376 boost::shared_ptr<Route> r = (i->first.lock());
2379 r->set_meter_point (i->second, arg);
2385 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2387 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2389 boost::shared_ptr<Route> r = (i->first.lock());
2392 Route* rp = r.get();
2393 (rp->*method) (i->second, arg);
2399 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2401 set_global_route_boolean (s, &Route::set_mute, src);
2405 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2407 set_global_route_boolean (s, &Route::set_solo, src);
2411 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2413 set_global_route_boolean (s, &Route::set_record_enable, src);
2418 Session::global_mute_memento (void* src)
2420 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2424 Session::global_metering_memento (void* src)
2426 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2430 Session::global_solo_memento (void* src)
2432 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2436 Session::global_record_enable_memento (void* src)
2438 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2443 template_filter (const string &str, void *arg)
2445 return (str.length() > strlen(template_suffix) &&
2446 str.find (template_suffix) == (str.length() - strlen (template_suffix)));
2450 Session::get_template_list (list<string> &template_names)
2452 vector<string *> *templates;
2453 PathScanner scanner;
2456 path = template_path ();
2458 templates = scanner (path, template_filter, 0, false, true);
2460 vector<string*>::iterator i;
2461 for (i = templates->begin(); i != templates->end(); ++i) {
2462 string fullpath = *(*i);
2465 start = fullpath.find_last_of ('/') + 1;
2466 if ((end = fullpath.find_last_of ('.')) <0) {
2467 end = fullpath.length();
2470 template_names.push_back(fullpath.substr(start, (end-start)));
2475 Session::read_favorite_dirs (FavoriteDirs & favs)
2477 string path = get_user_ardour_path();
2478 path += "/favorite_dirs";
2480 ifstream fav (path.c_str());
2485 if (errno != ENOENT) {
2486 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2497 getline(fav, newfav);
2503 favs.push_back (newfav);
2510 Session::write_favorite_dirs (FavoriteDirs & favs)
2512 string path = get_user_ardour_path();
2513 path += "/favorite_dirs";
2515 ofstream fav (path.c_str());
2521 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2522 fav << (*i) << endl;
2529 accept_all_non_peak_files (const string& path, void *arg)
2531 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2535 accept_all_state_files (const string& path, void *arg)
2537 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2541 Session::find_all_sources (string path, set<string>& result)
2546 if (!tree.read (path)) {
2550 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2555 XMLNodeConstIterator niter;
2557 nlist = node->children();
2561 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2565 if ((prop = (*niter)->property (X_("name"))) == 0) {
2569 if (prop->value()[0] == '/') {
2570 /* external file, ignore */
2574 string path = _path; /* /-terminated */
2575 path += sound_dir_name;
2577 path += prop->value();
2579 result.insert (path);
2586 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2588 PathScanner scanner;
2589 vector<string*>* state_files;
2591 string this_snapshot_path;
2597 if (ripped[ripped.length()-1] == '/') {
2598 ripped = ripped.substr (0, ripped.length() - 1);
2601 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2603 if (state_files == 0) {
2608 this_snapshot_path = _path;
2609 this_snapshot_path += _current_snapshot_name;
2610 this_snapshot_path += statefile_suffix;
2612 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2614 if (exclude_this_snapshot && **i == this_snapshot_path) {
2618 if (find_all_sources (**i, result) < 0) {
2626 struct RegionCounter {
2627 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2628 AudioSourceList::iterator iter;
2629 boost::shared_ptr<Region> region;
2632 RegionCounter() : count (0) {}
2636 Session::cleanup_sources (Session::cleanup_report& rep)
2638 vector<boost::shared_ptr<Source> > dead_sources;
2639 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2640 PathScanner scanner;
2642 vector<space_and_path>::iterator i;
2643 vector<space_and_path>::iterator nexti;
2644 vector<string*>* soundfiles;
2645 vector<string> unused;
2646 set<string> all_sources;
2651 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2653 /* step 1: consider deleting all unused playlists */
2655 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2658 status = AskAboutPlaylistDeletion (*x);
2667 playlists_tbd.push_back (*x);
2671 /* leave it alone */
2676 /* now delete any that were marked for deletion */
2678 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2679 (*x)->drop_references ();
2682 playlists_tbd.clear ();
2684 /* step 2: find all un-used sources */
2689 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2691 SourceMap::iterator tmp;
2696 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2700 if (!i->second->used() && i->second->length() > 0) {
2701 dead_sources.push_back (i->second);
2702 i->second->GoingAway();
2708 /* build a list of all the possible sound directories for the session */
2710 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2715 sound_path += (*i).path;
2716 sound_path += sound_dir (false);
2718 if (nexti != session_dirs.end()) {
2725 /* now do the same thing for the files that ended up in the sounds dir(s)
2726 but are not referenced as sources in any snapshot.
2729 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2731 if (soundfiles == 0) {
2735 /* find all sources, but don't use this snapshot because the
2736 state file on disk still references sources we may have already
2740 find_all_sources_across_snapshots (all_sources, true);
2742 /* add our current source list
2745 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2746 boost::shared_ptr<AudioFileSource> fs;
2748 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2749 all_sources.insert (fs->path());
2753 char tmppath1[PATH_MAX+1];
2754 char tmppath2[PATH_MAX+1];
2756 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2761 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2763 realpath(spath.c_str(), tmppath1);
2764 realpath((*i).c_str(), tmppath2);
2766 if (strcmp(tmppath1, tmppath2) == 0) {
2773 unused.push_back (spath);
2777 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2779 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2780 struct stat statbuf;
2782 rep.paths.push_back (*x);
2783 if (stat ((*x).c_str(), &statbuf) == 0) {
2784 rep.space += statbuf.st_size;
2789 /* don't move the file across filesystems, just
2790 stick it in the `dead_sound_dir_name' directory
2791 on whichever filesystem it was already on.
2794 if ((*x).find ("/sounds/") != string::npos) {
2796 /* old school, go up 1 level */
2798 newpath = Glib::path_get_dirname (*x); // "sounds"
2799 newpath = Glib::path_get_dirname (newpath); // "session-name"
2803 /* new school, go up 4 levels */
2805 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2806 newpath = Glib::path_get_dirname (newpath); // "session-name"
2807 newpath = Glib::path_get_dirname (newpath); // "interchange"
2808 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2812 newpath += dead_sound_dir_name;
2814 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2815 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2820 newpath += Glib::path_get_basename ((*x));
2822 if (access (newpath.c_str(), F_OK) == 0) {
2824 /* the new path already exists, try versioning */
2826 char buf[PATH_MAX+1];
2830 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2833 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2834 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2838 if (version == 999) {
2839 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2843 newpath = newpath_v;
2848 /* it doesn't exist, or we can't read it or something */
2852 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2853 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2854 (*x), newpath, strerror (errno))
2859 /* see if there an easy to find peakfile for this file, and remove it.
2862 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2863 peakpath += ".peak";
2865 if (access (peakpath.c_str(), W_OK) == 0) {
2866 if (::unlink (peakpath.c_str()) != 0) {
2867 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2868 peakpath, _path, strerror (errno))
2870 /* try to back out */
2871 rename (newpath.c_str(), _path.c_str());
2879 /* dump the history list */
2883 /* save state so we don't end up a session file
2884 referring to non-existent sources.
2890 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2895 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2897 vector<space_and_path>::iterator i;
2898 string dead_sound_dir;
2899 struct dirent* dentry;
2900 struct stat statbuf;
2906 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2908 dead_sound_dir = (*i).path;
2909 dead_sound_dir += dead_sound_dir_name;
2911 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2915 while ((dentry = readdir (dead)) != 0) {
2917 /* avoid '.' and '..' */
2919 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2920 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2926 fullpath = dead_sound_dir;
2928 fullpath += dentry->d_name;
2930 if (stat (fullpath.c_str(), &statbuf)) {
2934 if (!S_ISREG (statbuf.st_mode)) {
2938 if (unlink (fullpath.c_str())) {
2939 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2940 fullpath, strerror (errno))
2944 rep.paths.push_back (dentry->d_name);
2945 rep.space += statbuf.st_size;
2956 Session::set_dirty ()
2958 bool was_dirty = dirty();
2960 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2963 DirtyChanged(); /* EMIT SIGNAL */
2969 Session::set_clean ()
2971 bool was_dirty = dirty();
2973 _state_of_the_state = Clean;
2976 DirtyChanged(); /* EMIT SIGNAL */
2981 Session::set_deletion_in_progress ()
2983 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2987 Session::add_controllable (Controllable* c)
2989 /* this adds a controllable to the list managed by the Session.
2990 this is a subset of those managed by the Controllable class
2991 itself, and represents the only ones whose state will be saved
2992 as part of the session.
2995 Glib::Mutex::Lock lm (controllables_lock);
2996 controllables.insert (c);
3000 Session::remove_controllable (Controllable* c)
3002 if (_state_of_the_state | Deletion) {
3006 Glib::Mutex::Lock lm (controllables_lock);
3008 Controllables::iterator x = controllables.find (c);
3010 if (x != controllables.end()) {
3011 controllables.erase (x);
3016 Session::controllable_by_id (const PBD::ID& id)
3018 Glib::Mutex::Lock lm (controllables_lock);
3020 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3021 if ((*i)->id() == id) {
3030 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3032 Stateful::add_instant_xml (node, dir);
3033 Config->add_instant_xml (node, get_user_ardour_path());
3038 Session::save_history (string snapshot_name)
3044 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3046 if (snapshot_name.empty()) {
3047 snapshot_name = _current_snapshot_name;
3050 xml_path = _path + snapshot_name + ".history";
3052 bak_path = xml_path + ".bak";
3054 if ((access (xml_path.c_str(), F_OK) == 0) &&
3055 (rename (xml_path.c_str(), bak_path.c_str())))
3057 error << _("could not backup old history file, current history not saved.") << endmsg;
3061 if (!tree.write (xml_path))
3063 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3065 /* don't leave a corrupt file lying around if it is
3069 if (unlink (xml_path.c_str())) {
3070 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
3072 if (rename (bak_path.c_str(), xml_path.c_str()))
3074 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
3085 Session::restore_history (string snapshot_name)
3090 if (snapshot_name.empty()) {
3091 snapshot_name = _current_snapshot_name;
3095 xmlpath = _path + snapshot_name + ".history";
3096 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
3098 if (access (xmlpath.c_str(), F_OK)) {
3099 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
3103 if (!tree.read (xmlpath)) {
3104 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
3108 /* replace history */
3111 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3114 UndoTransaction* ut = new UndoTransaction ();
3117 ut->set_name(t->property("name")->value());
3118 stringstream ss(t->property("tv_sec")->value());
3120 ss.str(t->property("tv_usec")->value());
3122 ut->set_timestamp(tv);
3124 for (XMLNodeConstIterator child_it = t->children().begin();
3125 child_it != t->children().end();
3128 XMLNode *n = *child_it;
3131 if (n->name() == "MementoCommand" ||
3132 n->name() == "MementoUndoCommand" ||
3133 n->name() == "MementoRedoCommand") {
3135 if ((c = memento_command_factory(n))) {
3139 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3141 if ((c = global_state_command_factory (*n))) {
3142 ut->add_command (c);
3147 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3158 Session::config_changed (const char* parameter_name)
3160 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3162 if (PARAM_IS ("seamless-loop")) {
3164 } else if (PARAM_IS ("rf-speed")) {
3166 } else if (PARAM_IS ("auto-loop")) {
3168 } else if (PARAM_IS ("auto-input")) {
3170 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3171 /* auto-input only makes a difference if we're rolling */
3173 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3175 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3176 if ((*i)->record_enabled ()) {
3177 (*i)->monitor_input (!Config->get_auto_input());
3182 } else if (PARAM_IS ("punch-in")) {
3186 if ((location = _locations.auto_punch_location()) != 0) {
3188 if (Config->get_punch_in ()) {
3189 replace_event (Event::PunchIn, location->start());
3191 remove_event (location->start(), Event::PunchIn);
3195 } else if (PARAM_IS ("punch-out")) {
3199 if ((location = _locations.auto_punch_location()) != 0) {
3201 if (Config->get_punch_out()) {
3202 replace_event (Event::PunchOut, location->end());
3204 clear_events (Event::PunchOut);
3208 } else if (PARAM_IS ("edit-mode")) {
3210 Glib::Mutex::Lock lm (playlist_lock);
3212 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3213 (*i)->set_edit_mode (Config->get_edit_mode ());
3216 } else if (PARAM_IS ("use-video-sync")) {
3218 waiting_for_sync_offset = Config->get_use_video_sync();
3220 } else if (PARAM_IS ("mmc-control")) {
3222 //poke_midi_thread ();
3224 } else if (PARAM_IS ("mmc-device-id")) {
3227 mmc->set_device_id (Config->get_mmc_device_id());
3230 } else if (PARAM_IS ("midi-control")) {
3232 //poke_midi_thread ();
3234 } else if (PARAM_IS ("raid-path")) {
3236 setup_raid_path (Config->get_raid_path());
3238 } else if (PARAM_IS ("smpte-format")) {
3242 } else if (PARAM_IS ("video-pullup")) {
3246 } else if (PARAM_IS ("seamless-loop")) {
3248 if (play_loop && transport_rolling()) {
3249 // to reset diskstreams etc
3250 request_play_loop (true);
3253 } else if (PARAM_IS ("rf-speed")) {
3255 cumulative_rf_motion = 0;
3258 } else if (PARAM_IS ("click-sound")) {
3260 setup_click_sounds (1);
3262 } else if (PARAM_IS ("click-emphasis-sound")) {
3264 setup_click_sounds (-1);
3266 } else if (PARAM_IS ("clicking")) {
3268 if (Config->get_clicking()) {
3269 if (_click_io && click_data) { // don't require emphasis data
3276 } else if (PARAM_IS ("send-mtc")) {
3278 /* only set the internal flag if we have
3282 if (_mtc_port != 0) {
3283 session_send_mtc = Config->get_send_mtc();
3284 if (session_send_mtc) {
3285 /* mark us ready to send */
3286 next_quarter_frame_to_send = 0;
3289 session_send_mtc = false;
3292 } else if (PARAM_IS ("send-mmc")) {
3294 /* only set the internal flag if we have
3298 if (_mmc_port != 0) {
3299 session_send_mmc = Config->get_send_mmc();
3302 session_send_mmc = false;
3305 } else if (PARAM_IS ("midi-feedback")) {
3307 /* only set the internal flag if we have
3311 if (_mtc_port != 0) {
3312 session_midi_feedback = Config->get_midi_feedback();
3315 } else if (PARAM_IS ("jack-time-master")) {
3317 engine().reset_timebase ();
3319 } else if (PARAM_IS ("native-file-header-format")) {
3321 if (!first_file_header_format_reset) {
3322 reset_native_file_format ();
3325 first_file_header_format_reset = false;
3327 } else if (PARAM_IS ("native-file-data-format")) {
3329 if (!first_file_data_format_reset) {
3330 reset_native_file_format ();
3333 first_file_data_format_reset = false;
3335 } else if (PARAM_IS ("slave-source")) {
3336 set_slave_source (Config->get_slave_source());
3337 } else if (PARAM_IS ("remote-model")) {
3338 set_remote_control_ids ();
3339 } else if (PARAM_IS ("denormal-model")) {