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());
1401 if ((prop = node.property ("name")) == 0) {
1402 cerr << "no name for this region\n";
1406 if ((prop = node.property (X_("source-0"))) == 0) {
1407 if ((prop = node.property ("source")) == 0) {
1408 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1409 return boost::shared_ptr<AudioRegion>();
1413 PBD::ID s_id (prop->value());
1415 if ((source = source_by_id (s_id)) == 0) {
1416 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1417 return boost::shared_ptr<AudioRegion>();
1420 as = boost::dynamic_pointer_cast<AudioSource>(source);
1422 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1423 return boost::shared_ptr<AudioRegion>();
1426 sources.push_back (as);
1428 /* pickup other channels */
1430 for (uint32_t n=1; n < nchans; ++n) {
1431 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1432 if ((prop = node.property (buf)) != 0) {
1434 PBD::ID id2 (prop->value());
1436 if ((source = source_by_id (id2)) == 0) {
1437 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1438 return boost::shared_ptr<AudioRegion>();
1441 as = boost::dynamic_pointer_cast<AudioSource>(source);
1443 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1444 return boost::shared_ptr<AudioRegion>();
1446 sources.push_back (as);
1451 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1453 /* a final detail: this is the one and only place that we know how long missing files are */
1455 if (region->whole_file()) {
1456 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1457 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1459 sfp->set_length (region->length());
1469 catch (failed_constructor& err) {
1470 return boost::shared_ptr<AudioRegion>();
1474 boost::shared_ptr<MidiRegion>
1475 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1477 const XMLProperty* prop;
1478 boost::shared_ptr<Source> source;
1479 boost::shared_ptr<MidiSource> ms;
1480 MidiRegion::SourceList sources;
1481 uint32_t nchans = 1;
1483 if (node.name() != X_("Region")) {
1484 return boost::shared_ptr<MidiRegion>();
1487 if ((prop = node.property (X_("channels"))) != 0) {
1488 nchans = atoi (prop->value().c_str());
1491 // Multiple midi channels? that's just crazy talk
1492 assert(nchans == 1);
1494 if ((prop = node.property (X_("source-0"))) == 0) {
1495 if ((prop = node.property ("source")) == 0) {
1496 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1497 return boost::shared_ptr<MidiRegion>();
1501 PBD::ID s_id (prop->value());
1503 if ((source = source_by_id (s_id)) == 0) {
1504 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1505 return boost::shared_ptr<MidiRegion>();
1508 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1510 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1511 return boost::shared_ptr<MidiRegion>();
1514 sources.push_back (ms);
1517 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1521 catch (failed_constructor& err) {
1522 return boost::shared_ptr<MidiRegion>();
1527 Session::get_sources_as_xml ()
1530 XMLNode* node = new XMLNode (X_("Sources"));
1531 Glib::Mutex::Lock lm (source_lock);
1533 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1534 node->add_child_nocopy (i->second->get_state());
1537 /* XXX get MIDI and other sources here */
1543 Session::path_from_region_name (string name, string identifier)
1545 char buf[PATH_MAX+1];
1547 string dir = discover_best_sound_dir ();
1549 for (n = 0; n < 999999; ++n) {
1550 if (identifier.length()) {
1551 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1552 identifier.c_str(), n);
1554 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1557 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1562 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1571 Session::load_sources (const XMLNode& node)
1574 XMLNodeConstIterator niter;
1575 boost::shared_ptr<Source> source;
1577 nlist = node.children();
1581 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1584 if ((source = XMLSourceFactory (**niter)) == 0) {
1585 error << _("Session: cannot create Source from XML description.") << endmsg;
1589 catch (non_existent_source& err) {
1590 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1591 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1598 boost::shared_ptr<Source>
1599 Session::XMLSourceFactory (const XMLNode& node)
1601 if (node.name() != "Source") {
1602 return boost::shared_ptr<Source>();
1606 return SourceFactory::create (*this, node);
1609 catch (failed_constructor& err) {
1610 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1611 return boost::shared_ptr<Source>();
1616 Session::save_template (string template_name)
1619 string xml_path, bak_path, template_path;
1621 if (_state_of_the_state & CannotSave) {
1626 string dir = template_dir();
1628 if ((dp = opendir (dir.c_str()))) {
1631 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1632 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1637 tree.set_root (&get_template());
1640 xml_path += template_name;
1641 xml_path += template_suffix;
1643 ifstream in(xml_path.c_str());
1646 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1652 if (!tree.write (xml_path)) {
1653 error << _("mix template not saved") << endmsg;
1661 Session::rename_template (string old_name, string new_name)
1663 string old_path = template_dir() + old_name + template_suffix;
1664 string new_path = template_dir() + new_name + template_suffix;
1666 return rename (old_path.c_str(), new_path.c_str());
1670 Session::delete_template (string name)
1672 string template_path = template_dir();
1673 template_path += name;
1674 template_path += template_suffix;
1676 return remove (template_path.c_str());
1680 Session::refresh_disk_space ()
1683 struct statfs statfsbuf;
1684 vector<space_and_path>::iterator i;
1685 Glib::Mutex::Lock lm (space_lock);
1688 /* get freespace on every FS that is part of the session path */
1690 _total_free_4k_blocks = 0;
1692 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1693 statfs ((*i).path.c_str(), &statfsbuf);
1695 scale = statfsbuf.f_bsize/4096.0;
1697 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1698 _total_free_4k_blocks += (*i).blocks;
1704 Session::ensure_sound_dir (string path, string& result)
1709 /* Ensure that the parent directory exists */
1711 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1712 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1716 /* Ensure that the sounds directory exists */
1720 result += sound_dir_name;
1722 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1723 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1729 dead += dead_sound_dir_name;
1731 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1732 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1738 peak += peak_dir_name;
1740 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1741 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1745 /* callers expect this to be terminated ... */
1752 Session::discover_best_sound_dir (bool destructive)
1754 vector<space_and_path>::iterator i;
1757 /* handle common case without system calls */
1759 if (session_dirs.size() == 1) {
1763 /* OK, here's the algorithm we're following here:
1765 We want to select which directory to use for
1766 the next file source to be created. Ideally,
1767 we'd like to use a round-robin process so as to
1768 get maximum performance benefits from splitting
1769 the files across multiple disks.
1771 However, in situations without much diskspace, an
1772 RR approach may end up filling up a filesystem
1773 with new files while others still have space.
1774 Its therefore important to pay some attention to
1775 the freespace in the filesystem holding each
1776 directory as well. However, if we did that by
1777 itself, we'd keep creating new files in the file
1778 system with the most space until it was as full
1779 as all others, thus negating any performance
1780 benefits of this RAID-1 like approach.
1782 So, we use a user-configurable space threshold. If
1783 there are at least 2 filesystems with more than this
1784 much space available, we use RR selection between them.
1785 If not, then we pick the filesystem with the most space.
1787 This gets a good balance between the two
1791 refresh_disk_space ();
1793 int free_enough = 0;
1795 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1796 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1801 if (free_enough >= 2) {
1803 bool found_it = false;
1805 /* use RR selection process, ensuring that the one
1809 i = last_rr_session_dir;
1812 if (++i == session_dirs.end()) {
1813 i = session_dirs.begin();
1816 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1817 if (ensure_sound_dir ((*i).path, result) == 0) {
1818 last_rr_session_dir = i;
1824 } while (i != last_rr_session_dir);
1827 result = sound_dir();
1832 /* pick FS with the most freespace (and that
1833 seems to actually work ...)
1836 vector<space_and_path> sorted;
1837 space_and_path_ascending_cmp cmp;
1839 sorted = session_dirs;
1840 sort (sorted.begin(), sorted.end(), cmp);
1842 for (i = sorted.begin(); i != sorted.end(); ++i) {
1843 if (ensure_sound_dir ((*i).path, result) == 0) {
1844 last_rr_session_dir = i;
1849 /* if the above fails, fall back to the most simplistic solution */
1851 if (i == sorted.end()) {
1860 Session::load_playlists (const XMLNode& node)
1863 XMLNodeConstIterator niter;
1864 boost::shared_ptr<Playlist> playlist;
1866 nlist = node.children();
1870 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1872 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1873 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1881 Session::load_unused_playlists (const XMLNode& node)
1884 XMLNodeConstIterator niter;
1885 boost::shared_ptr<Playlist> playlist;
1887 nlist = node.children();
1891 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1893 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1894 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1898 // now manually untrack it
1900 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1906 boost::shared_ptr<Playlist>
1907 Session::XMLPlaylistFactory (const XMLNode& node)
1910 return PlaylistFactory::create (*this, node);
1913 catch (failed_constructor& err) {
1914 return boost::shared_ptr<Playlist>();
1919 Session::load_named_selections (const XMLNode& node)
1922 XMLNodeConstIterator niter;
1925 nlist = node.children();
1929 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1931 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1932 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1940 Session::XMLNamedSelectionFactory (const XMLNode& node)
1943 return new NamedSelection (*this, node);
1946 catch (failed_constructor& err) {
1952 Session::dead_sound_dir () const
1955 res += dead_sound_dir_name;
1961 Session::old_sound_dir (bool with_path) const
1969 res += old_sound_dir_name;
1975 Session::sound_dir (bool with_path) const
1986 res += interchange_dir_name;
1988 res += legalize_for_path (_name);
1990 res += sound_dir_name;
1998 /* if this already exists, don't check for the old session sound directory */
2000 if (Glib::file_test (full, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2004 /* possibly support old session structure */
2007 string old_withpath;
2009 old_nopath += old_sound_dir_name;
2012 old_withpath = _path;
2013 old_withpath += old_sound_dir_name;
2015 if (Glib::file_test (old_withpath.c_str(), Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2017 return old_withpath;
2022 /* ok, old "sounds" directory isn't there, return the new path */
2028 Session::peak_dir () const
2031 res += peak_dir_name;
2037 Session::automation_dir () const
2040 res += "automation/";
2045 Session::template_dir ()
2047 string path = get_user_ardour_path();
2048 path += "templates/";
2054 Session::export_dir () const
2057 res += export_dir_name;
2063 Session::suffixed_search_path (string suffix, bool data)
2067 path += get_user_ardour_path();
2068 if (path[path.length()-1] != ':') {
2073 path += get_system_data_path();
2075 path += get_system_module_path();
2078 vector<string> split_path;
2080 split (path, split_path, ':');
2083 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2088 if (distance (i, split_path.end()) != 1) {
2097 Session::template_path ()
2099 return suffixed_search_path (X_("templates"), true);
2103 Session::control_protocol_path ()
2105 return suffixed_search_path (X_("surfaces"), false);
2109 Session::load_bundles (const XMLNode& node)
2111 XMLNodeList nlist = node.children();
2112 XMLNodeConstIterator niter;
2116 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2117 if ((*niter)->name() == "InputConnection") {
2118 add_bundle (new ARDOUR::InputBundle (**niter));
2119 } else if ((*niter)->name() == "OutputConnection") {
2120 add_bundle (new ARDOUR::OutputBundle (**niter));
2122 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2131 Session::load_edit_groups (const XMLNode& node)
2133 return load_route_groups (node, true);
2137 Session::load_mix_groups (const XMLNode& node)
2139 return load_route_groups (node, false);
2143 Session::load_route_groups (const XMLNode& node, bool edit)
2145 XMLNodeList nlist = node.children();
2146 XMLNodeConstIterator niter;
2151 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2152 if ((*niter)->name() == "RouteGroup") {
2154 rg = add_edit_group ("");
2155 rg->set_state (**niter);
2157 rg = add_mix_group ("");
2158 rg->set_state (**niter);
2167 state_file_filter (const string &str, void *arg)
2169 return (str.length() > strlen(statefile_suffix) &&
2170 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2174 bool operator()(const string* a, const string* b) {
2180 remove_end(string* state)
2182 string statename(*state);
2184 string::size_type start,end;
2185 if ((start = statename.find_last_of ('/')) != string::npos) {
2186 statename = statename.substr (start+1);
2189 if ((end = statename.rfind(".ardour")) == string::npos) {
2190 end = statename.length();
2193 return new string(statename.substr (0, end));
2197 Session::possible_states (string path)
2199 PathScanner scanner;
2200 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2202 transform(states->begin(), states->end(), states->begin(), remove_end);
2205 sort (states->begin(), states->end(), cmp);
2211 Session::possible_states () const
2213 return possible_states(_path);
2217 Session::auto_save()
2219 save_state (_current_snapshot_name);
2223 Session::add_edit_group (string name)
2225 RouteGroup* rg = new RouteGroup (*this, name);
2226 edit_groups.push_back (rg);
2227 edit_group_added (rg); /* EMIT SIGNAL */
2233 Session::add_mix_group (string name)
2235 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2236 mix_groups.push_back (rg);
2237 mix_group_added (rg); /* EMIT SIGNAL */
2243 Session::remove_edit_group (RouteGroup& rg)
2245 list<RouteGroup*>::iterator i;
2247 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2248 (*i)->apply (&Route::drop_edit_group, this);
2249 edit_groups.erase (i);
2250 edit_group_removed (); /* EMIT SIGNAL */
2257 Session::remove_mix_group (RouteGroup& rg)
2259 list<RouteGroup*>::iterator i;
2261 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2262 (*i)->apply (&Route::drop_mix_group, this);
2263 mix_groups.erase (i);
2264 mix_group_removed (); /* EMIT SIGNAL */
2271 Session::mix_group_by_name (string name)
2273 list<RouteGroup *>::iterator i;
2275 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2276 if ((*i)->name() == name) {
2284 Session::edit_group_by_name (string name)
2286 list<RouteGroup *>::iterator i;
2288 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2289 if ((*i)->name() == name) {
2297 Session::begin_reversible_command (string name)
2299 current_trans = new UndoTransaction;
2300 current_trans->set_name (name);
2304 Session::commit_reversible_command (Command *cmd)
2309 current_trans->add_command (cmd);
2312 gettimeofday (&now, 0);
2313 current_trans->set_timestamp (now);
2315 _history.add (current_trans);
2318 Session::GlobalRouteBooleanState
2319 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2321 GlobalRouteBooleanState s;
2322 boost::shared_ptr<RouteList> r = routes.reader ();
2324 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2325 if (!(*i)->hidden()) {
2326 RouteBooleanState v;
2329 Route* r = (*i).get();
2330 v.second = (r->*method)();
2339 Session::GlobalRouteMeterState
2340 Session::get_global_route_metering ()
2342 GlobalRouteMeterState s;
2343 boost::shared_ptr<RouteList> r = routes.reader ();
2345 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2346 if (!(*i)->hidden()) {
2350 v.second = (*i)->meter_point();
2360 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2362 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2364 boost::shared_ptr<Route> r = (i->first.lock());
2367 r->set_meter_point (i->second, arg);
2373 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2375 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2377 boost::shared_ptr<Route> r = (i->first.lock());
2380 Route* rp = r.get();
2381 (rp->*method) (i->second, arg);
2387 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2389 set_global_route_boolean (s, &Route::set_mute, src);
2393 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2395 set_global_route_boolean (s, &Route::set_solo, src);
2399 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2401 set_global_route_boolean (s, &Route::set_record_enable, src);
2406 Session::global_mute_memento (void* src)
2408 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2412 Session::global_metering_memento (void* src)
2414 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2418 Session::global_solo_memento (void* src)
2420 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2424 Session::global_record_enable_memento (void* src)
2426 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2431 template_filter (const string &str, void *arg)
2433 return (str.length() > strlen(template_suffix) &&
2434 str.find (template_suffix) == (str.length() - strlen (template_suffix)));
2438 Session::get_template_list (list<string> &template_names)
2440 vector<string *> *templates;
2441 PathScanner scanner;
2444 path = template_path ();
2446 templates = scanner (path, template_filter, 0, false, true);
2448 vector<string*>::iterator i;
2449 for (i = templates->begin(); i != templates->end(); ++i) {
2450 string fullpath = *(*i);
2453 start = fullpath.find_last_of ('/') + 1;
2454 if ((end = fullpath.find_last_of ('.')) <0) {
2455 end = fullpath.length();
2458 template_names.push_back(fullpath.substr(start, (end-start)));
2463 Session::read_favorite_dirs (FavoriteDirs & favs)
2465 string path = get_user_ardour_path();
2466 path += "/favorite_dirs";
2468 ifstream fav (path.c_str());
2473 if (errno != ENOENT) {
2474 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2485 getline(fav, newfav);
2491 favs.push_back (newfav);
2498 Session::write_favorite_dirs (FavoriteDirs & favs)
2500 string path = get_user_ardour_path();
2501 path += "/favorite_dirs";
2503 ofstream fav (path.c_str());
2509 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2510 fav << (*i) << endl;
2517 accept_all_non_peak_files (const string& path, void *arg)
2519 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2523 accept_all_state_files (const string& path, void *arg)
2525 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2529 Session::find_all_sources (string path, set<string>& result)
2534 if (!tree.read (path)) {
2538 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2543 XMLNodeConstIterator niter;
2545 nlist = node->children();
2549 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2553 if ((prop = (*niter)->property (X_("name"))) == 0) {
2557 if (prop->value()[0] == '/') {
2558 /* external file, ignore */
2562 string path = _path; /* /-terminated */
2563 path += sound_dir_name;
2565 path += prop->value();
2567 result.insert (path);
2574 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2576 PathScanner scanner;
2577 vector<string*>* state_files;
2579 string this_snapshot_path;
2585 if (ripped[ripped.length()-1] == '/') {
2586 ripped = ripped.substr (0, ripped.length() - 1);
2589 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2591 if (state_files == 0) {
2596 this_snapshot_path = _path;
2597 this_snapshot_path += _current_snapshot_name;
2598 this_snapshot_path += statefile_suffix;
2600 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2602 if (exclude_this_snapshot && **i == this_snapshot_path) {
2606 if (find_all_sources (**i, result) < 0) {
2614 struct RegionCounter {
2615 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2616 AudioSourceList::iterator iter;
2617 boost::shared_ptr<Region> region;
2620 RegionCounter() : count (0) {}
2624 Session::cleanup_sources (Session::cleanup_report& rep)
2626 vector<boost::shared_ptr<Source> > dead_sources;
2627 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2628 PathScanner scanner;
2630 vector<space_and_path>::iterator i;
2631 vector<space_and_path>::iterator nexti;
2632 vector<string*>* soundfiles;
2633 vector<string> unused;
2634 set<string> all_sources;
2639 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2641 /* step 1: consider deleting all unused playlists */
2643 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2646 status = AskAboutPlaylistDeletion (*x);
2655 playlists_tbd.push_back (*x);
2659 /* leave it alone */
2664 /* now delete any that were marked for deletion */
2666 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2667 (*x)->drop_references ();
2670 playlists_tbd.clear ();
2672 /* step 2: find all un-used sources */
2677 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2679 SourceMap::iterator tmp;
2684 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2688 if (!i->second->used() && i->second->length() > 0) {
2689 dead_sources.push_back (i->second);
2690 i->second->GoingAway();
2696 /* build a list of all the possible sound directories for the session */
2698 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2703 sound_path += (*i).path;
2704 sound_path += sound_dir (false);
2706 if (nexti != session_dirs.end()) {
2713 /* now do the same thing for the files that ended up in the sounds dir(s)
2714 but are not referenced as sources in any snapshot.
2717 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2719 if (soundfiles == 0) {
2723 /* find all sources, but don't use this snapshot because the
2724 state file on disk still references sources we may have already
2728 find_all_sources_across_snapshots (all_sources, true);
2730 /* add our current source list
2733 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2734 boost::shared_ptr<AudioFileSource> fs;
2736 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2737 all_sources.insert (fs->path());
2741 char tmppath1[PATH_MAX+1];
2742 char tmppath2[PATH_MAX+1];
2744 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2749 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2751 realpath(spath.c_str(), tmppath1);
2752 realpath((*i).c_str(), tmppath2);
2754 if (strcmp(tmppath1, tmppath2) == 0) {
2761 unused.push_back (spath);
2765 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2767 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2768 struct stat statbuf;
2770 rep.paths.push_back (*x);
2771 if (stat ((*x).c_str(), &statbuf) == 0) {
2772 rep.space += statbuf.st_size;
2777 /* don't move the file across filesystems, just
2778 stick it in the `dead_sound_dir_name' directory
2779 on whichever filesystem it was already on.
2782 if ((*x).find ("/sounds/") != string::npos) {
2784 /* old school, go up 1 level */
2786 newpath = Glib::path_get_dirname (*x); // "sounds"
2787 newpath = Glib::path_get_dirname (newpath); // "session-name"
2791 /* new school, go up 4 levels */
2793 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2794 newpath = Glib::path_get_dirname (newpath); // "session-name"
2795 newpath = Glib::path_get_dirname (newpath); // "interchange"
2796 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2800 newpath += dead_sound_dir_name;
2802 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2803 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2808 newpath += Glib::path_get_basename ((*x));
2810 if (access (newpath.c_str(), F_OK) == 0) {
2812 /* the new path already exists, try versioning */
2814 char buf[PATH_MAX+1];
2818 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2821 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2822 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2826 if (version == 999) {
2827 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2831 newpath = newpath_v;
2836 /* it doesn't exist, or we can't read it or something */
2840 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2841 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2842 (*x), newpath, strerror (errno))
2847 /* see if there an easy to find peakfile for this file, and remove it.
2850 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2851 peakpath += ".peak";
2853 if (access (peakpath.c_str(), W_OK) == 0) {
2854 if (::unlink (peakpath.c_str()) != 0) {
2855 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2856 peakpath, _path, strerror (errno))
2858 /* try to back out */
2859 rename (newpath.c_str(), _path.c_str());
2867 /* dump the history list */
2871 /* save state so we don't end up a session file
2872 referring to non-existent sources.
2878 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2883 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2885 vector<space_and_path>::iterator i;
2886 string dead_sound_dir;
2887 struct dirent* dentry;
2888 struct stat statbuf;
2894 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2896 dead_sound_dir = (*i).path;
2897 dead_sound_dir += dead_sound_dir_name;
2899 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2903 while ((dentry = readdir (dead)) != 0) {
2905 /* avoid '.' and '..' */
2907 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2908 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2914 fullpath = dead_sound_dir;
2916 fullpath += dentry->d_name;
2918 if (stat (fullpath.c_str(), &statbuf)) {
2922 if (!S_ISREG (statbuf.st_mode)) {
2926 if (unlink (fullpath.c_str())) {
2927 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2928 fullpath, strerror (errno))
2932 rep.paths.push_back (dentry->d_name);
2933 rep.space += statbuf.st_size;
2944 Session::set_dirty ()
2946 bool was_dirty = dirty();
2948 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2951 DirtyChanged(); /* EMIT SIGNAL */
2957 Session::set_clean ()
2959 bool was_dirty = dirty();
2961 _state_of_the_state = Clean;
2964 DirtyChanged(); /* EMIT SIGNAL */
2969 Session::set_deletion_in_progress ()
2971 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2975 Session::add_controllable (Controllable* c)
2977 /* this adds a controllable to the list managed by the Session.
2978 this is a subset of those managed by the Controllable class
2979 itself, and represents the only ones whose state will be saved
2980 as part of the session.
2983 Glib::Mutex::Lock lm (controllables_lock);
2984 controllables.insert (c);
2988 Session::remove_controllable (Controllable* c)
2990 if (_state_of_the_state | Deletion) {
2994 Glib::Mutex::Lock lm (controllables_lock);
2996 Controllables::iterator x = controllables.find (c);
2998 if (x != controllables.end()) {
2999 controllables.erase (x);
3004 Session::controllable_by_id (const PBD::ID& id)
3006 Glib::Mutex::Lock lm (controllables_lock);
3008 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3009 if ((*i)->id() == id) {
3018 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3020 Stateful::add_instant_xml (node, dir);
3021 Config->add_instant_xml (node, get_user_ardour_path());
3026 Session::save_history (string snapshot_name)
3032 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3034 if (snapshot_name.empty()) {
3035 snapshot_name = _current_snapshot_name;
3038 xml_path = _path + snapshot_name + ".history";
3040 bak_path = xml_path + ".bak";
3042 if ((access (xml_path.c_str(), F_OK) == 0) &&
3043 (rename (xml_path.c_str(), bak_path.c_str())))
3045 error << _("could not backup old history file, current history not saved.") << endmsg;
3049 if (!tree.write (xml_path))
3051 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3053 /* don't leave a corrupt file lying around if it is
3057 if (unlink (xml_path.c_str())) {
3058 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
3060 if (rename (bak_path.c_str(), xml_path.c_str()))
3062 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
3073 Session::restore_history (string snapshot_name)
3078 if (snapshot_name.empty()) {
3079 snapshot_name = _current_snapshot_name;
3083 xmlpath = _path + snapshot_name + ".history";
3084 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
3086 if (access (xmlpath.c_str(), F_OK)) {
3087 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
3091 if (!tree.read (xmlpath)) {
3092 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
3096 /* replace history */
3099 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3102 UndoTransaction* ut = new UndoTransaction ();
3105 ut->set_name(t->property("name")->value());
3106 stringstream ss(t->property("tv_sec")->value());
3108 ss.str(t->property("tv_usec")->value());
3110 ut->set_timestamp(tv);
3112 for (XMLNodeConstIterator child_it = t->children().begin();
3113 child_it != t->children().end();
3116 XMLNode *n = *child_it;
3119 if (n->name() == "MementoCommand" ||
3120 n->name() == "MementoUndoCommand" ||
3121 n->name() == "MementoRedoCommand") {
3123 if ((c = memento_command_factory(n))) {
3127 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3129 if ((c = global_state_command_factory (*n))) {
3130 ut->add_command (c);
3135 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3146 Session::config_changed (const char* parameter_name)
3148 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3150 if (PARAM_IS ("seamless-loop")) {
3152 } else if (PARAM_IS ("rf-speed")) {
3154 } else if (PARAM_IS ("auto-loop")) {
3156 } else if (PARAM_IS ("auto-input")) {
3158 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3159 /* auto-input only makes a difference if we're rolling */
3161 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3163 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3164 if ((*i)->record_enabled ()) {
3165 (*i)->monitor_input (!Config->get_auto_input());
3170 } else if (PARAM_IS ("punch-in")) {
3174 if ((location = _locations.auto_punch_location()) != 0) {
3176 if (Config->get_punch_in ()) {
3177 replace_event (Event::PunchIn, location->start());
3179 remove_event (location->start(), Event::PunchIn);
3183 } else if (PARAM_IS ("punch-out")) {
3187 if ((location = _locations.auto_punch_location()) != 0) {
3189 if (Config->get_punch_out()) {
3190 replace_event (Event::PunchOut, location->end());
3192 clear_events (Event::PunchOut);
3196 } else if (PARAM_IS ("edit-mode")) {
3198 Glib::Mutex::Lock lm (playlist_lock);
3200 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3201 (*i)->set_edit_mode (Config->get_edit_mode ());
3204 } else if (PARAM_IS ("use-video-sync")) {
3206 waiting_for_sync_offset = Config->get_use_video_sync();
3208 } else if (PARAM_IS ("mmc-control")) {
3210 //poke_midi_thread ();
3212 } else if (PARAM_IS ("mmc-device-id")) {
3215 mmc->set_device_id (Config->get_mmc_device_id());
3218 } else if (PARAM_IS ("midi-control")) {
3220 //poke_midi_thread ();
3222 } else if (PARAM_IS ("raid-path")) {
3224 setup_raid_path (Config->get_raid_path());
3226 } else if (PARAM_IS ("smpte-format")) {
3230 } else if (PARAM_IS ("video-pullup")) {
3234 } else if (PARAM_IS ("seamless-loop")) {
3236 if (play_loop && transport_rolling()) {
3237 // to reset diskstreams etc
3238 request_play_loop (true);
3241 } else if (PARAM_IS ("rf-speed")) {
3243 cumulative_rf_motion = 0;
3246 } else if (PARAM_IS ("click-sound")) {
3248 setup_click_sounds (1);
3250 } else if (PARAM_IS ("click-emphasis-sound")) {
3252 setup_click_sounds (-1);
3254 } else if (PARAM_IS ("clicking")) {
3256 if (Config->get_clicking()) {
3257 if (_click_io && click_data) { // don't require emphasis data
3264 } else if (PARAM_IS ("send-mtc")) {
3266 /* only set the internal flag if we have
3270 if (_mtc_port != 0) {
3271 session_send_mtc = Config->get_send_mtc();
3272 if (session_send_mtc) {
3273 /* mark us ready to send */
3274 next_quarter_frame_to_send = 0;
3277 session_send_mtc = false;
3280 } else if (PARAM_IS ("send-mmc")) {
3282 /* only set the internal flag if we have
3286 if (_mmc_port != 0) {
3287 session_send_mmc = Config->get_send_mmc();
3290 session_send_mmc = false;
3293 } else if (PARAM_IS ("midi-feedback")) {
3295 /* only set the internal flag if we have
3299 if (_mtc_port != 0) {
3300 session_midi_feedback = Config->get_midi_feedback();
3303 } else if (PARAM_IS ("jack-time-master")) {
3305 engine().reset_timebase ();
3307 } else if (PARAM_IS ("native-file-header-format")) {
3309 if (!first_file_header_format_reset) {
3310 reset_native_file_format ();
3313 first_file_header_format_reset = false;
3315 } else if (PARAM_IS ("native-file-data-format")) {
3317 if (!first_file_data_format_reset) {
3318 reset_native_file_format ();
3321 first_file_data_format_reset = false;
3323 } else if (PARAM_IS ("slave-source")) {
3324 set_slave_source (Config->get_slave_source());
3325 } else if (PARAM_IS ("remote-model")) {
3326 set_remote_control_ids ();
3327 } else if (PARAM_IS ("denormal-model")) {