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.
21 #define __STDC_FORMAT_MACROS 1
29 #include <sigc++/bind.h>
31 #include <cstdio> /* snprintf(3) ... grrr */
46 #include <sys/mount.h>
47 #include <sys/param.h>
52 #include <midi++/mmc.h>
53 #include <midi++/port.h>
54 #include <pbd/error.h>
56 #include <glibmm/thread.h>
57 #include <pbd/pathscanner.h>
58 #include <pbd/pthread_utils.h>
59 #include <pbd/strsplit.h>
61 #include <ardour/audioengine.h>
62 #include <ardour/configuration.h>
63 #include <ardour/session.h>
64 #include <ardour/buffer.h>
65 #include <ardour/audio_diskstream.h>
66 #include <ardour/midi_diskstream.h>
67 #include <ardour/utils.h>
68 #include <ardour/audioplaylist.h>
69 #include <ardour/midi_playlist.h>
70 #include <ardour/smf_source.h>
71 #include <ardour/audiofilesource.h>
72 #include <ardour/destructive_filesource.h>
73 #include <ardour/midi_source.h>
74 #include <ardour/sndfile_helpers.h>
75 #include <ardour/auditioner.h>
76 #include <ardour/export.h>
77 #include <ardour/redirect.h>
78 #include <ardour/send.h>
79 #include <ardour/insert.h>
80 #include <ardour/connection.h>
81 #include <ardour/slave.h>
82 #include <ardour/tempo.h>
83 #include <ardour/audio_track.h>
84 #include <ardour/midi_track.h>
85 #include <ardour/cycle_timer.h>
86 #include <ardour/utils.h>
87 #include <ardour/named_selection.h>
88 #include <ardour/version.h>
89 #include <ardour/location.h>
90 #include <ardour/audioregion.h>
91 #include <ardour/midi_region.h>
92 #include <ardour/crossfade.h>
93 #include <ardour/control_protocol_manager.h>
94 #include <ardour/region_factory.h>
95 #include <ardour/source_factory.h>
97 #include <control_protocol/control_protocol.h>
103 using namespace ARDOUR;
107 Session::first_stage_init (string fullpath, string snapshot_name)
109 if (fullpath.length() == 0) {
110 throw failed_constructor();
113 char buf[PATH_MAX+1];
114 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
115 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
116 throw failed_constructor();
121 if (_path[_path.length()-1] != '/') {
125 /* these two are just provisional settings. set_state()
126 will likely override them.
129 _name = _current_snapshot_name = snapshot_name;
131 _current_frame_rate = _engine.frame_rate ();
132 _tempo_map = new TempoMap (_current_frame_rate);
133 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
135 g_atomic_int_set (&processing_prohibited, 0);
138 _transport_speed = 0;
139 _last_transport_speed = 0;
140 transport_sub_state = 0;
141 _transport_frame = 0;
143 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
144 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
145 _end_location_is_free = true;
146 g_atomic_int_set (&_record_status, Disabled);
147 loop_changing = false;
149 _last_roll_location = 0;
150 _last_record_location = 0;
151 pending_locate_frame = 0;
152 pending_locate_roll = false;
153 pending_locate_flush = false;
154 dstream_buffer_size = 0;
156 state_was_pending = false;
158 outbound_mtc_smpte_frame = 0;
159 next_quarter_frame_to_send = -1;
160 current_block_size = 0;
161 solo_update_disabled = false;
162 currently_soloing = false;
163 _have_captured = false;
164 _worst_output_latency = 0;
165 _worst_input_latency = 0;
166 _worst_track_latency = 0;
167 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
169 butler_mixdown_buffer = 0;
170 butler_gain_buffer = 0;
172 session_send_mmc = false;
173 session_send_mtc = false;
174 post_transport_work = PostTransportWork (0);
175 g_atomic_int_set (&butler_should_do_transport_work, 0);
176 g_atomic_int_set (&butler_active, 0);
177 g_atomic_int_set (&_playback_load, 100);
178 g_atomic_int_set (&_capture_load, 100);
179 g_atomic_int_set (&_playback_load_min, 100);
180 g_atomic_int_set (&_capture_load_min, 100);
182 waiting_to_start = false;
184 _gain_automation_buffer = 0;
185 _pan_automation_buffer = 0;
187 pending_abort = false;
188 destructive_index = 0;
190 first_file_data_format_reset = true;
191 first_file_header_format_reset = true;
193 AudioDiskstream::allocate_working_buffers();
195 /* default short fade = 15ms */
197 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
198 DestructiveFileSource::setup_standard_crossfades (frame_rate());
200 last_mmc_step.tv_sec = 0;
201 last_mmc_step.tv_usec = 0;
204 /* click sounds are unset by default, which causes us to internal
205 waveforms for clicks.
209 click_emphasis_data = 0;
211 click_emphasis_length = 0;
214 process_function = &Session::process_with_events;
216 if (Config->get_use_video_sync()) {
217 waiting_for_sync_offset = true;
219 waiting_for_sync_offset = false;
222 _current_frame_rate = 48000;
223 _base_frame_rate = 48000;
227 _smpte_offset_negative = true;
228 last_smpte_valid = false;
232 last_rr_session_dir = session_dirs.begin();
233 refresh_disk_space ();
235 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
239 average_slave_delta = 1800;
240 have_first_delta_accumulator = false;
241 delta_accumulator_cnt = 0;
242 slave_state = Stopped;
244 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
246 /* These are all static "per-class" signals */
248 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
249 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
250 Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
251 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
252 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
253 Curve::CurveCreated.connect (mem_fun (*this, &Session::add_curve));
254 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
256 Controllable::GoingAway.connect (mem_fun (*this, &Session::remove_controllable));
258 IO::MoreChannels.connect (mem_fun (*this, &Session::ensure_buffers));
260 /* stop IO objects from doing stuff until we're ready for them */
262 IO::disable_panners ();
263 IO::disable_ports ();
264 IO::disable_connecting ();
268 Session::second_stage_init (bool new_session)
270 AudioFileSource::set_peak_dir (peak_dir());
273 if (load_state (_current_snapshot_name)) {
276 remove_empty_sounds ();
279 if (start_butler_thread()) {
283 /*if (start_midi_thread ()) {
287 // set_state() will call setup_raid_path(), but if it's a new session we need
288 // to call setup_raid_path() here.
290 if (set_state (*state_tree->root())) {
294 setup_raid_path(_path);
297 /* we can't save till after ::when_engine_running() is called,
298 because otherwise we save state with no connections made.
299 therefore, we reset _state_of_the_state because ::set_state()
300 will have cleared it.
302 we also have to include Loading so that any events that get
303 generated between here and the end of ::when_engine_running()
304 will be processed directly rather than queued.
307 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
309 // set_auto_input (true);
310 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
311 _locations.added.connect (mem_fun (this, &Session::locations_added));
312 setup_click_sounds (0);
313 setup_midi_control ();
315 /* Pay attention ... */
317 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
318 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
320 if (_engine.running()) {
321 when_engine_running();
323 first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
326 //send_full_time_code ();
327 _engine.transport_locate (0);
328 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
329 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
331 ControlProtocolManager::instance().set_session (*this);
334 _end_location_is_free = true;
336 _end_location_is_free = false;
343 Session::raid_path () const
347 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
352 return path.substr (0, path.length() - 1); // drop final colon
356 Session::setup_raid_path (string path)
358 string::size_type colon;
362 string::size_type len = path.length();
367 if (path.length() == 0) {
371 session_dirs.clear ();
373 for (string::size_type n = 0; n < len; ++n) {
374 if (path[n] == ':') {
381 /* no multiple search path, just one location (common case) */
385 session_dirs.push_back (sp);
392 if (fspath[fspath.length()-1] != '/') {
395 fspath += sound_dir (false);
397 AudioFileSource::set_search_path (fspath);
398 SMFSource::set_search_path (fspath); // FIXME: should be different
405 while ((colon = remaining.find_first_of (':')) != string::npos) {
408 sp.path = remaining.substr (0, colon);
409 session_dirs.push_back (sp);
411 /* add sounds to file search path */
414 if (fspath[fspath.length()-1] != '/') {
417 fspath += sound_dir (false);
420 remaining = remaining.substr (colon+1);
423 if (remaining.length()) {
430 if (fspath[fspath.length()-1] != '/') {
433 fspath += sound_dir (false);
436 session_dirs.push_back (sp);
439 /* set the AudioFileSource search path */
441 AudioFileSource::set_search_path (fspath);
442 SMFSource::set_search_path (fspath); // FIXME: should be different
444 /* reset the round-robin soundfile path thingie */
446 last_rr_session_dir = session_dirs.begin();
450 Session::create (bool& new_session, string* mix_template, nframes_t initial_length)
454 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
455 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
461 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
462 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
468 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
469 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
473 dir = dead_sound_dir ();
475 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
476 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
480 dir = automation_dir ();
482 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
483 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
488 /* check new_session so we don't overwrite an existing one */
491 std::string in_path = *mix_template;
493 ifstream in(in_path.c_str());
496 string out_path = _path;
498 out_path += _statefile_suffix;
500 ofstream out(out_path.c_str());
505 // okay, session is set up. Treat like normal saved
506 // session from now on.
512 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
518 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
525 /* set initial start + end point */
527 start_location->set_end (0);
528 _locations.add (start_location);
530 end_location->set_end (initial_length);
531 _locations.add (end_location);
533 _state_of_the_state = Clean;
535 if (save_state (_current_snapshot_name)) {
536 save_history (_current_snapshot_name);
544 Session::load_diskstreams (const XMLNode& node)
547 XMLNodeConstIterator citer;
549 clist = node.children();
551 for (citer = clist.begin(); citer != clist.end(); ++citer) {
554 /* diskstreams added automatically by DiskstreamCreated handler */
555 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
556 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
557 add_diskstream (dstream);
558 } else if ((*citer)->name() == "MidiDiskstream") {
559 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
560 add_diskstream (dstream);
562 error << _("Session: unknown diskstream type in XML") << endmsg;
566 catch (failed_constructor& err) {
567 error << _("Session: could not load diskstream via XML state") << endmsg;
576 Session::remove_pending_capture_state ()
581 xml_path += _current_snapshot_name;
582 xml_path += _pending_suffix;
584 unlink (xml_path.c_str());
588 Session::save_state (string snapshot_name, bool pending)
594 if (_state_of_the_state & CannotSave) {
598 tree.set_root (&get_state());
600 if (snapshot_name.empty()) {
601 snapshot_name = _current_snapshot_name;
607 xml_path += snapshot_name;
608 xml_path += _statefile_suffix;
612 // Make backup of state file
614 if ((access (xml_path.c_str(), F_OK) == 0) &&
615 (rename(xml_path.c_str(), bak_path.c_str()))) {
616 error << _("could not backup old state file, current state not saved.") << endmsg;
623 xml_path += snapshot_name;
624 xml_path += _pending_suffix;
628 cerr << "actually writing state\n";
630 if (!tree.write (xml_path)) {
631 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
633 /* don't leave a corrupt file lying around if it is
637 if (unlink (xml_path.c_str())) {
638 error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
641 if (rename (bak_path.c_str(), xml_path.c_str())) {
642 error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
651 save_history(snapshot_name);
653 bool was_dirty = dirty();
655 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
658 DirtyChanged (); /* EMIT SIGNAL */
661 StateSaved (snapshot_name); /* EMIT SIGNAL */
668 Session::restore_state (string snapshot_name)
670 if (load_state (snapshot_name) == 0) {
671 set_state (*state_tree->root());
678 Session::load_state (string snapshot_name)
687 state_was_pending = false;
689 /* check for leftover pending state from a crashed capture attempt */
692 xmlpath += snapshot_name;
693 xmlpath += _pending_suffix;
695 if (!access (xmlpath.c_str(), F_OK)) {
697 /* there is pending state from a crashed capture attempt */
699 if (AskAboutPendingState()) {
700 state_was_pending = true;
704 if (!state_was_pending) {
707 xmlpath += snapshot_name;
708 xmlpath += _statefile_suffix;
711 if (access (xmlpath.c_str(), F_OK)) {
712 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
716 state_tree = new XMLTree;
720 if (state_tree->read (xmlpath)) {
723 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
732 Session::load_options (const XMLNode& node)
736 LocaleGuard lg (X_("POSIX"));
738 Config->set_variables (node, ConfigVariableBase::Session);
740 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
741 if ((prop = child->property ("val")) != 0) {
742 _end_location_is_free = (prop->value() == "yes");
750 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
752 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
753 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
755 return owner & modified_by_session_or_user;
759 Session::get_options () const
762 LocaleGuard lg (X_("POSIX"));
764 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
766 child = option_root.add_child ("end-marker-is-free");
767 child->add_property ("val", _end_location_is_free ? "yes" : "no");
779 Session::get_template()
781 /* if we don't disable rec-enable, diskstreams
782 will believe they need to store their capture
783 sources in their state node.
786 disable_record (false);
792 Session::state(bool full_state)
794 XMLNode* node = new XMLNode("Session");
797 // store libardour version, just in case
799 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
800 libardour_major_version, libardour_minor_version, libardour_micro_version);
801 node->add_property("version", string(buf));
803 /* store configuration settings */
808 node->add_property ("name", _name);
810 if (session_dirs.size() > 1) {
814 vector<space_and_path>::iterator i = session_dirs.begin();
815 vector<space_and_path>::iterator next;
817 ++i; /* skip the first one */
821 while (i != session_dirs.end()) {
825 if (next != session_dirs.end()) {
835 child = node->add_child ("Path");
836 child->add_content (p);
840 /* save the ID counter */
842 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
843 node->add_property ("id-counter", buf);
845 /* various options */
847 node->add_child_nocopy (get_options());
849 child = node->add_child ("Sources");
852 Glib::Mutex::Lock sl (source_lock);
854 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
856 /* Don't save information about AudioFileSources that are empty */
858 boost::shared_ptr<AudioFileSource> fs;
860 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
861 boost::shared_ptr<DestructiveFileSource> dfs = boost::dynamic_pointer_cast<DestructiveFileSource> (fs);
863 /* Don't save sources that are empty, unless they're destructive (which are OK
864 if they are empty, because we will re-use them every time.)
866 if ( ! dfs && siter->second->length() == 0) {
871 child->add_child_nocopy (siter->second->get_state());
875 child = node->add_child ("Regions");
878 Glib::Mutex::Lock rl (region_lock);
880 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
882 /* only store regions not attached to playlists */
884 if (i->second->playlist() == 0) {
885 child->add_child_nocopy (i->second->state (true));
890 child = node->add_child ("DiskStreams");
893 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
894 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
895 if (!(*i)->hidden()) {
896 child->add_child_nocopy ((*i)->get_state());
901 node->add_child_nocopy (_locations.get_state());
903 child = node->add_child ("Connections");
905 Glib::Mutex::Lock lm (connection_lock);
906 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
907 if (!(*i)->system_dependent()) {
908 child->add_child_nocopy ((*i)->get_state());
913 child = node->add_child ("Routes");
915 boost::shared_ptr<RouteList> r = routes.reader ();
917 RoutePublicOrderSorter cmp;
918 RouteList public_order (*r);
919 public_order.sort (cmp);
921 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
922 if (!(*i)->hidden()) {
924 child->add_child_nocopy ((*i)->get_state());
926 child->add_child_nocopy ((*i)->get_template());
933 child = node->add_child ("EditGroups");
934 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
935 child->add_child_nocopy ((*i)->get_state());
938 child = node->add_child ("MixGroups");
939 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
940 child->add_child_nocopy ((*i)->get_state());
943 child = node->add_child ("Playlists");
944 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
945 if (!(*i)->hidden()) {
946 if (!(*i)->empty()) {
948 child->add_child_nocopy ((*i)->get_state());
950 child->add_child_nocopy ((*i)->get_template());
956 child = node->add_child ("UnusedPlaylists");
957 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
958 if (!(*i)->hidden()) {
959 if (!(*i)->empty()) {
961 child->add_child_nocopy ((*i)->get_state());
963 child->add_child_nocopy ((*i)->get_template());
971 child = node->add_child ("Click");
972 child->add_child_nocopy (_click_io->state (full_state));
976 child = node->add_child ("NamedSelections");
977 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
979 child->add_child_nocopy ((*i)->get_state());
984 node->add_child_nocopy (_tempo_map->get_state());
986 node->add_child_nocopy (get_control_protocol_state());
989 node->add_child_copy (*_extra_xml);
996 Session::get_control_protocol_state ()
998 ControlProtocolManager& cpm (ControlProtocolManager::instance());
999 XMLNode* node = new XMLNode (X_("ControlProtocols"));
1001 cpm.foreach_known_protocol (bind (mem_fun (*this, &Session::add_control_protocol), node));
1007 Session::add_control_protocol (const ControlProtocolInfo* const cpi, XMLNode* node)
1009 if (cpi->protocol) {
1010 node->add_child_nocopy (cpi->protocol->get_state());
1015 Session::set_state (const XMLNode& node)
1019 const XMLProperty* prop;
1022 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1024 if (node.name() != X_("Session")){
1025 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1029 StateManager::prohibit_save ();
1031 if ((prop = node.property ("name")) != 0) {
1032 _name = prop->value ();
1035 setup_raid_path(_path);
1037 if ((prop = node.property (X_("id-counter"))) != 0) {
1039 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1040 ID::init_counter (x);
1042 /* old sessions used a timebased counter, so fake
1043 the startup ID counter based on a standard
1048 ID::init_counter (now);
1052 IO::disable_ports ();
1053 IO::disable_connecting ();
1055 /* Object loading order:
1073 if (use_config_midi_ports ()) {
1076 if ((child = find_named_node (node, "extra")) != 0) {
1077 _extra_xml = new XMLNode (*child);
1080 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1081 load_options (*child);
1082 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1083 load_options (*child);
1085 error << _("Session: XML state has no options section") << endmsg;
1088 if ((child = find_named_node (node, "Sources")) == 0) {
1089 error << _("Session: XML state has no sources section") << endmsg;
1091 } else if (load_sources (*child)) {
1095 if ((child = find_named_node (node, "Regions")) == 0) {
1096 error << _("Session: XML state has no Regions section") << endmsg;
1098 } else if (load_regions (*child)) {
1102 if ((child = find_named_node (node, "Playlists")) == 0) {
1103 error << _("Session: XML state has no playlists section") << endmsg;
1105 } else if (load_playlists (*child)) {
1109 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1111 } else if (load_unused_playlists (*child)) {
1115 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1116 if (load_named_selections (*child)) {
1121 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1122 error << _("Session: XML state has no diskstreams section") << endmsg;
1124 } else if (load_diskstreams (*child)) {
1128 if ((child = find_named_node (node, "Connections")) == 0) {
1129 error << _("Session: XML state has no connections section") << endmsg;
1131 } else if (load_connections (*child)) {
1135 if ((child = find_named_node (node, "Locations")) == 0) {
1136 error << _("Session: XML state has no locations section") << endmsg;
1138 } else if (_locations.set_state (*child)) {
1144 if ((location = _locations.auto_loop_location()) != 0) {
1145 set_auto_loop_location (location);
1148 if ((location = _locations.auto_punch_location()) != 0) {
1149 set_auto_punch_location (location);
1152 if ((location = _locations.end_location()) == 0) {
1153 _locations.add (end_location);
1155 delete end_location;
1156 end_location = location;
1159 if ((location = _locations.start_location()) == 0) {
1160 _locations.add (start_location);
1162 delete start_location;
1163 start_location = location;
1166 _locations.save_state (_("initial state"));
1168 if ((child = find_named_node (node, "EditGroups")) == 0) {
1169 error << _("Session: XML state has no edit groups section") << endmsg;
1171 } else if (load_edit_groups (*child)) {
1175 if ((child = find_named_node (node, "MixGroups")) == 0) {
1176 error << _("Session: XML state has no mix groups section") << endmsg;
1178 } else if (load_mix_groups (*child)) {
1182 if ((child = find_named_node (node, "TempoMap")) == 0) {
1183 error << _("Session: XML state has no Tempo Map section") << endmsg;
1185 } else if (_tempo_map->set_state (*child)) {
1189 if ((child = find_named_node (node, "Routes")) == 0) {
1190 error << _("Session: XML state has no routes section") << endmsg;
1192 } else if (load_routes (*child)) {
1196 if ((child = find_named_node (node, "Click")) == 0) {
1197 warning << _("Session: XML state has no click section") << endmsg;
1198 } else if (_click_io) {
1199 _click_io->set_state (*child);
1202 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1203 ControlProtocolManager::instance().set_protocol_states (*child);
1206 /* here beginneth the second phase ... */
1208 StateReady (); /* EMIT SIGNAL */
1210 _state_of_the_state = Clean;
1212 StateManager::allow_save (_("initial state"), true);
1214 if (state_was_pending) {
1215 save_state (_current_snapshot_name);
1216 remove_pending_capture_state ();
1217 state_was_pending = false;
1223 /* we failed, re-enable state saving but don't actually save internal state */
1224 StateManager::allow_save (X_("ignored"), false);
1229 Session::load_routes (const XMLNode& node)
1232 XMLNodeConstIterator niter;
1233 RouteList new_routes;
1235 nlist = node.children();
1239 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1241 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1244 error << _("Session: cannot create Route from XML description.") << endmsg;
1248 new_routes.push_back (route);
1251 add_routes (new_routes);
1256 boost::shared_ptr<Route>
1257 Session::XMLRouteFactory (const XMLNode& node)
1259 if (node.name() != "Route") {
1260 return boost::shared_ptr<Route> ((Route*) 0);
1263 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1265 DataType type = DataType::AUDIO;
1266 const XMLProperty* prop = node.property("default-type");
1268 type = DataType(prop->value());
1270 assert(type != DataType::NIL);
1272 if (has_diskstream) {
1273 if (type == DataType::AUDIO) {
1274 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1277 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1281 boost::shared_ptr<Route> ret (new Route (*this, node));
1287 Session::load_regions (const XMLNode& node)
1290 XMLNodeConstIterator niter;
1291 boost::shared_ptr<Region> region;
1293 nlist = node.children();
1297 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1298 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1299 error << _("Session: cannot create Region from XML description.") << endmsg;
1306 boost::shared_ptr<Region>
1307 Session::XMLRegionFactory (const XMLNode& node, bool full)
1309 const XMLProperty* type = node.property("type");
1313 if ( !type || type->value() == "audio" ) {
1315 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1317 } else if (type->value() == "midi") {
1319 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1323 } catch (failed_constructor& err) {
1324 return boost::shared_ptr<Region> ();
1327 return boost::shared_ptr<Region> ();
1330 boost::shared_ptr<AudioRegion>
1331 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1333 const XMLProperty* prop;
1334 boost::shared_ptr<Source> source;
1335 boost::shared_ptr<AudioSource> as;
1337 uint32_t nchans = 1;
1340 if (node.name() != X_("Region")) {
1341 return boost::shared_ptr<AudioRegion>();
1344 if ((prop = node.property (X_("channels"))) != 0) {
1345 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)));
1404 catch (failed_constructor& err) {
1405 return boost::shared_ptr<AudioRegion>();
1409 boost::shared_ptr<MidiRegion>
1410 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1412 const XMLProperty* prop;
1413 boost::shared_ptr<Source> source;
1414 boost::shared_ptr<MidiSource> ms;
1415 MidiRegion::SourceList sources;
1416 uint32_t nchans = 1;
1418 if (node.name() != X_("Region")) {
1419 return boost::shared_ptr<MidiRegion>();
1422 if ((prop = node.property (X_("channels"))) != 0) {
1423 nchans = atoi (prop->value().c_str());
1426 // Multiple midi channels? that's just crazy talk
1427 assert(nchans == 1);
1429 if ((prop = node.property (X_("source-0"))) == 0) {
1430 if ((prop = node.property ("source")) == 0) {
1431 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1432 return boost::shared_ptr<MidiRegion>();
1436 PBD::ID s_id (prop->value());
1438 if ((source = source_by_id (s_id)) == 0) {
1439 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1440 return boost::shared_ptr<MidiRegion>();
1443 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1445 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1446 return boost::shared_ptr<MidiRegion>();
1449 sources.push_back (ms);
1452 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1456 catch (failed_constructor& err) {
1457 return boost::shared_ptr<MidiRegion>();
1462 Session::get_sources_as_xml ()
1465 XMLNode* node = new XMLNode (X_("Sources"));
1466 Glib::Mutex::Lock lm (source_lock);
1468 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1469 node->add_child_nocopy (i->second->get_state());
1472 /* XXX get MIDI and other sources here */
1478 Session::path_from_region_name (string name, string identifier)
1480 char buf[PATH_MAX+1];
1482 string dir = discover_best_sound_dir ();
1484 for (n = 0; n < 999999; ++n) {
1485 if (identifier.length()) {
1486 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1487 identifier.c_str(), n);
1489 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1491 if (access (buf, F_OK) != 0) {
1501 Session::load_sources (const XMLNode& node)
1504 XMLNodeConstIterator niter;
1505 boost::shared_ptr<Source> source;
1507 nlist = node.children();
1511 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1513 if ((source = XMLSourceFactory (**niter)) == 0) {
1514 error << _("Session: cannot create Source from XML description.") << endmsg;
1521 boost::shared_ptr<Source>
1522 Session::XMLSourceFactory (const XMLNode& node)
1524 if (node.name() != "Source") {
1525 return boost::shared_ptr<Source>();
1529 return SourceFactory::create (*this, node);
1532 catch (failed_constructor& err) {
1533 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1534 return boost::shared_ptr<Source>();
1539 Session::save_template (string template_name)
1542 string xml_path, bak_path, template_path;
1544 if (_state_of_the_state & CannotSave) {
1549 string dir = template_dir();
1551 if ((dp = opendir (dir.c_str()))) {
1554 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1555 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1560 tree.set_root (&get_template());
1563 xml_path += template_name;
1564 xml_path += _template_suffix;
1566 ifstream in(xml_path.c_str());
1569 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1575 if (!tree.write (xml_path)) {
1576 error << _("mix template not saved") << endmsg;
1584 Session::rename_template (string old_name, string new_name)
1586 string old_path = template_dir() + old_name + _template_suffix;
1587 string new_path = template_dir() + new_name + _template_suffix;
1589 return rename (old_path.c_str(), new_path.c_str());
1593 Session::delete_template (string name)
1595 string template_path = template_dir();
1596 template_path += name;
1597 template_path += _template_suffix;
1599 return remove (template_path.c_str());
1603 Session::refresh_disk_space ()
1606 struct statfs statfsbuf;
1607 vector<space_and_path>::iterator i;
1608 Glib::Mutex::Lock lm (space_lock);
1611 /* get freespace on every FS that is part of the session path */
1613 _total_free_4k_blocks = 0;
1615 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1616 statfs ((*i).path.c_str(), &statfsbuf);
1618 scale = statfsbuf.f_bsize/4096.0;
1620 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1621 _total_free_4k_blocks += (*i).blocks;
1627 Session::ensure_sound_dir (string path, string& result)
1632 /* Ensure that the parent directory exists */
1634 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1635 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1639 /* Ensure that the sounds directory exists */
1643 result += sound_dir_name;
1645 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1646 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1652 dead += dead_sound_dir_name;
1654 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1655 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1661 peak += peak_dir_name;
1663 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1664 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1668 /* callers expect this to be terminated ... */
1675 Session::discover_best_sound_dir (bool destructive)
1677 vector<space_and_path>::iterator i;
1680 /* handle common case without system calls */
1682 if (session_dirs.size() == 1) {
1686 /* OK, here's the algorithm we're following here:
1688 We want to select which directory to use for
1689 the next file source to be created. Ideally,
1690 we'd like to use a round-robin process so as to
1691 get maximum performance benefits from splitting
1692 the files across multiple disks.
1694 However, in situations without much diskspace, an
1695 RR approach may end up filling up a filesystem
1696 with new files while others still have space.
1697 Its therefore important to pay some attention to
1698 the freespace in the filesystem holding each
1699 directory as well. However, if we did that by
1700 itself, we'd keep creating new files in the file
1701 system with the most space until it was as full
1702 as all others, thus negating any performance
1703 benefits of this RAID-1 like approach.
1705 So, we use a user-configurable space threshold. If
1706 there are at least 2 filesystems with more than this
1707 much space available, we use RR selection between them.
1708 If not, then we pick the filesystem with the most space.
1710 This gets a good balance between the two
1714 refresh_disk_space ();
1716 int free_enough = 0;
1718 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1719 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1724 if (free_enough >= 2) {
1726 bool found_it = false;
1728 /* use RR selection process, ensuring that the one
1732 i = last_rr_session_dir;
1735 if (++i == session_dirs.end()) {
1736 i = session_dirs.begin();
1739 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1740 if (ensure_sound_dir ((*i).path, result) == 0) {
1741 last_rr_session_dir = i;
1747 } while (i != last_rr_session_dir);
1750 result = sound_dir();
1755 /* pick FS with the most freespace (and that
1756 seems to actually work ...)
1759 vector<space_and_path> sorted;
1760 space_and_path_ascending_cmp cmp;
1762 sorted = session_dirs;
1763 sort (sorted.begin(), sorted.end(), cmp);
1765 for (i = sorted.begin(); i != sorted.end(); ++i) {
1766 if (ensure_sound_dir ((*i).path, result) == 0) {
1767 last_rr_session_dir = i;
1772 /* if the above fails, fall back to the most simplistic solution */
1774 if (i == sorted.end()) {
1783 Session::load_playlists (const XMLNode& node)
1786 XMLNodeConstIterator niter;
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;
1804 Session::load_unused_playlists (const XMLNode& node)
1807 XMLNodeConstIterator niter;
1810 nlist = node.children();
1814 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1816 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1817 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1821 // now manually untrack it
1823 track_playlist (playlist, false);
1830 Session::XMLPlaylistFactory (const XMLNode& node)
1832 const XMLProperty* type = node.property("type");
1836 if ( !type || type->value() == "audio" ) {
1838 return new AudioPlaylist (*this, node);
1840 } else if (type->value() == "midi") {
1842 return new MidiPlaylist (*this, node);
1846 } catch (failed_constructor& err) {
1854 Session::load_named_selections (const XMLNode& node)
1857 XMLNodeConstIterator niter;
1860 nlist = node.children();
1864 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1866 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1867 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1875 Session::XMLNamedSelectionFactory (const XMLNode& node)
1878 return new NamedSelection (*this, node);
1881 catch (failed_constructor& err) {
1887 Session::dead_sound_dir () const
1890 res += dead_sound_dir_name;
1896 Session::sound_dir (bool with_path) const
1898 /* support old session structure */
1900 struct stat statbuf;
1902 string old_withpath;
1904 old_nopath += old_sound_dir_name;
1907 old_withpath = _path;
1908 old_withpath += old_sound_dir_name;
1909 old_withpath += '/';
1911 if (stat (old_withpath.c_str(), &statbuf) == 0) {
1913 return old_withpath;
1924 res += interchange_dir_name;
1926 res += legalize_for_path (_name);
1928 res += sound_dir_name;
1935 Session::peak_dir () const
1938 res += peak_dir_name;
1944 Session::automation_dir () const
1947 res += "automation/";
1952 Session::template_dir ()
1954 string path = get_user_ardour_path();
1955 path += "templates/";
1961 Session::suffixed_search_path (string suffix, bool data)
1965 path += get_user_ardour_path();
1966 if (path[path.length()-1] != ':') {
1971 path += get_system_data_path();
1973 path += get_system_module_path();
1976 vector<string> split_path;
1978 split (path, split_path, ':');
1981 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
1986 if (distance (i, split_path.end()) != 1) {
1995 Session::template_path ()
1997 return suffixed_search_path (X_("templates"), true);
2001 Session::control_protocol_path ()
2003 return suffixed_search_path (X_("surfaces"), false);
2007 Session::load_connections (const XMLNode& node)
2009 XMLNodeList nlist = node.children();
2010 XMLNodeConstIterator niter;
2014 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2015 if ((*niter)->name() == "InputConnection") {
2016 add_connection (new ARDOUR::InputConnection (**niter));
2017 } else if ((*niter)->name() == "OutputConnection") {
2018 add_connection (new ARDOUR::OutputConnection (**niter));
2020 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2029 Session::load_edit_groups (const XMLNode& node)
2031 return load_route_groups (node, true);
2035 Session::load_mix_groups (const XMLNode& node)
2037 return load_route_groups (node, false);
2041 Session::load_route_groups (const XMLNode& node, bool edit)
2043 XMLNodeList nlist = node.children();
2044 XMLNodeConstIterator niter;
2049 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2050 if ((*niter)->name() == "RouteGroup") {
2052 rg = add_edit_group ("");
2053 rg->set_state (**niter);
2055 rg = add_mix_group ("");
2056 rg->set_state (**niter);
2065 state_file_filter (const string &str, void *arg)
2067 return (str.length() > strlen(Session::statefile_suffix()) &&
2068 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2072 bool operator()(const string* a, const string* b) {
2078 remove_end(string* state)
2080 string statename(*state);
2082 string::size_type start,end;
2083 if ((start = statename.find_last_of ('/')) != string::npos) {
2084 statename = statename.substr (start+1);
2087 if ((end = statename.rfind(".ardour")) == string::npos) {
2088 end = statename.length();
2091 return new string(statename.substr (0, end));
2095 Session::possible_states (string path)
2097 PathScanner scanner;
2098 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2100 transform(states->begin(), states->end(), states->begin(), remove_end);
2103 sort (states->begin(), states->end(), cmp);
2109 Session::possible_states () const
2111 return possible_states(_path);
2115 Session::auto_save()
2117 save_state (_current_snapshot_name);
2121 Session::add_edit_group (string name)
2123 RouteGroup* rg = new RouteGroup (*this, name);
2124 edit_groups.push_back (rg);
2125 edit_group_added (rg); /* EMIT SIGNAL */
2131 Session::add_mix_group (string name)
2133 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2134 mix_groups.push_back (rg);
2135 mix_group_added (rg); /* EMIT SIGNAL */
2141 Session::remove_edit_group (RouteGroup& rg)
2143 list<RouteGroup*>::iterator i;
2145 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2146 (*i)->apply (&Route::drop_edit_group, this);
2147 edit_groups.erase (i);
2148 edit_group_removed (); /* EMIT SIGNAL */
2155 Session::remove_mix_group (RouteGroup& rg)
2157 list<RouteGroup*>::iterator i;
2159 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2160 (*i)->apply (&Route::drop_mix_group, this);
2161 mix_groups.erase (i);
2162 mix_group_removed (); /* EMIT SIGNAL */
2169 Session::mix_group_by_name (string name)
2171 list<RouteGroup *>::iterator i;
2173 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2174 if ((*i)->name() == name) {
2182 Session::edit_group_by_name (string name)
2184 list<RouteGroup *>::iterator i;
2186 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2187 if ((*i)->name() == name) {
2195 Session::begin_reversible_command (string name)
2197 current_trans = new UndoTransaction;
2198 current_trans->set_name (name);
2202 Session::commit_reversible_command (Command *cmd)
2207 current_trans->add_command (cmd);
2210 gettimeofday (&now, 0);
2211 current_trans->set_timestamp (now);
2213 history.add (current_trans);
2216 Session::GlobalRouteBooleanState
2217 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2219 GlobalRouteBooleanState s;
2220 boost::shared_ptr<RouteList> r = routes.reader ();
2222 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2223 if (!(*i)->hidden()) {
2224 RouteBooleanState v;
2227 Route* r = (*i).get();
2228 v.second = (r->*method)();
2237 Session::GlobalRouteMeterState
2238 Session::get_global_route_metering ()
2240 GlobalRouteMeterState s;
2241 boost::shared_ptr<RouteList> r = routes.reader ();
2243 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2244 if (!(*i)->hidden()) {
2248 v.second = (*i)->meter_point();
2258 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2260 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2261 i->first->set_meter_point (i->second, arg);
2266 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2268 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2269 Route* r = i->first.get();
2270 (r->*method) (i->second, arg);
2275 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2277 set_global_route_boolean (s, &Route::set_mute, src);
2281 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2283 set_global_route_boolean (s, &Route::set_solo, src);
2287 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2289 set_global_route_boolean (s, &Route::set_record_enable, src);
2294 Session::global_mute_memento (void* src)
2296 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2300 Session::global_metering_memento (void* src)
2302 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2306 Session::global_solo_memento (void* src)
2308 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2312 Session::global_record_enable_memento (void* src)
2314 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2319 template_filter (const string &str, void *arg)
2321 return (str.length() > strlen(Session::template_suffix()) &&
2322 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2326 Session::get_template_list (list<string> &template_names)
2328 vector<string *> *templates;
2329 PathScanner scanner;
2332 path = template_path ();
2334 templates = scanner (path, template_filter, 0, false, true);
2336 vector<string*>::iterator i;
2337 for (i = templates->begin(); i != templates->end(); ++i) {
2338 string fullpath = *(*i);
2341 start = fullpath.find_last_of ('/') + 1;
2342 if ((end = fullpath.find_last_of ('.')) <0) {
2343 end = fullpath.length();
2346 template_names.push_back(fullpath.substr(start, (end-start)));
2351 Session::read_favorite_dirs (FavoriteDirs & favs)
2353 string path = get_user_ardour_path();
2354 path += "/favorite_dirs";
2356 ifstream fav (path.c_str());
2361 if (errno != ENOENT) {
2362 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2373 getline(fav, newfav);
2379 favs.push_back (newfav);
2386 Session::write_favorite_dirs (FavoriteDirs & favs)
2388 string path = get_user_ardour_path();
2389 path += "/favorite_dirs";
2391 ofstream fav (path.c_str());
2397 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2398 fav << (*i) << endl;
2405 accept_all_non_peak_files (const string& path, void *arg)
2407 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2411 accept_all_state_files (const string& path, void *arg)
2413 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2417 Session::find_all_sources (string path, set<string>& result)
2422 if (!tree.read (path)) {
2426 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2431 XMLNodeConstIterator niter;
2433 nlist = node->children();
2437 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2441 if ((prop = (*niter)->property (X_("name"))) == 0) {
2445 if (prop->value()[0] == '/') {
2446 /* external file, ignore */
2450 string path = _path; /* /-terminated */
2451 path += sound_dir_name;
2453 path += prop->value();
2455 result.insert (path);
2462 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2464 PathScanner scanner;
2465 vector<string*>* state_files;
2467 string this_snapshot_path;
2473 if (ripped[ripped.length()-1] == '/') {
2474 ripped = ripped.substr (0, ripped.length() - 1);
2477 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2479 if (state_files == 0) {
2484 this_snapshot_path = _path;
2485 this_snapshot_path += _current_snapshot_name;
2486 this_snapshot_path += _statefile_suffix;
2488 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2490 if (exclude_this_snapshot && **i == this_snapshot_path) {
2494 if (find_all_sources (**i, result) < 0) {
2503 Session::cleanup_sources (Session::cleanup_report& rep)
2505 vector<boost::shared_ptr<Source> > dead_sources;
2506 vector<Playlist*> playlists_tbd;
2507 PathScanner scanner;
2509 vector<space_and_path>::iterator i;
2510 vector<space_and_path>::iterator nexti;
2511 vector<string*>* soundfiles;
2512 vector<string> unused;
2513 set<string> all_sources;
2518 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2520 /* step 1: consider deleting all unused playlists */
2522 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2525 status = AskAboutPlaylistDeletion (*x);
2534 playlists_tbd.push_back (*x);
2538 /* leave it alone */
2543 /* now delete any that were marked for deletion */
2545 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2546 PlaylistList::iterator foo;
2548 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2549 unused_playlists.erase (foo);
2554 /* step 2: clear the undo/redo history for all playlists */
2556 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2557 (*x)->drop_all_states ();
2560 /* step 3: find all un-referenced sources */
2565 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2567 SourceMap::iterator tmp;
2572 /* only remove files that are not in use and have some size
2573 to them. otherwise we remove the current "nascent"
2577 if (i->second.use_count() == 1 && i->second->length() > 0) {
2578 dead_sources.push_back (i->second);
2580 /* remove this source from our own list to avoid us
2581 adding it to the list of all sources below
2590 /* Step 4: get rid of all regions in the region list that use any dead sources
2591 in case the sources themselves don't go away (they might be referenced in
2595 for (vector<boost::shared_ptr<Source> >::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2597 for (RegionList::iterator r = regions.begin(); r != regions.end(); ) {
2598 RegionList::iterator tmp;
2603 boost::shared_ptr<Region> reg = r->second;
2605 for (uint32_t n = 0; n < reg->n_channels(); ++n) {
2606 if (reg->source (n) == (*i)) {
2607 /* this region is dead */
2608 remove_region (reg);
2616 /* build a list of all the possible sound directories for the session */
2618 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2623 sound_path += (*i).path;
2624 sound_path += sound_dir_name;
2626 if (nexti != session_dirs.end()) {
2633 /* now do the same thing for the files that ended up in the sounds dir(s)
2634 but are not referenced as sources in any snapshot.
2637 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2639 if (soundfiles == 0) {
2643 /* find all sources, but don't use this snapshot because the
2644 state file on disk still references sources we may have already
2648 find_all_sources_across_snapshots (all_sources, true);
2650 /* add our current source list
2653 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2654 boost::shared_ptr<AudioFileSource> fs;
2656 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2657 all_sources.insert (fs->path());
2661 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2666 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2676 unused.push_back (spath);
2680 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2682 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2683 struct stat statbuf;
2685 rep.paths.push_back (*x);
2686 if (stat ((*x).c_str(), &statbuf) == 0) {
2687 rep.space += statbuf.st_size;
2692 /* don't move the file across filesystems, just
2693 stick it in the `dead_sound_dir_name' directory
2694 on whichever filesystem it was already on.
2697 newpath = Glib::path_get_dirname (*x);
2698 newpath = Glib::path_get_dirname (newpath);
2701 newpath += dead_sound_dir_name;
2703 newpath += Glib::path_get_basename ((*x));
2705 if (access (newpath.c_str(), F_OK) == 0) {
2707 /* the new path already exists, try versioning */
2709 char buf[PATH_MAX+1];
2713 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2716 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2717 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2721 if (version == 999) {
2722 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2726 newpath = newpath_v;
2731 /* it doesn't exist, or we can't read it or something */
2735 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2736 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2737 (*x), newpath, strerror (errno))
2743 /* see if there an easy to find peakfile for this file, and remove it.
2746 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2747 peakpath += ".peak";
2749 if (access (peakpath.c_str(), W_OK) == 0) {
2750 if (::unlink (peakpath.c_str()) != 0) {
2751 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2752 peakpath, _path, strerror (errno))
2754 /* try to back out */
2755 rename (newpath.c_str(), _path.c_str());
2764 /* dump the history list */
2768 /* save state so we don't end up a session file
2769 referring to non-existent sources.
2775 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2780 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2782 vector<space_and_path>::iterator i;
2783 string dead_sound_dir;
2784 struct dirent* dentry;
2785 struct stat statbuf;
2791 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2793 dead_sound_dir = (*i).path;
2794 dead_sound_dir += dead_sound_dir_name;
2796 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2800 while ((dentry = readdir (dead)) != 0) {
2802 /* avoid '.' and '..' */
2804 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2805 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2811 fullpath = dead_sound_dir;
2813 fullpath += dentry->d_name;
2815 if (stat (fullpath.c_str(), &statbuf)) {
2819 if (!S_ISREG (statbuf.st_mode)) {
2823 if (unlink (fullpath.c_str())) {
2824 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2825 fullpath, strerror (errno))
2829 rep.paths.push_back (dentry->d_name);
2830 rep.space += statbuf.st_size;
2841 Session::set_dirty ()
2843 bool was_dirty = dirty();
2845 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2848 DirtyChanged(); /* EMIT SIGNAL */
2854 Session::set_clean ()
2856 bool was_dirty = dirty();
2858 _state_of_the_state = Clean;
2861 DirtyChanged(); /* EMIT SIGNAL */
2866 Session::add_controllable (Controllable* c)
2868 Glib::Mutex::Lock lm (controllables_lock);
2869 controllables.insert (c);
2873 Session::remove_controllable (Controllable* c)
2875 if (_state_of_the_state | Deletion) {
2879 Glib::Mutex::Lock lm (controllables_lock);
2881 Controllables::iterator x = controllables.find (c);
2883 if (x != controllables.end()) {
2884 controllables.erase (x);
2889 Session::controllable_by_id (const PBD::ID& id)
2891 Glib::Mutex::Lock lm (controllables_lock);
2893 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2894 if ((*i)->id() == id) {
2903 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2905 Stateful::add_instant_xml (node, dir);
2906 Config->add_instant_xml (node, get_user_ardour_path());
2911 Session::save_history (string snapshot_name)
2917 tree.set_root (&history.get_state());
2919 if (snapshot_name.empty()) {
2920 snapshot_name = _current_snapshot_name;
2923 xml_path = _path + snapshot_name + ".history";
2925 bak_path = xml_path + ".bak";
2927 if ((access (xml_path.c_str(), F_OK) == 0) &&
2928 (rename (xml_path.c_str(), bak_path.c_str())))
2930 error << _("could not backup old history file, current history not saved.") << endmsg;
2934 cerr << "actually writing history\n";
2936 if (!tree.write (xml_path))
2938 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2940 /* don't leave a corrupt file lying around if it is
2944 if (unlink (xml_path.c_str()))
2946 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2948 if (rename (bak_path.c_str(), xml_path.c_str()))
2950 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2961 Session::restore_history (string snapshot_name)
2967 xmlpath = _path + snapshot_name + ".history";
2968 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2970 if (access (xmlpath.c_str(), F_OK)) {
2971 error << string_compose(_("%1: session history file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
2975 if (!tree.read (xmlpath)) {
2976 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
2980 /* replace history */
2982 for (XMLNodeConstIterator it = tree.root()->children().begin();
2983 it != tree.root()->children().end();
2987 UndoTransaction* ut = new UndoTransaction ();
2990 ut->set_name(t->property("name")->value());
2991 stringstream ss(t->property("tv_sec")->value());
2993 ss.str(t->property("tv_usec")->value());
2995 ut->set_timestamp(tv);
2997 for (XMLNodeConstIterator child_it = t->children().begin();
2998 child_it != t->children().end();
3001 XMLNode *n = *child_it;
3003 if (n->name() == "MementoCommand" ||
3004 n->name() == "MementoUndoCommand" ||
3005 n->name() == "MementoRedoCommand")
3007 c = memento_command_factory(n);
3013 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3023 Session::config_changed (const char* parameter_name)
3025 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3027 if (PARAM_IS ("seamless-loop")) {
3029 } else if (PARAM_IS ("rf-speed")) {
3031 } else if (PARAM_IS ("auto-loop")) {
3033 } else if (PARAM_IS ("auto-input")) {
3035 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3036 /* auto-input only makes a difference if we're rolling */
3038 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3040 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3041 if ((*i)->record_enabled ()) {
3042 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
3043 (*i)->monitor_input (!Config->get_auto_input());
3048 } else if (PARAM_IS ("punch-in")) {
3052 if ((location = _locations.auto_punch_location()) != 0) {
3054 if (Config->get_punch_in ()) {
3055 replace_event (Event::PunchIn, location->start());
3057 remove_event (location->start(), Event::PunchIn);
3061 } else if (PARAM_IS ("punch-out")) {
3065 if ((location = _locations.auto_punch_location()) != 0) {
3067 if (Config->get_punch_out()) {
3068 replace_event (Event::PunchOut, location->end());
3070 clear_events (Event::PunchOut);
3074 } else if (PARAM_IS ("edit-mode")) {
3076 Glib::Mutex::Lock lm (playlist_lock);
3078 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3079 (*i)->set_edit_mode (Config->get_edit_mode ());
3082 } else if (PARAM_IS ("use-video-sync")) {
3084 if (transport_stopped()) {
3085 if (Config->get_use_video_sync()) {
3086 waiting_for_sync_offset = true;
3090 } else if (PARAM_IS ("mmc-control")) {
3092 //poke_midi_thread ();
3094 } else if (PARAM_IS ("midi-control")) {
3096 //poke_midi_thread ();
3098 } else if (PARAM_IS ("raid-path")) {
3100 setup_raid_path (Config->get_raid_path());
3102 } else if (PARAM_IS ("smpte-frames-per-second") || PARAM_IS ("smpte-drop-frames")) {
3106 } else if (PARAM_IS ("video-pullup")) {
3110 } else if (PARAM_IS ("seamless-loop")) {
3112 if (play_loop && transport_rolling()) {
3113 // to reset diskstreams etc
3114 request_play_loop (true);
3117 } else if (PARAM_IS ("rf-speed")) {
3119 cumulative_rf_motion = 0;
3122 } else if (PARAM_IS ("click-sound")) {
3124 setup_click_sounds (1);
3126 } else if (PARAM_IS ("click-emphasis-sound")) {
3128 setup_click_sounds (-1);
3130 } else if (PARAM_IS ("clicking")) {
3132 if (Config->get_clicking()) {
3133 if (_click_io && click_data) { // don't require emphasis data
3140 } else if (PARAM_IS ("send-mtc")) {
3142 /* only set the internal flag if we have
3146 if (_mtc_port != 0) {
3147 session_send_mtc = Config->get_send_mtc();
3150 } else if (PARAM_IS ("send-mmc")) {
3152 /* only set the internal flag if we have
3156 if (_mmc_port != 0) {
3157 session_send_mmc = Config->get_send_mmc();
3160 } else if (PARAM_IS ("midi-feedback")) {
3162 /* only set the internal flag if we have
3166 if (_mtc_port != 0) {
3167 session_midi_feedback = Config->get_midi_feedback();
3170 } else if (PARAM_IS ("jack-time-master")) {
3172 engine().reset_timebase ();
3174 } else if (PARAM_IS ("native-file-header-format")) {
3176 if (!first_file_header_format_reset) {
3177 reset_native_file_format ();
3180 first_file_header_format_reset = false;
3182 } else if (PARAM_IS ("native-file-data-format")) {
3184 if (!first_file_data_format_reset) {
3185 reset_native_file_format ();
3188 first_file_data_format_reset = false;