2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #define __STDC_FORMAT_MACROS 1
28 #include <sigc++/bind.h>
30 #include <cstdio> /* snprintf(3) ... grrr */
45 #include <sys/param.h>
46 #include <sys/mount.h>
51 #include <midi++/mmc.h>
52 #include <midi++/port.h>
53 #include <pbd/error.h>
55 #include <glibmm/thread.h>
56 #include <pbd/pathscanner.h>
57 #include <pbd/pthread_utils.h>
58 #include <pbd/search_path.h>
59 #include <pbd/strsplit.h>
60 #include <pbd/stacktrace.h>
61 #include <pbd/copyfile.h>
63 #include <ardour/audioengine.h>
64 #include <ardour/configuration.h>
65 #include <ardour/session.h>
66 #include <ardour/session_directory.h>
67 #include <ardour/session_utils.h>
68 #include <ardour/buffer.h>
69 #include <ardour/audio_diskstream.h>
70 #include <ardour/midi_diskstream.h>
71 #include <ardour/utils.h>
72 #include <ardour/audioplaylist.h>
73 #include <ardour/midi_playlist.h>
74 #include <ardour/smf_source.h>
75 #include <ardour/audiofilesource.h>
76 #include <ardour/silentfilesource.h>
77 #include <ardour/sndfilesource.h>
78 #include <ardour/midi_source.h>
79 #include <ardour/sndfile_helpers.h>
80 #include <ardour/auditioner.h>
81 #include <ardour/export.h>
82 #include <ardour/redirect.h>
83 #include <ardour/send.h>
84 #include <ardour/insert.h>
85 #include <ardour/bundle.h>
86 #include <ardour/slave.h>
87 #include <ardour/tempo.h>
88 #include <ardour/audio_track.h>
89 #include <ardour/midi_track.h>
90 #include <ardour/cycle_timer.h>
91 #include <ardour/utils.h>
92 #include <ardour/named_selection.h>
93 #include <ardour/version.h>
94 #include <ardour/location.h>
95 #include <ardour/audioregion.h>
96 #include <ardour/midi_region.h>
97 #include <ardour/crossfade.h>
98 #include <ardour/control_protocol_manager.h>
99 #include <ardour/region_factory.h>
100 #include <ardour/source_factory.h>
101 #include <ardour/playlist_factory.h>
102 #include <ardour/filename_extensions.h>
103 #include <ardour/directory_names.h>
104 #include <control_protocol/control_protocol.h>
110 using namespace ARDOUR;
114 Session::first_stage_init (string fullpath, string snapshot_name)
116 if (fullpath.length() == 0) {
118 throw failed_constructor();
121 char buf[PATH_MAX+1];
122 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
123 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
125 throw failed_constructor();
130 if (_path[_path.length()-1] != '/') {
134 /* these two are just provisional settings. set_state()
135 will likely override them.
138 _name = _current_snapshot_name = snapshot_name;
140 _current_frame_rate = _engine.frame_rate ();
141 _tempo_map = new TempoMap (_current_frame_rate);
142 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
144 g_atomic_int_set (&processing_prohibited, 0);
146 _transport_speed = 0;
147 _last_transport_speed = 0;
148 auto_play_legal = false;
149 transport_sub_state = 0;
150 _transport_frame = 0;
152 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
153 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
154 _end_location_is_free = true;
155 g_atomic_int_set (&_record_status, Disabled);
156 loop_changing = false;
158 _last_roll_location = 0;
159 _last_record_location = 0;
160 pending_locate_frame = 0;
161 pending_locate_roll = false;
162 pending_locate_flush = false;
163 dstream_buffer_size = 0;
165 state_was_pending = false;
167 outbound_mtc_smpte_frame = 0;
168 next_quarter_frame_to_send = -1;
169 current_block_size = 0;
170 solo_update_disabled = false;
171 currently_soloing = false;
172 _have_captured = false;
173 _worst_output_latency = 0;
174 _worst_input_latency = 0;
175 _worst_track_latency = 0;
176 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
178 butler_mixdown_buffer = 0;
179 butler_gain_buffer = 0;
181 session_send_mmc = false;
182 session_send_mtc = false;
183 post_transport_work = PostTransportWork (0);
184 g_atomic_int_set (&butler_should_do_transport_work, 0);
185 g_atomic_int_set (&butler_active, 0);
186 g_atomic_int_set (&_playback_load, 100);
187 g_atomic_int_set (&_capture_load, 100);
188 g_atomic_int_set (&_playback_load_min, 100);
189 g_atomic_int_set (&_capture_load_min, 100);
191 waiting_to_start = false;
193 _gain_automation_buffer = 0;
194 _pan_automation_buffer = 0;
196 pending_abort = false;
197 destructive_index = 0;
199 first_file_data_format_reset = true;
200 first_file_header_format_reset = true;
201 butler_thread = (pthread_t) 0;
202 //midi_thread = (pthread_t) 0;
204 AudioDiskstream::allocate_working_buffers();
206 /* default short fade = 15ms */
208 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
209 SndFileSource::setup_standard_crossfades (frame_rate());
211 last_mmc_step.tv_sec = 0;
212 last_mmc_step.tv_usec = 0;
215 /* click sounds are unset by default, which causes us to internal
216 waveforms for clicks.
220 click_emphasis_data = 0;
222 click_emphasis_length = 0;
225 process_function = &Session::process_with_events;
227 if (Config->get_use_video_sync()) {
228 waiting_for_sync_offset = true;
230 waiting_for_sync_offset = false;
233 _current_frame_rate = 48000;
234 _base_frame_rate = 48000;
238 _smpte_offset_negative = true;
239 last_smpte_valid = false;
243 last_rr_session_dir = session_dirs.begin();
244 refresh_disk_space ();
246 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
250 average_slave_delta = 1800;
251 have_first_delta_accumulator = false;
252 delta_accumulator_cnt = 0;
253 slave_state = Stopped;
255 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
257 /* These are all static "per-class" signals */
259 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
260 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
261 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
262 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
263 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
264 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
266 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
268 IO::MoreChannels.connect (mem_fun (*this, &Session::ensure_buffers));
270 /* stop IO objects from doing stuff until we're ready for them */
272 IO::disable_panners ();
273 IO::disable_ports ();
274 IO::disable_connecting ();
278 Session::second_stage_init (bool new_session)
280 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
283 if (load_state (_current_snapshot_name)) {
286 remove_empty_sounds ();
289 if (start_butler_thread()) {
293 /*if (start_midi_thread ()) {
297 // set_state() will call setup_raid_path(), but if it's a new session we need
298 // to call setup_raid_path() here.
300 if (set_state (*state_tree->root())) {
304 setup_raid_path(_path);
307 /* we can't save till after ::when_engine_running() is called,
308 because otherwise we save state with no connections made.
309 therefore, we reset _state_of_the_state because ::set_state()
310 will have cleared it.
312 we also have to include Loading so that any events that get
313 generated between here and the end of ::when_engine_running()
314 will be processed directly rather than queued.
317 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
319 // set_auto_input (true);
320 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
321 _locations.added.connect (mem_fun (this, &Session::locations_added));
322 setup_click_sounds (0);
323 setup_midi_control ();
325 /* Pay attention ... */
327 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
328 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
331 when_engine_running();
334 /* handle this one in a different way than all others, so that its clear what happened */
336 catch (AudioEngine::PortRegistrationFailure& err) {
337 error << _("Unable to create all required ports")
346 //send_full_time_code ();
347 _engine.transport_locate (0);
348 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
349 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
351 ControlProtocolManager::instance().set_session (*this);
354 _end_location_is_free = true;
356 _end_location_is_free = false;
363 Session::raid_path () const
365 SearchPath raid_search_path;
367 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
368 raid_search_path += sys::path((*i).path);
371 return raid_search_path.get_string ();
375 Session::setup_raid_path (string path)
384 session_dirs.clear ();
386 SearchPath search_path(path);
387 SearchPath sound_search_path;
388 SearchPath midi_search_path;
391 SearchPath::const_iterator i = search_path.begin();
392 i != search_path.end();
396 sp.path = (*i).to_string ();
397 sp.blocks = 0; // not needed
398 session_dirs.push_back (sp);
400 SessionDirectory sdir(sp.path);
402 sound_search_path += sdir.sound_path ();
403 midi_search_path += sdir.midi_path ();
406 // set the AudioFileSource and SMFSource search path
408 AudioFileSource::set_search_path (sound_search_path.get_string ());
409 SMFSource::set_search_path (midi_search_path.get_string ());
411 // reset the round-robin soundfile path thingie
413 last_rr_session_dir = session_dirs.begin();
417 Session::initialize_start_and_end_locations (nframes_t start, nframes_t end)
419 start_location->set_end (start);
420 _locations.add (start_location);
422 end_location->set_end (end);
423 _locations.add (end_location);
427 Session::create_session_file ()
429 _state_of_the_state = Clean;
431 if (save_state (_current_snapshot_name)) {
432 error << "Could not create new session file" << endmsg;
439 Session::create_session_file_from_template (const string& template_path)
441 string out_path = _path + _name + statefile_suffix;
443 if(!copy_file (template_path, out_path)) {
444 error << string_compose (_("Could not use session template %1 to create new session."), template_path)
452 Session::load_diskstreams (const XMLNode& node)
455 XMLNodeConstIterator citer;
457 clist = node.children();
459 for (citer = clist.begin(); citer != clist.end(); ++citer) {
462 /* diskstreams added automatically by DiskstreamCreated handler */
463 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
464 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
465 add_diskstream (dstream);
466 } else if ((*citer)->name() == "MidiDiskstream") {
467 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
468 add_diskstream (dstream);
470 error << _("Session: unknown diskstream type in XML") << endmsg;
474 catch (failed_constructor& err) {
475 error << _("Session: could not load diskstream via XML state") << endmsg;
484 Session::maybe_write_autosave()
486 if (dirty() && record_status() != Recording) {
487 save_state("", true);
492 Session::remove_pending_capture_state ()
497 xml_path += _current_snapshot_name;
498 xml_path += pending_suffix;
500 unlink (xml_path.c_str());
503 /** Rename a state file.
504 * @param snapshot_name Snapshot name.
507 Session::rename_state (string old_name, string new_name)
509 if (old_name == _current_snapshot_name || old_name == _name) {
510 /* refuse to rename the current snapshot or the "main" one */
514 const string old_xml_path = _path + old_name + statefile_suffix;
515 const string new_xml_path = _path + new_name + statefile_suffix;
517 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
518 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
522 /** Remove a state file.
523 * @param snapshot_name Snapshot name.
526 Session::remove_state (string snapshot_name)
528 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
529 /* refuse to remove the current snapshot or the "main" one */
533 const string xml_path = _path + snapshot_name + statefile_suffix;
535 /* make a backup copy of the state file */
536 const string bak_path = xml_path + ".bak";
537 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
538 copy_file (xml_path, bak_path);
542 unlink (xml_path.c_str());
546 Session::save_state (string snapshot_name, bool pending)
552 if (_state_of_the_state & CannotSave) {
556 if (!_engine.connected ()) {
557 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
562 tree.set_root (&get_state());
564 if (snapshot_name.empty()) {
565 snapshot_name = _current_snapshot_name;
570 /* proper save: use statefile_suffix (.ardour in English) */
572 xml_path += snapshot_name;
573 xml_path += statefile_suffix;
575 /* make a backup copy of the old file */
579 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
580 copy_file (xml_path, bak_path);
585 /* pending save: use pending_suffix (.pending in English) */
587 xml_path += snapshot_name;
588 xml_path += pending_suffix;
595 tmp_path += snapshot_name;
598 // cerr << "actually writing state to " << xml_path << endl;
600 if (!tree.write (tmp_path)) {
601 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
602 unlink (tmp_path.c_str());
607 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
608 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
609 unlink (tmp_path.c_str());
616 save_history (snapshot_name);
618 bool was_dirty = dirty();
620 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
623 DirtyChanged (); /* EMIT SIGNAL */
626 StateSaved (snapshot_name); /* EMIT SIGNAL */
633 Session::restore_state (string snapshot_name)
635 if (load_state (snapshot_name) == 0) {
636 set_state (*state_tree->root());
643 Session::load_state (string snapshot_name)
652 state_was_pending = false;
654 /* check for leftover pending state from a crashed capture attempt */
657 xmlpath += snapshot_name;
658 xmlpath += pending_suffix;
660 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
662 /* there is pending state from a crashed capture attempt */
664 if (AskAboutPendingState()) {
665 state_was_pending = true;
669 if (!state_was_pending) {
672 xmlpath += snapshot_name;
673 xmlpath += statefile_suffix;
676 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
677 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
681 state_tree = new XMLTree;
685 if (!state_tree->read (xmlpath)) {
686 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
692 XMLNode& root (*state_tree->root());
694 if (root.name() != X_("Session")) {
695 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
701 const XMLProperty* prop;
704 if ((prop = root.property ("version")) == 0) {
705 /* no version implies very old version of Ardour */
709 major_version = atoi (prop->value()); // grab just the first number before the period
710 if (major_version < 2) {
719 backup_path += snapshot_name;
721 backup_path += statefile_suffix;
723 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
724 xmlpath, backup_path)
727 copy_file (xmlpath, backup_path);
729 /* if it fails, don't worry. right? */
736 Session::load_options (const XMLNode& node)
740 LocaleGuard lg (X_("POSIX"));
742 Config->set_variables (node, ConfigVariableBase::Session);
744 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
745 if ((prop = child->property ("val")) != 0) {
746 _end_location_is_free = (prop->value() == "yes");
754 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
756 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
757 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
759 return owner & modified_by_session_or_user;
763 Session::get_options () const
766 LocaleGuard lg (X_("POSIX"));
768 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
770 child = option_root.add_child ("end-marker-is-free");
771 child->add_property ("val", _end_location_is_free ? "yes" : "no");
783 Session::get_template()
785 /* if we don't disable rec-enable, diskstreams
786 will believe they need to store their capture
787 sources in their state node.
790 disable_record (false);
796 Session::state(bool full_state)
798 XMLNode* node = new XMLNode("Session");
801 // store libardour version, just in case
803 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
804 libardour_major_version, libardour_minor_version, libardour_micro_version);
805 node->add_property("version", string(buf));
807 /* store configuration settings */
812 node->add_property ("name", _name);
814 if (session_dirs.size() > 1) {
818 vector<space_and_path>::iterator i = session_dirs.begin();
819 vector<space_and_path>::iterator next;
821 ++i; /* skip the first one */
825 while (i != session_dirs.end()) {
829 if (next != session_dirs.end()) {
839 child = node->add_child ("Path");
840 child->add_content (p);
844 /* save the ID counter */
846 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
847 node->add_property ("id-counter", buf);
849 /* various options */
851 node->add_child_nocopy (get_options());
853 child = node->add_child ("Sources");
856 Glib::Mutex::Lock sl (source_lock);
858 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
860 /* Don't save information about AudioFileSources that are empty */
862 boost::shared_ptr<AudioFileSource> fs;
864 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
866 /* Don't save sources that are empty, unless they're destructive (which are OK
867 if they are empty, because we will re-use them every time.)
870 if (!fs->destructive()) {
871 if (fs->length() == 0) {
877 child->add_child_nocopy (siter->second->get_state());
881 child = node->add_child ("Regions");
884 Glib::Mutex::Lock rl (region_lock);
886 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
888 /* only store regions not attached to playlists */
890 if (i->second->playlist() == 0) {
891 child->add_child_nocopy (i->second->state (true));
896 child = node->add_child ("DiskStreams");
899 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
900 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
901 if (!(*i)->hidden()) {
902 child->add_child_nocopy ((*i)->get_state());
908 node->add_child_nocopy (_locations.get_state());
910 // for a template, just create a new Locations, populate it
911 // with the default start and end, and get the state for that.
913 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
914 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
917 end->set_end(compute_initial_length());
919 node->add_child_nocopy (loc.get_state());
922 child = node->add_child ("Connections");
924 Glib::Mutex::Lock lm (bundle_lock);
925 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
926 if (!(*i)->dynamic()) {
927 child->add_child_nocopy ((*i)->get_state());
932 child = node->add_child ("Routes");
934 boost::shared_ptr<RouteList> r = routes.reader ();
936 RoutePublicOrderSorter cmp;
937 RouteList public_order (*r);
938 public_order.sort (cmp);
940 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
941 if (!(*i)->hidden()) {
943 child->add_child_nocopy ((*i)->get_state());
945 child->add_child_nocopy ((*i)->get_template());
952 child = node->add_child ("EditGroups");
953 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
954 child->add_child_nocopy ((*i)->get_state());
957 child = node->add_child ("MixGroups");
958 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
959 child->add_child_nocopy ((*i)->get_state());
962 child = node->add_child ("Playlists");
963 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
964 if (!(*i)->hidden()) {
965 if (!(*i)->empty()) {
967 child->add_child_nocopy ((*i)->get_state());
969 child->add_child_nocopy ((*i)->get_template());
975 child = node->add_child ("UnusedPlaylists");
976 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
977 if (!(*i)->hidden()) {
978 if (!(*i)->empty()) {
980 child->add_child_nocopy ((*i)->get_state());
982 child->add_child_nocopy ((*i)->get_template());
990 child = node->add_child ("Click");
991 child->add_child_nocopy (_click_io->state (full_state));
995 child = node->add_child ("NamedSelections");
996 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
998 child->add_child_nocopy ((*i)->get_state());
1003 node->add_child_nocopy (_tempo_map->get_state());
1005 node->add_child_nocopy (get_control_protocol_state());
1008 node->add_child_copy (*_extra_xml);
1015 Session::get_control_protocol_state ()
1017 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1018 return cpm.get_state();
1022 Session::set_state (const XMLNode& node)
1026 const XMLProperty* prop;
1029 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1031 if (node.name() != X_("Session")){
1032 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1036 if ((prop = node.property ("name")) != 0) {
1037 _name = prop->value ();
1040 setup_raid_path(_path);
1042 if ((prop = node.property (X_("id-counter"))) != 0) {
1044 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1045 ID::init_counter (x);
1047 /* old sessions used a timebased counter, so fake
1048 the startup ID counter based on a standard
1053 ID::init_counter (now);
1057 IO::disable_ports ();
1058 IO::disable_connecting ();
1060 /* Object loading order:
1078 if (use_config_midi_ports ()) {
1081 if ((child = find_named_node (node, "extra")) != 0) {
1082 _extra_xml = new XMLNode (*child);
1085 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1086 load_options (*child);
1087 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1088 load_options (*child);
1090 error << _("Session: XML state has no options section") << endmsg;
1093 if ((child = find_named_node (node, "Locations")) == 0) {
1094 error << _("Session: XML state has no locations section") << endmsg;
1096 } else if (_locations.set_state (*child)) {
1102 if ((location = _locations.auto_loop_location()) != 0) {
1103 set_auto_loop_location (location);
1106 if ((location = _locations.auto_punch_location()) != 0) {
1107 set_auto_punch_location (location);
1110 if ((location = _locations.end_location()) == 0) {
1111 _locations.add (end_location);
1113 delete end_location;
1114 end_location = location;
1117 if ((location = _locations.start_location()) == 0) {
1118 _locations.add (start_location);
1120 delete start_location;
1121 start_location = location;
1124 AudioFileSource::set_header_position_offset (start_location->start());
1126 if ((child = find_named_node (node, "Sources")) == 0) {
1127 error << _("Session: XML state has no sources section") << endmsg;
1129 } else if (load_sources (*child)) {
1133 if ((child = find_named_node (node, "Regions")) == 0) {
1134 error << _("Session: XML state has no Regions section") << endmsg;
1136 } else if (load_regions (*child)) {
1140 if ((child = find_named_node (node, "Playlists")) == 0) {
1141 error << _("Session: XML state has no playlists section") << endmsg;
1143 } else if (load_playlists (*child)) {
1147 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1149 } else if (load_unused_playlists (*child)) {
1153 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1154 if (load_named_selections (*child)) {
1159 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1160 error << _("Session: XML state has no diskstreams section") << endmsg;
1162 } else if (load_diskstreams (*child)) {
1166 if ((child = find_named_node (node, "Connections")) == 0) {
1167 error << _("Session: XML state has no connections section") << endmsg;
1169 } else if (load_bundles (*child)) {
1173 if ((child = find_named_node (node, "EditGroups")) == 0) {
1174 error << _("Session: XML state has no edit groups section") << endmsg;
1176 } else if (load_edit_groups (*child)) {
1180 if ((child = find_named_node (node, "MixGroups")) == 0) {
1181 error << _("Session: XML state has no mix groups section") << endmsg;
1183 } else if (load_mix_groups (*child)) {
1187 if ((child = find_named_node (node, "TempoMap")) == 0) {
1188 error << _("Session: XML state has no Tempo Map section") << endmsg;
1190 } else if (_tempo_map->set_state (*child)) {
1194 if ((child = find_named_node (node, "Routes")) == 0) {
1195 error << _("Session: XML state has no routes section") << endmsg;
1197 } else if (load_routes (*child)) {
1201 if ((child = find_named_node (node, "Click")) == 0) {
1202 warning << _("Session: XML state has no click section") << endmsg;
1203 } else if (_click_io) {
1204 _click_io->set_state (*child);
1207 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1208 ControlProtocolManager::instance().set_protocol_states (*child);
1211 /* here beginneth the second phase ... */
1213 StateReady (); /* EMIT SIGNAL */
1215 _state_of_the_state = Clean;
1217 if (state_was_pending) {
1218 save_state (_current_snapshot_name);
1219 remove_pending_capture_state ();
1220 state_was_pending = false;
1230 Session::load_routes (const XMLNode& node)
1233 XMLNodeConstIterator niter;
1234 RouteList new_routes;
1236 nlist = node.children();
1240 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1242 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1245 error << _("Session: cannot create Route from XML description.") << endmsg;
1249 new_routes.push_back (route);
1252 add_routes (new_routes);
1257 boost::shared_ptr<Route>
1258 Session::XMLRouteFactory (const XMLNode& node)
1260 if (node.name() != "Route") {
1261 return boost::shared_ptr<Route> ((Route*) 0);
1264 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1266 DataType type = DataType::AUDIO;
1267 const XMLProperty* prop = node.property("default-type");
1269 type = DataType(prop->value());
1271 assert(type != DataType::NIL);
1273 if (has_diskstream) {
1274 if (type == DataType::AUDIO) {
1275 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1278 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1282 boost::shared_ptr<Route> ret (new Route (*this, node));
1288 Session::load_regions (const XMLNode& node)
1291 XMLNodeConstIterator niter;
1292 boost::shared_ptr<Region> region;
1294 nlist = node.children();
1298 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1299 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1300 error << _("Session: cannot create Region from XML description.") << endmsg;
1307 boost::shared_ptr<Region>
1308 Session::XMLRegionFactory (const XMLNode& node, bool full)
1310 const XMLProperty* type = node.property("type");
1314 if ( !type || type->value() == "audio" ) {
1316 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1318 } else if (type->value() == "midi") {
1320 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1324 } catch (failed_constructor& err) {
1325 return boost::shared_ptr<Region> ();
1328 return boost::shared_ptr<Region> ();
1331 boost::shared_ptr<AudioRegion>
1332 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1334 const XMLProperty* prop;
1335 boost::shared_ptr<Source> source;
1336 boost::shared_ptr<AudioSource> as;
1338 uint32_t nchans = 1;
1341 if (node.name() != X_("Region")) {
1342 return boost::shared_ptr<AudioRegion>();
1345 if ((prop = node.property (X_("channels"))) != 0) {
1346 nchans = atoi (prop->value().c_str());
1349 if ((prop = node.property ("name")) == 0) {
1350 cerr << "no name for this region\n";
1354 if ((prop = node.property (X_("source-0"))) == 0) {
1355 if ((prop = node.property ("source")) == 0) {
1356 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1357 return boost::shared_ptr<AudioRegion>();
1361 PBD::ID s_id (prop->value());
1363 if ((source = source_by_id (s_id)) == 0) {
1364 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1365 return boost::shared_ptr<AudioRegion>();
1368 as = boost::dynamic_pointer_cast<AudioSource>(source);
1370 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1371 return boost::shared_ptr<AudioRegion>();
1374 sources.push_back (as);
1376 /* pickup other channels */
1378 for (uint32_t n=1; n < nchans; ++n) {
1379 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1380 if ((prop = node.property (buf)) != 0) {
1382 PBD::ID id2 (prop->value());
1384 if ((source = source_by_id (id2)) == 0) {
1385 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1386 return boost::shared_ptr<AudioRegion>();
1389 as = boost::dynamic_pointer_cast<AudioSource>(source);
1391 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1392 return boost::shared_ptr<AudioRegion>();
1394 sources.push_back (as);
1399 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1401 /* a final detail: this is the one and only place that we know how long missing files are */
1403 if (region->whole_file()) {
1404 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1405 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1407 sfp->set_length (region->length());
1416 catch (failed_constructor& err) {
1417 return boost::shared_ptr<AudioRegion>();
1421 boost::shared_ptr<MidiRegion>
1422 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1424 const XMLProperty* prop;
1425 boost::shared_ptr<Source> source;
1426 boost::shared_ptr<MidiSource> ms;
1428 uint32_t nchans = 1;
1430 if (node.name() != X_("Region")) {
1431 return boost::shared_ptr<MidiRegion>();
1434 if ((prop = node.property (X_("channels"))) != 0) {
1435 nchans = atoi (prop->value().c_str());
1438 if ((prop = node.property ("name")) == 0) {
1439 cerr << "no name for this region\n";
1443 // Multiple midi channels? that's just crazy talk
1444 assert(nchans == 1);
1446 if ((prop = node.property (X_("source-0"))) == 0) {
1447 if ((prop = node.property ("source")) == 0) {
1448 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1449 return boost::shared_ptr<MidiRegion>();
1453 PBD::ID s_id (prop->value());
1455 if ((source = source_by_id (s_id)) == 0) {
1456 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1457 return boost::shared_ptr<MidiRegion>();
1460 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1462 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1463 return boost::shared_ptr<MidiRegion>();
1466 sources.push_back (ms);
1469 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1470 /* a final detail: this is the one and only place that we know how long missing files are */
1472 if (region->whole_file()) {
1473 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1474 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1476 sfp->set_length (region->length());
1484 catch (failed_constructor& err) {
1485 return boost::shared_ptr<MidiRegion>();
1490 Session::get_sources_as_xml ()
1493 XMLNode* node = new XMLNode (X_("Sources"));
1494 Glib::Mutex::Lock lm (source_lock);
1496 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1497 node->add_child_nocopy (i->second->get_state());
1504 Session::path_from_region_name (string name, string identifier)
1506 char buf[PATH_MAX+1];
1508 SessionDirectory sdir(get_best_session_directory_for_new_source());
1509 string sound_dir = sdir.sound_path().to_string();
1511 for (n = 0; n < 999999; ++n) {
1512 if (identifier.length()) {
1513 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", sound_dir.c_str(), name.c_str(),
1514 identifier.c_str(), n);
1516 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", sound_dir.c_str(), name.c_str(), n);
1519 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1524 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1533 Session::load_sources (const XMLNode& node)
1536 XMLNodeConstIterator niter;
1537 boost::shared_ptr<Source> source;
1539 nlist = node.children();
1543 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1546 if ((source = XMLSourceFactory (**niter)) == 0) {
1547 error << _("Session: cannot create Source from XML description.") << endmsg;
1551 catch (non_existent_source& err) {
1552 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1553 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1560 boost::shared_ptr<Source>
1561 Session::XMLSourceFactory (const XMLNode& node)
1563 if (node.name() != "Source") {
1564 return boost::shared_ptr<Source>();
1568 return SourceFactory::create (*this, node);
1571 catch (failed_constructor& err) {
1572 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1573 return boost::shared_ptr<Source>();
1578 Session::save_template (string template_name)
1581 string xml_path, bak_path, template_path;
1583 if (_state_of_the_state & CannotSave) {
1588 string dir = template_dir();
1590 if ((dp = opendir (dir.c_str()))) {
1593 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1594 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1599 tree.set_root (&get_template());
1602 xml_path += template_name;
1603 xml_path += template_suffix;
1605 ifstream in(xml_path.c_str());
1608 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1614 if (!tree.write (xml_path)) {
1615 error << _("mix template not saved") << endmsg;
1623 Session::rename_template (string old_name, string new_name)
1625 string old_path = template_dir() + old_name + template_suffix;
1626 string new_path = template_dir() + new_name + template_suffix;
1628 return rename (old_path.c_str(), new_path.c_str());
1632 Session::delete_template (string name)
1634 string template_path = template_dir();
1635 template_path += name;
1636 template_path += template_suffix;
1638 return remove (template_path.c_str());
1642 Session::refresh_disk_space ()
1645 struct statfs statfsbuf;
1646 vector<space_and_path>::iterator i;
1647 Glib::Mutex::Lock lm (space_lock);
1650 /* get freespace on every FS that is part of the session path */
1652 _total_free_4k_blocks = 0;
1654 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1655 statfs ((*i).path.c_str(), &statfsbuf);
1657 scale = statfsbuf.f_bsize/4096.0;
1659 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1660 _total_free_4k_blocks += (*i).blocks;
1666 Session::get_best_session_directory_for_new_source ()
1668 vector<space_and_path>::iterator i;
1669 string result = _session_dir->root_path().to_string();
1671 /* handle common case without system calls */
1673 if (session_dirs.size() == 1) {
1677 /* OK, here's the algorithm we're following here:
1679 We want to select which directory to use for
1680 the next file source to be created. Ideally,
1681 we'd like to use a round-robin process so as to
1682 get maximum performance benefits from splitting
1683 the files across multiple disks.
1685 However, in situations without much diskspace, an
1686 RR approach may end up filling up a filesystem
1687 with new files while others still have space.
1688 Its therefore important to pay some attention to
1689 the freespace in the filesystem holding each
1690 directory as well. However, if we did that by
1691 itself, we'd keep creating new files in the file
1692 system with the most space until it was as full
1693 as all others, thus negating any performance
1694 benefits of this RAID-1 like approach.
1696 So, we use a user-configurable space threshold. If
1697 there are at least 2 filesystems with more than this
1698 much space available, we use RR selection between them.
1699 If not, then we pick the filesystem with the most space.
1701 This gets a good balance between the two
1705 refresh_disk_space ();
1707 int free_enough = 0;
1709 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1710 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1715 if (free_enough >= 2) {
1716 /* use RR selection process, ensuring that the one
1720 i = last_rr_session_dir;
1723 if (++i == session_dirs.end()) {
1724 i = session_dirs.begin();
1727 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1728 if (create_session_directory ((*i).path)) {
1730 last_rr_session_dir = i;
1735 } while (i != last_rr_session_dir);
1739 /* pick FS with the most freespace (and that
1740 seems to actually work ...)
1743 vector<space_and_path> sorted;
1744 space_and_path_ascending_cmp cmp;
1746 sorted = session_dirs;
1747 sort (sorted.begin(), sorted.end(), cmp);
1749 for (i = sorted.begin(); i != sorted.end(); ++i) {
1750 if (create_session_directory ((*i).path)) {
1752 last_rr_session_dir = i;
1762 Session::load_playlists (const XMLNode& node)
1765 XMLNodeConstIterator niter;
1766 boost::shared_ptr<Playlist> playlist;
1768 nlist = node.children();
1772 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1774 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1775 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1783 Session::load_unused_playlists (const XMLNode& node)
1786 XMLNodeConstIterator niter;
1787 boost::shared_ptr<Playlist> playlist;
1789 nlist = node.children();
1793 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1795 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1796 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1800 // now manually untrack it
1802 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1808 boost::shared_ptr<Playlist>
1809 Session::XMLPlaylistFactory (const XMLNode& node)
1812 return PlaylistFactory::create (*this, node);
1815 catch (failed_constructor& err) {
1816 return boost::shared_ptr<Playlist>();
1821 Session::load_named_selections (const XMLNode& node)
1824 XMLNodeConstIterator niter;
1827 nlist = node.children();
1831 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1833 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1834 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1842 Session::XMLNamedSelectionFactory (const XMLNode& node)
1845 return new NamedSelection (*this, node);
1848 catch (failed_constructor& err) {
1854 Session::automation_dir () const
1857 res += "automation/";
1862 Session::template_dir ()
1864 string path = get_user_ardour_path();
1865 path += "templates/";
1871 Session::suffixed_search_path (string suffix, bool data)
1875 path += get_user_ardour_path();
1876 if (path[path.length()-1] != ':') {
1881 path += get_system_data_path();
1883 path += get_system_module_path();
1886 vector<string> split_path;
1888 split (path, split_path, ':');
1891 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
1896 if (distance (i, split_path.end()) != 1) {
1905 Session::template_path ()
1907 return suffixed_search_path (templates_dir_name, true);
1911 Session::control_protocol_path ()
1913 return suffixed_search_path (surfaces_dir_name, false);
1917 Session::load_bundles (const XMLNode& node)
1919 XMLNodeList nlist = node.children();
1920 XMLNodeConstIterator niter;
1924 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1925 if ((*niter)->name() == "InputConnection") {
1926 add_bundle (new ARDOUR::InputBundle (**niter));
1927 } else if ((*niter)->name() == "OutputConnection") {
1928 add_bundle (new ARDOUR::OutputBundle (**niter));
1930 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1939 Session::load_edit_groups (const XMLNode& node)
1941 return load_route_groups (node, true);
1945 Session::load_mix_groups (const XMLNode& node)
1947 return load_route_groups (node, false);
1951 Session::load_route_groups (const XMLNode& node, bool edit)
1953 XMLNodeList nlist = node.children();
1954 XMLNodeConstIterator niter;
1959 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1960 if ((*niter)->name() == "RouteGroup") {
1962 rg = add_edit_group ("");
1963 rg->set_state (**niter);
1965 rg = add_mix_group ("");
1966 rg->set_state (**niter);
1975 state_file_filter (const string &str, void *arg)
1977 return (str.length() > strlen(statefile_suffix) &&
1978 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
1982 bool operator()(const string* a, const string* b) {
1988 remove_end(string* state)
1990 string statename(*state);
1992 string::size_type start,end;
1993 if ((start = statename.find_last_of ('/')) != string::npos) {
1994 statename = statename.substr (start+1);
1997 if ((end = statename.rfind(".ardour")) == string::npos) {
1998 end = statename.length();
2001 return new string(statename.substr (0, end));
2005 Session::possible_states (string path)
2007 PathScanner scanner;
2008 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2010 transform(states->begin(), states->end(), states->begin(), remove_end);
2013 sort (states->begin(), states->end(), cmp);
2019 Session::possible_states () const
2021 return possible_states(_path);
2025 Session::auto_save()
2027 save_state (_current_snapshot_name);
2031 Session::add_edit_group (string name)
2033 RouteGroup* rg = new RouteGroup (*this, name);
2034 edit_groups.push_back (rg);
2035 edit_group_added (rg); /* EMIT SIGNAL */
2041 Session::add_mix_group (string name)
2043 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2044 mix_groups.push_back (rg);
2045 mix_group_added (rg); /* EMIT SIGNAL */
2051 Session::remove_edit_group (RouteGroup& rg)
2053 list<RouteGroup*>::iterator i;
2055 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2056 (*i)->apply (&Route::drop_edit_group, this);
2057 edit_groups.erase (i);
2058 edit_group_removed (); /* EMIT SIGNAL */
2065 Session::remove_mix_group (RouteGroup& rg)
2067 list<RouteGroup*>::iterator i;
2069 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2070 (*i)->apply (&Route::drop_mix_group, this);
2071 mix_groups.erase (i);
2072 mix_group_removed (); /* EMIT SIGNAL */
2079 Session::mix_group_by_name (string name)
2081 list<RouteGroup *>::iterator i;
2083 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2084 if ((*i)->name() == name) {
2092 Session::edit_group_by_name (string name)
2094 list<RouteGroup *>::iterator i;
2096 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2097 if ((*i)->name() == name) {
2105 Session::begin_reversible_command (string name)
2107 current_trans = new UndoTransaction;
2108 current_trans->set_name (name);
2112 Session::commit_reversible_command (Command *cmd)
2117 current_trans->add_command (cmd);
2120 gettimeofday (&now, 0);
2121 current_trans->set_timestamp (now);
2123 _history.add (current_trans);
2126 Session::GlobalRouteBooleanState
2127 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2129 GlobalRouteBooleanState s;
2130 boost::shared_ptr<RouteList> r = routes.reader ();
2132 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2133 if (!(*i)->hidden()) {
2134 RouteBooleanState v;
2137 Route* r = (*i).get();
2138 v.second = (r->*method)();
2147 Session::GlobalRouteMeterState
2148 Session::get_global_route_metering ()
2150 GlobalRouteMeterState s;
2151 boost::shared_ptr<RouteList> r = routes.reader ();
2153 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2154 if (!(*i)->hidden()) {
2158 v.second = (*i)->meter_point();
2168 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2170 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2172 boost::shared_ptr<Route> r = (i->first.lock());
2175 r->set_meter_point (i->second, arg);
2181 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2183 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2185 boost::shared_ptr<Route> r = (i->first.lock());
2188 Route* rp = r.get();
2189 (rp->*method) (i->second, arg);
2195 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2197 set_global_route_boolean (s, &Route::set_mute, src);
2201 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2203 set_global_route_boolean (s, &Route::set_solo, src);
2207 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2209 set_global_route_boolean (s, &Route::set_record_enable, src);
2214 Session::global_mute_memento (void* src)
2216 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2220 Session::global_metering_memento (void* src)
2222 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2226 Session::global_solo_memento (void* src)
2228 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2232 Session::global_record_enable_memento (void* src)
2234 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2239 accept_all_non_peak_files (const string& path, void *arg)
2241 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2245 accept_all_state_files (const string& path, void *arg)
2247 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2251 Session::find_all_sources (string path, set<string>& result)
2256 if (!tree.read (path)) {
2260 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2265 XMLNodeConstIterator niter;
2267 nlist = node->children();
2271 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2275 if ((prop = (*niter)->property (X_("name"))) == 0) {
2279 if (prop->value()[0] == '/') {
2280 /* external file, ignore */
2284 sys::path source_path = _session_dir->sound_path ();
2286 source_path /= prop->value ();
2288 result.insert (source_path.to_string ());
2295 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2297 PathScanner scanner;
2298 vector<string*>* state_files;
2300 string this_snapshot_path;
2306 if (ripped[ripped.length()-1] == '/') {
2307 ripped = ripped.substr (0, ripped.length() - 1);
2310 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2312 if (state_files == 0) {
2317 this_snapshot_path = _path;
2318 this_snapshot_path += _current_snapshot_name;
2319 this_snapshot_path += statefile_suffix;
2321 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2323 if (exclude_this_snapshot && **i == this_snapshot_path) {
2327 if (find_all_sources (**i, result) < 0) {
2335 struct RegionCounter {
2336 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2337 AudioSourceList::iterator iter;
2338 boost::shared_ptr<Region> region;
2341 RegionCounter() : count (0) {}
2345 Session::cleanup_sources (Session::cleanup_report& rep)
2347 // FIXME: needs adaptation to midi
2349 vector<boost::shared_ptr<Source> > dead_sources;
2350 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2351 PathScanner scanner;
2353 vector<space_and_path>::iterator i;
2354 vector<space_and_path>::iterator nexti;
2355 vector<string*>* soundfiles;
2356 vector<string> unused;
2357 set<string> all_sources;
2362 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2364 /* step 1: consider deleting all unused playlists */
2366 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2369 status = AskAboutPlaylistDeletion (*x);
2378 playlists_tbd.push_back (*x);
2382 /* leave it alone */
2387 /* now delete any that were marked for deletion */
2389 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2390 (*x)->drop_references ();
2393 playlists_tbd.clear ();
2395 /* step 2: find all un-used sources */
2400 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2402 SourceMap::iterator tmp;
2407 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2411 if (!i->second->used() && i->second->length() > 0) {
2412 dead_sources.push_back (i->second);
2413 i->second->GoingAway();
2419 /* build a list of all the possible sound directories for the session */
2421 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2426 SessionDirectory sdir ((*i).path);
2427 sound_path += sdir.sound_path().to_string();
2429 if (nexti != session_dirs.end()) {
2436 /* now do the same thing for the files that ended up in the sounds dir(s)
2437 but are not referenced as sources in any snapshot.
2440 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2442 if (soundfiles == 0) {
2446 /* find all sources, but don't use this snapshot because the
2447 state file on disk still references sources we may have already
2451 find_all_sources_across_snapshots (all_sources, true);
2453 /* add our current source list
2456 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2457 boost::shared_ptr<AudioFileSource> fs;
2459 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2460 all_sources.insert (fs->path());
2464 char tmppath1[PATH_MAX+1];
2465 char tmppath2[PATH_MAX+1];
2467 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2472 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2474 realpath(spath.c_str(), tmppath1);
2475 realpath((*i).c_str(), tmppath2);
2477 if (strcmp(tmppath1, tmppath2) == 0) {
2484 unused.push_back (spath);
2488 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2490 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2491 struct stat statbuf;
2493 rep.paths.push_back (*x);
2494 if (stat ((*x).c_str(), &statbuf) == 0) {
2495 rep.space += statbuf.st_size;
2500 /* don't move the file across filesystems, just
2501 stick it in the `dead_sound_dir_name' directory
2502 on whichever filesystem it was already on.
2505 if ((*x).find ("/sounds/") != string::npos) {
2507 /* old school, go up 1 level */
2509 newpath = Glib::path_get_dirname (*x); // "sounds"
2510 newpath = Glib::path_get_dirname (newpath); // "session-name"
2514 /* new school, go up 4 levels */
2516 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2517 newpath = Glib::path_get_dirname (newpath); // "session-name"
2518 newpath = Glib::path_get_dirname (newpath); // "interchange"
2519 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2523 newpath += dead_sound_dir_name;
2525 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2526 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2531 newpath += Glib::path_get_basename ((*x));
2533 if (access (newpath.c_str(), F_OK) == 0) {
2535 /* the new path already exists, try versioning */
2537 char buf[PATH_MAX+1];
2541 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2544 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2545 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2549 if (version == 999) {
2550 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2554 newpath = newpath_v;
2559 /* it doesn't exist, or we can't read it or something */
2563 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2564 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2565 (*x), newpath, strerror (errno))
2570 /* see if there an easy to find peakfile for this file, and remove it.
2573 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2574 peakpath += peakfile_suffix;
2576 if (access (peakpath.c_str(), W_OK) == 0) {
2577 if (::unlink (peakpath.c_str()) != 0) {
2578 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2579 peakpath, _path, strerror (errno))
2581 /* try to back out */
2582 rename (newpath.c_str(), _path.c_str());
2590 /* dump the history list */
2594 /* save state so we don't end up a session file
2595 referring to non-existent sources.
2601 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2606 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2608 // FIXME: needs adaptation for MIDI
2610 vector<space_and_path>::iterator i;
2611 string dead_sound_dir;
2612 struct dirent* dentry;
2613 struct stat statbuf;
2619 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2621 dead_sound_dir = (*i).path;
2622 dead_sound_dir += dead_sound_dir_name;
2624 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2628 while ((dentry = readdir (dead)) != 0) {
2630 /* avoid '.' and '..' */
2632 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2633 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2639 fullpath = dead_sound_dir;
2641 fullpath += dentry->d_name;
2643 if (stat (fullpath.c_str(), &statbuf)) {
2647 if (!S_ISREG (statbuf.st_mode)) {
2651 if (unlink (fullpath.c_str())) {
2652 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2653 fullpath, strerror (errno))
2657 rep.paths.push_back (dentry->d_name);
2658 rep.space += statbuf.st_size;
2669 Session::set_dirty ()
2671 bool was_dirty = dirty();
2673 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2676 DirtyChanged(); /* EMIT SIGNAL */
2682 Session::set_clean ()
2684 bool was_dirty = dirty();
2686 _state_of_the_state = Clean;
2689 DirtyChanged(); /* EMIT SIGNAL */
2694 Session::set_deletion_in_progress ()
2696 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2700 Session::add_controllable (Controllable* c)
2702 /* this adds a controllable to the list managed by the Session.
2703 this is a subset of those managed by the Controllable class
2704 itself, and represents the only ones whose state will be saved
2705 as part of the session.
2708 Glib::Mutex::Lock lm (controllables_lock);
2709 controllables.insert (c);
2713 Session::remove_controllable (Controllable* c)
2715 if (_state_of_the_state | Deletion) {
2719 Glib::Mutex::Lock lm (controllables_lock);
2721 Controllables::iterator x = controllables.find (c);
2723 if (x != controllables.end()) {
2724 controllables.erase (x);
2729 Session::controllable_by_id (const PBD::ID& id)
2731 Glib::Mutex::Lock lm (controllables_lock);
2733 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2734 if ((*i)->id() == id) {
2743 Session::add_instant_xml (XMLNode& node)
2745 Stateful::add_instant_xml (node, _path);
2746 Config->add_instant_xml (node);
2750 Session::instant_xml (const string& node_name)
2752 return Stateful::instant_xml (node_name, _path);
2756 Session::save_history (string snapshot_name)
2762 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2764 if (snapshot_name.empty()) {
2765 snapshot_name = _current_snapshot_name;
2768 xml_path = _path + snapshot_name + ".history";
2770 bak_path = xml_path + ".bak";
2772 if ((access (xml_path.c_str(), F_OK) == 0) &&
2773 (rename (xml_path.c_str(), bak_path.c_str())))
2775 error << _("could not backup old history file, current history not saved.") << endmsg;
2779 if (!tree.write (xml_path))
2781 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2783 /* don't leave a corrupt file lying around if it is
2787 if (unlink (xml_path.c_str())) {
2788 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2790 if (rename (bak_path.c_str(), xml_path.c_str()))
2792 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2803 Session::restore_history (string snapshot_name)
2808 if (snapshot_name.empty()) {
2809 snapshot_name = _current_snapshot_name;
2813 xmlpath = _path + snapshot_name + ".history";
2814 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2816 if (access (xmlpath.c_str(), F_OK)) {
2817 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2821 if (!tree.read (xmlpath)) {
2822 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2826 /* replace history */
2829 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2832 UndoTransaction* ut = new UndoTransaction ();
2835 ut->set_name(t->property("name")->value());
2836 stringstream ss(t->property("tv_sec")->value());
2838 ss.str(t->property("tv_usec")->value());
2840 ut->set_timestamp(tv);
2842 for (XMLNodeConstIterator child_it = t->children().begin();
2843 child_it != t->children().end();
2846 XMLNode *n = *child_it;
2849 if (n->name() == "MementoCommand" ||
2850 n->name() == "MementoUndoCommand" ||
2851 n->name() == "MementoRedoCommand") {
2853 if ((c = memento_command_factory(n))) {
2857 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2859 if ((c = global_state_command_factory (*n))) {
2860 ut->add_command (c);
2865 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2876 Session::config_changed (const char* parameter_name)
2878 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2880 if (PARAM_IS ("seamless-loop")) {
2882 } else if (PARAM_IS ("rf-speed")) {
2884 } else if (PARAM_IS ("auto-loop")) {
2886 } else if (PARAM_IS ("auto-input")) {
2888 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2889 /* auto-input only makes a difference if we're rolling */
2891 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2893 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2894 if ((*i)->record_enabled ()) {
2895 (*i)->monitor_input (!Config->get_auto_input());
2900 } else if (PARAM_IS ("punch-in")) {
2904 if ((location = _locations.auto_punch_location()) != 0) {
2906 if (Config->get_punch_in ()) {
2907 replace_event (Event::PunchIn, location->start());
2909 remove_event (location->start(), Event::PunchIn);
2913 } else if (PARAM_IS ("punch-out")) {
2917 if ((location = _locations.auto_punch_location()) != 0) {
2919 if (Config->get_punch_out()) {
2920 replace_event (Event::PunchOut, location->end());
2922 clear_events (Event::PunchOut);
2926 } else if (PARAM_IS ("edit-mode")) {
2928 Glib::Mutex::Lock lm (playlist_lock);
2930 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2931 (*i)->set_edit_mode (Config->get_edit_mode ());
2934 } else if (PARAM_IS ("use-video-sync")) {
2936 waiting_for_sync_offset = Config->get_use_video_sync();
2938 } else if (PARAM_IS ("mmc-control")) {
2940 //poke_midi_thread ();
2942 } else if (PARAM_IS ("mmc-device-id")) {
2945 mmc->set_device_id (Config->get_mmc_device_id());
2948 } else if (PARAM_IS ("midi-control")) {
2950 //poke_midi_thread ();
2952 } else if (PARAM_IS ("raid-path")) {
2954 setup_raid_path (Config->get_raid_path());
2956 } else if (PARAM_IS ("smpte-format")) {
2960 } else if (PARAM_IS ("video-pullup")) {
2964 } else if (PARAM_IS ("seamless-loop")) {
2966 if (play_loop && transport_rolling()) {
2967 // to reset diskstreams etc
2968 request_play_loop (true);
2971 } else if (PARAM_IS ("rf-speed")) {
2973 cumulative_rf_motion = 0;
2976 } else if (PARAM_IS ("click-sound")) {
2978 setup_click_sounds (1);
2980 } else if (PARAM_IS ("click-emphasis-sound")) {
2982 setup_click_sounds (-1);
2984 } else if (PARAM_IS ("clicking")) {
2986 if (Config->get_clicking()) {
2987 if (_click_io && click_data) { // don't require emphasis data
2994 } else if (PARAM_IS ("send-mtc")) {
2996 /* only set the internal flag if we have
3000 if (_mtc_port != 0) {
3001 session_send_mtc = Config->get_send_mtc();
3002 if (session_send_mtc) {
3003 /* mark us ready to send */
3004 next_quarter_frame_to_send = 0;
3007 session_send_mtc = false;
3010 } else if (PARAM_IS ("send-mmc")) {
3012 /* only set the internal flag if we have
3016 if (_mmc_port != 0) {
3017 session_send_mmc = Config->get_send_mmc();
3020 session_send_mmc = false;
3023 } else if (PARAM_IS ("midi-feedback")) {
3025 /* only set the internal flag if we have
3029 if (_mtc_port != 0) {
3030 session_midi_feedback = Config->get_midi_feedback();
3033 } else if (PARAM_IS ("jack-time-master")) {
3035 engine().reset_timebase ();
3037 } else if (PARAM_IS ("native-file-header-format")) {
3039 if (!first_file_header_format_reset) {
3040 reset_native_file_format ();
3043 first_file_header_format_reset = false;
3045 } else if (PARAM_IS ("native-file-data-format")) {
3047 if (!first_file_data_format_reset) {
3048 reset_native_file_format ();
3051 first_file_data_format_reset = false;
3053 } else if (PARAM_IS ("slave-source")) {
3054 set_slave_source (Config->get_slave_source());
3055 } else if (PARAM_IS ("remote-model")) {
3056 set_remote_control_ids ();
3057 } else if (PARAM_IS ("denormal-model")) {