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::control_protocol_path ()
1907 return suffixed_search_path (surfaces_dir_name, false);
1911 Session::load_bundles (const XMLNode& node)
1913 XMLNodeList nlist = node.children();
1914 XMLNodeConstIterator niter;
1918 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1919 if ((*niter)->name() == "InputConnection") {
1920 add_bundle (new ARDOUR::InputBundle (**niter));
1921 } else if ((*niter)->name() == "OutputConnection") {
1922 add_bundle (new ARDOUR::OutputBundle (**niter));
1924 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1933 Session::load_edit_groups (const XMLNode& node)
1935 return load_route_groups (node, true);
1939 Session::load_mix_groups (const XMLNode& node)
1941 return load_route_groups (node, false);
1945 Session::load_route_groups (const XMLNode& node, bool edit)
1947 XMLNodeList nlist = node.children();
1948 XMLNodeConstIterator niter;
1953 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1954 if ((*niter)->name() == "RouteGroup") {
1956 rg = add_edit_group ("");
1957 rg->set_state (**niter);
1959 rg = add_mix_group ("");
1960 rg->set_state (**niter);
1969 state_file_filter (const string &str, void *arg)
1971 return (str.length() > strlen(statefile_suffix) &&
1972 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
1976 bool operator()(const string* a, const string* b) {
1982 remove_end(string* state)
1984 string statename(*state);
1986 string::size_type start,end;
1987 if ((start = statename.find_last_of ('/')) != string::npos) {
1988 statename = statename.substr (start+1);
1991 if ((end = statename.rfind(".ardour")) == string::npos) {
1992 end = statename.length();
1995 return new string(statename.substr (0, end));
1999 Session::possible_states (string path)
2001 PathScanner scanner;
2002 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2004 transform(states->begin(), states->end(), states->begin(), remove_end);
2007 sort (states->begin(), states->end(), cmp);
2013 Session::possible_states () const
2015 return possible_states(_path);
2019 Session::auto_save()
2021 save_state (_current_snapshot_name);
2025 Session::add_edit_group (string name)
2027 RouteGroup* rg = new RouteGroup (*this, name);
2028 edit_groups.push_back (rg);
2029 edit_group_added (rg); /* EMIT SIGNAL */
2035 Session::add_mix_group (string name)
2037 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2038 mix_groups.push_back (rg);
2039 mix_group_added (rg); /* EMIT SIGNAL */
2045 Session::remove_edit_group (RouteGroup& rg)
2047 list<RouteGroup*>::iterator i;
2049 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2050 (*i)->apply (&Route::drop_edit_group, this);
2051 edit_groups.erase (i);
2052 edit_group_removed (); /* EMIT SIGNAL */
2059 Session::remove_mix_group (RouteGroup& rg)
2061 list<RouteGroup*>::iterator i;
2063 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2064 (*i)->apply (&Route::drop_mix_group, this);
2065 mix_groups.erase (i);
2066 mix_group_removed (); /* EMIT SIGNAL */
2073 Session::mix_group_by_name (string name)
2075 list<RouteGroup *>::iterator i;
2077 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2078 if ((*i)->name() == name) {
2086 Session::edit_group_by_name (string name)
2088 list<RouteGroup *>::iterator i;
2090 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2091 if ((*i)->name() == name) {
2099 Session::begin_reversible_command (string name)
2101 current_trans = new UndoTransaction;
2102 current_trans->set_name (name);
2106 Session::commit_reversible_command (Command *cmd)
2111 current_trans->add_command (cmd);
2114 gettimeofday (&now, 0);
2115 current_trans->set_timestamp (now);
2117 _history.add (current_trans);
2120 Session::GlobalRouteBooleanState
2121 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2123 GlobalRouteBooleanState s;
2124 boost::shared_ptr<RouteList> r = routes.reader ();
2126 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2127 if (!(*i)->hidden()) {
2128 RouteBooleanState v;
2131 Route* r = (*i).get();
2132 v.second = (r->*method)();
2141 Session::GlobalRouteMeterState
2142 Session::get_global_route_metering ()
2144 GlobalRouteMeterState s;
2145 boost::shared_ptr<RouteList> r = routes.reader ();
2147 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2148 if (!(*i)->hidden()) {
2152 v.second = (*i)->meter_point();
2162 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2164 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2166 boost::shared_ptr<Route> r = (i->first.lock());
2169 r->set_meter_point (i->second, arg);
2175 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2177 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2179 boost::shared_ptr<Route> r = (i->first.lock());
2182 Route* rp = r.get();
2183 (rp->*method) (i->second, arg);
2189 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2191 set_global_route_boolean (s, &Route::set_mute, src);
2195 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2197 set_global_route_boolean (s, &Route::set_solo, src);
2201 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2203 set_global_route_boolean (s, &Route::set_record_enable, src);
2208 Session::global_mute_memento (void* src)
2210 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2214 Session::global_metering_memento (void* src)
2216 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2220 Session::global_solo_memento (void* src)
2222 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2226 Session::global_record_enable_memento (void* src)
2228 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2233 accept_all_non_peak_files (const string& path, void *arg)
2235 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2239 accept_all_state_files (const string& path, void *arg)
2241 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2245 Session::find_all_sources (string path, set<string>& result)
2250 if (!tree.read (path)) {
2254 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2259 XMLNodeConstIterator niter;
2261 nlist = node->children();
2265 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2269 if ((prop = (*niter)->property (X_("name"))) == 0) {
2273 if (prop->value()[0] == '/') {
2274 /* external file, ignore */
2278 sys::path source_path = _session_dir->sound_path ();
2280 source_path /= prop->value ();
2282 result.insert (source_path.to_string ());
2289 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2291 PathScanner scanner;
2292 vector<string*>* state_files;
2294 string this_snapshot_path;
2300 if (ripped[ripped.length()-1] == '/') {
2301 ripped = ripped.substr (0, ripped.length() - 1);
2304 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2306 if (state_files == 0) {
2311 this_snapshot_path = _path;
2312 this_snapshot_path += _current_snapshot_name;
2313 this_snapshot_path += statefile_suffix;
2315 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2317 if (exclude_this_snapshot && **i == this_snapshot_path) {
2321 if (find_all_sources (**i, result) < 0) {
2329 struct RegionCounter {
2330 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2331 AudioSourceList::iterator iter;
2332 boost::shared_ptr<Region> region;
2335 RegionCounter() : count (0) {}
2339 Session::cleanup_sources (Session::cleanup_report& rep)
2341 // FIXME: needs adaptation to midi
2343 vector<boost::shared_ptr<Source> > dead_sources;
2344 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2345 PathScanner scanner;
2347 vector<space_and_path>::iterator i;
2348 vector<space_and_path>::iterator nexti;
2349 vector<string*>* soundfiles;
2350 vector<string> unused;
2351 set<string> all_sources;
2356 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2358 /* step 1: consider deleting all unused playlists */
2360 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2363 status = AskAboutPlaylistDeletion (*x);
2372 playlists_tbd.push_back (*x);
2376 /* leave it alone */
2381 /* now delete any that were marked for deletion */
2383 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2384 (*x)->drop_references ();
2387 playlists_tbd.clear ();
2389 /* step 2: find all un-used sources */
2394 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2396 SourceMap::iterator tmp;
2401 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2405 if (!i->second->used() && i->second->length() > 0) {
2406 dead_sources.push_back (i->second);
2407 i->second->GoingAway();
2413 /* build a list of all the possible sound directories for the session */
2415 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2420 SessionDirectory sdir ((*i).path);
2421 sound_path += sdir.sound_path().to_string();
2423 if (nexti != session_dirs.end()) {
2430 /* now do the same thing for the files that ended up in the sounds dir(s)
2431 but are not referenced as sources in any snapshot.
2434 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2436 if (soundfiles == 0) {
2440 /* find all sources, but don't use this snapshot because the
2441 state file on disk still references sources we may have already
2445 find_all_sources_across_snapshots (all_sources, true);
2447 /* add our current source list
2450 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2451 boost::shared_ptr<AudioFileSource> fs;
2453 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2454 all_sources.insert (fs->path());
2458 char tmppath1[PATH_MAX+1];
2459 char tmppath2[PATH_MAX+1];
2461 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2466 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2468 realpath(spath.c_str(), tmppath1);
2469 realpath((*i).c_str(), tmppath2);
2471 if (strcmp(tmppath1, tmppath2) == 0) {
2478 unused.push_back (spath);
2482 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2484 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2485 struct stat statbuf;
2487 rep.paths.push_back (*x);
2488 if (stat ((*x).c_str(), &statbuf) == 0) {
2489 rep.space += statbuf.st_size;
2494 /* don't move the file across filesystems, just
2495 stick it in the `dead_sound_dir_name' directory
2496 on whichever filesystem it was already on.
2499 if ((*x).find ("/sounds/") != string::npos) {
2501 /* old school, go up 1 level */
2503 newpath = Glib::path_get_dirname (*x); // "sounds"
2504 newpath = Glib::path_get_dirname (newpath); // "session-name"
2508 /* new school, go up 4 levels */
2510 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2511 newpath = Glib::path_get_dirname (newpath); // "session-name"
2512 newpath = Glib::path_get_dirname (newpath); // "interchange"
2513 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2517 newpath += dead_sound_dir_name;
2519 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2520 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2525 newpath += Glib::path_get_basename ((*x));
2527 if (access (newpath.c_str(), F_OK) == 0) {
2529 /* the new path already exists, try versioning */
2531 char buf[PATH_MAX+1];
2535 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2538 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2539 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2543 if (version == 999) {
2544 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2548 newpath = newpath_v;
2553 /* it doesn't exist, or we can't read it or something */
2557 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2558 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2559 (*x), newpath, strerror (errno))
2564 /* see if there an easy to find peakfile for this file, and remove it.
2567 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2568 peakpath += peakfile_suffix;
2570 if (access (peakpath.c_str(), W_OK) == 0) {
2571 if (::unlink (peakpath.c_str()) != 0) {
2572 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2573 peakpath, _path, strerror (errno))
2575 /* try to back out */
2576 rename (newpath.c_str(), _path.c_str());
2584 /* dump the history list */
2588 /* save state so we don't end up a session file
2589 referring to non-existent sources.
2595 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2600 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2602 // FIXME: needs adaptation for MIDI
2604 vector<space_and_path>::iterator i;
2605 string dead_sound_dir;
2606 struct dirent* dentry;
2607 struct stat statbuf;
2613 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2615 dead_sound_dir = (*i).path;
2616 dead_sound_dir += dead_sound_dir_name;
2618 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2622 while ((dentry = readdir (dead)) != 0) {
2624 /* avoid '.' and '..' */
2626 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2627 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2633 fullpath = dead_sound_dir;
2635 fullpath += dentry->d_name;
2637 if (stat (fullpath.c_str(), &statbuf)) {
2641 if (!S_ISREG (statbuf.st_mode)) {
2645 if (unlink (fullpath.c_str())) {
2646 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2647 fullpath, strerror (errno))
2651 rep.paths.push_back (dentry->d_name);
2652 rep.space += statbuf.st_size;
2663 Session::set_dirty ()
2665 bool was_dirty = dirty();
2667 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2670 DirtyChanged(); /* EMIT SIGNAL */
2676 Session::set_clean ()
2678 bool was_dirty = dirty();
2680 _state_of_the_state = Clean;
2683 DirtyChanged(); /* EMIT SIGNAL */
2688 Session::set_deletion_in_progress ()
2690 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2694 Session::add_controllable (Controllable* c)
2696 /* this adds a controllable to the list managed by the Session.
2697 this is a subset of those managed by the Controllable class
2698 itself, and represents the only ones whose state will be saved
2699 as part of the session.
2702 Glib::Mutex::Lock lm (controllables_lock);
2703 controllables.insert (c);
2707 Session::remove_controllable (Controllable* c)
2709 if (_state_of_the_state | Deletion) {
2713 Glib::Mutex::Lock lm (controllables_lock);
2715 Controllables::iterator x = controllables.find (c);
2717 if (x != controllables.end()) {
2718 controllables.erase (x);
2723 Session::controllable_by_id (const PBD::ID& id)
2725 Glib::Mutex::Lock lm (controllables_lock);
2727 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2728 if ((*i)->id() == id) {
2737 Session::add_instant_xml (XMLNode& node)
2739 Stateful::add_instant_xml (node, _path);
2740 Config->add_instant_xml (node);
2744 Session::instant_xml (const string& node_name)
2746 return Stateful::instant_xml (node_name, _path);
2750 Session::save_history (string snapshot_name)
2756 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2758 if (snapshot_name.empty()) {
2759 snapshot_name = _current_snapshot_name;
2762 xml_path = _path + snapshot_name + ".history";
2764 bak_path = xml_path + ".bak";
2766 if ((access (xml_path.c_str(), F_OK) == 0) &&
2767 (rename (xml_path.c_str(), bak_path.c_str())))
2769 error << _("could not backup old history file, current history not saved.") << endmsg;
2773 if (!tree.write (xml_path))
2775 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2777 /* don't leave a corrupt file lying around if it is
2781 if (unlink (xml_path.c_str())) {
2782 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2784 if (rename (bak_path.c_str(), xml_path.c_str()))
2786 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2797 Session::restore_history (string snapshot_name)
2802 if (snapshot_name.empty()) {
2803 snapshot_name = _current_snapshot_name;
2807 xmlpath = _path + snapshot_name + ".history";
2808 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2810 if (access (xmlpath.c_str(), F_OK)) {
2811 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2815 if (!tree.read (xmlpath)) {
2816 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2820 /* replace history */
2823 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2826 UndoTransaction* ut = new UndoTransaction ();
2829 ut->set_name(t->property("name")->value());
2830 stringstream ss(t->property("tv_sec")->value());
2832 ss.str(t->property("tv_usec")->value());
2834 ut->set_timestamp(tv);
2836 for (XMLNodeConstIterator child_it = t->children().begin();
2837 child_it != t->children().end();
2840 XMLNode *n = *child_it;
2843 if (n->name() == "MementoCommand" ||
2844 n->name() == "MementoUndoCommand" ||
2845 n->name() == "MementoRedoCommand") {
2847 if ((c = memento_command_factory(n))) {
2851 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2853 if ((c = global_state_command_factory (*n))) {
2854 ut->add_command (c);
2859 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2870 Session::config_changed (const char* parameter_name)
2872 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2874 if (PARAM_IS ("seamless-loop")) {
2876 } else if (PARAM_IS ("rf-speed")) {
2878 } else if (PARAM_IS ("auto-loop")) {
2880 } else if (PARAM_IS ("auto-input")) {
2882 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2883 /* auto-input only makes a difference if we're rolling */
2885 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2887 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2888 if ((*i)->record_enabled ()) {
2889 (*i)->monitor_input (!Config->get_auto_input());
2894 } else if (PARAM_IS ("punch-in")) {
2898 if ((location = _locations.auto_punch_location()) != 0) {
2900 if (Config->get_punch_in ()) {
2901 replace_event (Event::PunchIn, location->start());
2903 remove_event (location->start(), Event::PunchIn);
2907 } else if (PARAM_IS ("punch-out")) {
2911 if ((location = _locations.auto_punch_location()) != 0) {
2913 if (Config->get_punch_out()) {
2914 replace_event (Event::PunchOut, location->end());
2916 clear_events (Event::PunchOut);
2920 } else if (PARAM_IS ("edit-mode")) {
2922 Glib::Mutex::Lock lm (playlist_lock);
2924 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2925 (*i)->set_edit_mode (Config->get_edit_mode ());
2928 } else if (PARAM_IS ("use-video-sync")) {
2930 waiting_for_sync_offset = Config->get_use_video_sync();
2932 } else if (PARAM_IS ("mmc-control")) {
2934 //poke_midi_thread ();
2936 } else if (PARAM_IS ("mmc-device-id")) {
2939 mmc->set_device_id (Config->get_mmc_device_id());
2942 } else if (PARAM_IS ("midi-control")) {
2944 //poke_midi_thread ();
2946 } else if (PARAM_IS ("raid-path")) {
2948 setup_raid_path (Config->get_raid_path());
2950 } else if (PARAM_IS ("smpte-format")) {
2954 } else if (PARAM_IS ("video-pullup")) {
2958 } else if (PARAM_IS ("seamless-loop")) {
2960 if (play_loop && transport_rolling()) {
2961 // to reset diskstreams etc
2962 request_play_loop (true);
2965 } else if (PARAM_IS ("rf-speed")) {
2967 cumulative_rf_motion = 0;
2970 } else if (PARAM_IS ("click-sound")) {
2972 setup_click_sounds (1);
2974 } else if (PARAM_IS ("click-emphasis-sound")) {
2976 setup_click_sounds (-1);
2978 } else if (PARAM_IS ("clicking")) {
2980 if (Config->get_clicking()) {
2981 if (_click_io && click_data) { // don't require emphasis data
2988 } else if (PARAM_IS ("send-mtc")) {
2990 /* only set the internal flag if we have
2994 if (_mtc_port != 0) {
2995 session_send_mtc = Config->get_send_mtc();
2996 if (session_send_mtc) {
2997 /* mark us ready to send */
2998 next_quarter_frame_to_send = 0;
3001 session_send_mtc = false;
3004 } else if (PARAM_IS ("send-mmc")) {
3006 /* only set the internal flag if we have
3010 if (_mmc_port != 0) {
3011 session_send_mmc = Config->get_send_mmc();
3014 session_send_mmc = false;
3017 } else if (PARAM_IS ("midi-feedback")) {
3019 /* only set the internal flag if we have
3023 if (_mtc_port != 0) {
3024 session_midi_feedback = Config->get_midi_feedback();
3027 } else if (PARAM_IS ("jack-time-master")) {
3029 engine().reset_timebase ();
3031 } else if (PARAM_IS ("native-file-header-format")) {
3033 if (!first_file_header_format_reset) {
3034 reset_native_file_format ();
3037 first_file_header_format_reset = false;
3039 } else if (PARAM_IS ("native-file-data-format")) {
3041 if (!first_file_data_format_reset) {
3042 reset_native_file_format ();
3045 first_file_data_format_reset = false;
3047 } else if (PARAM_IS ("slave-source")) {
3048 set_slave_source (Config->get_slave_source());
3049 } else if (PARAM_IS ("remote-model")) {
3050 set_remote_control_ids ();
3051 } else if (PARAM_IS ("denormal-model")) {