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: find all un-referenced sources */
2559 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2561 SourceMap::iterator tmp;
2566 /* only remove files that are not in use and have some size
2567 to them. otherwise we remove the current "nascent"
2571 if (i->second.use_count() == 1 && i->second->length() > 0) {
2572 dead_sources.push_back (i->second);
2574 /* remove this source from our own list to avoid us
2575 adding it to the list of all sources below
2584 /* Step 3: get rid of all regions in the region list that use any dead sources
2585 in case the sources themselves don't go away (they might be referenced in
2589 for (vector<boost::shared_ptr<Source> >::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2591 for (RegionList::iterator r = regions.begin(); r != regions.end(); ) {
2592 RegionList::iterator tmp;
2597 boost::shared_ptr<Region> reg = r->second;
2599 for (uint32_t n = 0; n < reg->n_channels(); ++n) {
2600 if (reg->source (n) == (*i)) {
2601 /* this region is dead */
2602 remove_region (reg);
2610 /* build a list of all the possible sound directories for the session */
2612 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2617 sound_path += (*i).path;
2618 sound_path += sound_dir_name;
2620 if (nexti != session_dirs.end()) {
2627 /* now do the same thing for the files that ended up in the sounds dir(s)
2628 but are not referenced as sources in any snapshot.
2631 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2633 if (soundfiles == 0) {
2637 /* find all sources, but don't use this snapshot because the
2638 state file on disk still references sources we may have already
2642 find_all_sources_across_snapshots (all_sources, true);
2644 /* add our current source list
2647 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2648 boost::shared_ptr<AudioFileSource> fs;
2650 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2651 all_sources.insert (fs->path());
2655 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2660 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2670 unused.push_back (spath);
2674 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2676 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2677 struct stat statbuf;
2679 rep.paths.push_back (*x);
2680 if (stat ((*x).c_str(), &statbuf) == 0) {
2681 rep.space += statbuf.st_size;
2686 /* don't move the file across filesystems, just
2687 stick it in the `dead_sound_dir_name' directory
2688 on whichever filesystem it was already on.
2691 newpath = Glib::path_get_dirname (*x);
2692 newpath = Glib::path_get_dirname (newpath);
2695 newpath += dead_sound_dir_name;
2697 newpath += Glib::path_get_basename ((*x));
2699 if (access (newpath.c_str(), F_OK) == 0) {
2701 /* the new path already exists, try versioning */
2703 char buf[PATH_MAX+1];
2707 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2710 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2711 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2715 if (version == 999) {
2716 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2720 newpath = newpath_v;
2725 /* it doesn't exist, or we can't read it or something */
2729 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2730 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2731 (*x), newpath, strerror (errno))
2737 /* see if there an easy to find peakfile for this file, and remove it.
2740 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2741 peakpath += ".peak";
2743 if (access (peakpath.c_str(), W_OK) == 0) {
2744 if (::unlink (peakpath.c_str()) != 0) {
2745 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2746 peakpath, _path, strerror (errno))
2748 /* try to back out */
2749 rename (newpath.c_str(), _path.c_str());
2758 /* dump the history list */
2762 /* save state so we don't end up a session file
2763 referring to non-existent sources.
2769 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2774 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2776 vector<space_and_path>::iterator i;
2777 string dead_sound_dir;
2778 struct dirent* dentry;
2779 struct stat statbuf;
2785 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2787 dead_sound_dir = (*i).path;
2788 dead_sound_dir += dead_sound_dir_name;
2790 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2794 while ((dentry = readdir (dead)) != 0) {
2796 /* avoid '.' and '..' */
2798 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2799 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2805 fullpath = dead_sound_dir;
2807 fullpath += dentry->d_name;
2809 if (stat (fullpath.c_str(), &statbuf)) {
2813 if (!S_ISREG (statbuf.st_mode)) {
2817 if (unlink (fullpath.c_str())) {
2818 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2819 fullpath, strerror (errno))
2823 rep.paths.push_back (dentry->d_name);
2824 rep.space += statbuf.st_size;
2835 Session::set_dirty ()
2837 bool was_dirty = dirty();
2839 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2842 DirtyChanged(); /* EMIT SIGNAL */
2848 Session::set_clean ()
2850 bool was_dirty = dirty();
2852 _state_of_the_state = Clean;
2855 DirtyChanged(); /* EMIT SIGNAL */
2860 Session::add_controllable (Controllable* c)
2862 Glib::Mutex::Lock lm (controllables_lock);
2863 controllables.insert (c);
2867 Session::remove_controllable (Controllable* c)
2869 if (_state_of_the_state | Deletion) {
2873 Glib::Mutex::Lock lm (controllables_lock);
2875 Controllables::iterator x = controllables.find (c);
2877 if (x != controllables.end()) {
2878 controllables.erase (x);
2883 Session::controllable_by_id (const PBD::ID& id)
2885 Glib::Mutex::Lock lm (controllables_lock);
2887 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2888 if ((*i)->id() == id) {
2897 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2899 Stateful::add_instant_xml (node, dir);
2900 Config->add_instant_xml (node, get_user_ardour_path());
2905 Session::save_history (string snapshot_name)
2911 tree.set_root (&history.get_state());
2913 if (snapshot_name.empty()) {
2914 snapshot_name = _current_snapshot_name;
2917 xml_path = _path + snapshot_name + ".history";
2919 bak_path = xml_path + ".bak";
2921 if ((access (xml_path.c_str(), F_OK) == 0) &&
2922 (rename (xml_path.c_str(), bak_path.c_str())))
2924 error << _("could not backup old history file, current history not saved.") << endmsg;
2928 cerr << "actually writing history\n";
2930 if (!tree.write (xml_path))
2932 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2934 /* don't leave a corrupt file lying around if it is
2938 if (unlink (xml_path.c_str()))
2940 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2942 if (rename (bak_path.c_str(), xml_path.c_str()))
2944 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2955 Session::restore_history (string snapshot_name)
2961 xmlpath = _path + snapshot_name + ".history";
2962 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2964 if (access (xmlpath.c_str(), F_OK)) {
2965 error << string_compose(_("%1: session history file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
2969 if (!tree.read (xmlpath)) {
2970 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
2974 /* replace history */
2977 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2980 UndoTransaction* ut = new UndoTransaction ();
2983 ut->set_name(t->property("name")->value());
2984 stringstream ss(t->property("tv_sec")->value());
2986 ss.str(t->property("tv_usec")->value());
2988 ut->set_timestamp(tv);
2990 for (XMLNodeConstIterator child_it = t->children().begin();
2991 child_it != t->children().end();
2994 XMLNode *n = *child_it;
2997 if (n->name() == "MementoCommand" ||
2998 n->name() == "MementoUndoCommand" ||
2999 n->name() == "MementoRedoCommand") {
3000 if ((c = memento_command_factory(n))) {
3004 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3015 Session::config_changed (const char* parameter_name)
3017 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3019 if (PARAM_IS ("seamless-loop")) {
3021 } else if (PARAM_IS ("rf-speed")) {
3023 } else if (PARAM_IS ("auto-loop")) {
3025 } else if (PARAM_IS ("auto-input")) {
3027 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3028 /* auto-input only makes a difference if we're rolling */
3030 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3032 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3033 if ((*i)->record_enabled ()) {
3034 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
3035 (*i)->monitor_input (!Config->get_auto_input());
3040 } else if (PARAM_IS ("punch-in")) {
3044 if ((location = _locations.auto_punch_location()) != 0) {
3046 if (Config->get_punch_in ()) {
3047 replace_event (Event::PunchIn, location->start());
3049 remove_event (location->start(), Event::PunchIn);
3053 } else if (PARAM_IS ("punch-out")) {
3057 if ((location = _locations.auto_punch_location()) != 0) {
3059 if (Config->get_punch_out()) {
3060 replace_event (Event::PunchOut, location->end());
3062 clear_events (Event::PunchOut);
3066 } else if (PARAM_IS ("edit-mode")) {
3068 Glib::Mutex::Lock lm (playlist_lock);
3070 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3071 (*i)->set_edit_mode (Config->get_edit_mode ());
3074 } else if (PARAM_IS ("use-video-sync")) {
3076 if (transport_stopped()) {
3077 if (Config->get_use_video_sync()) {
3078 waiting_for_sync_offset = true;
3082 } else if (PARAM_IS ("mmc-control")) {
3084 //poke_midi_thread ();
3086 } else if (PARAM_IS ("midi-control")) {
3088 //poke_midi_thread ();
3090 } else if (PARAM_IS ("raid-path")) {
3092 setup_raid_path (Config->get_raid_path());
3094 } else if (PARAM_IS ("smpte-frames-per-second") || PARAM_IS ("smpte-drop-frames")) {
3098 } else if (PARAM_IS ("video-pullup")) {
3102 } else if (PARAM_IS ("seamless-loop")) {
3104 if (play_loop && transport_rolling()) {
3105 // to reset diskstreams etc
3106 request_play_loop (true);
3109 } else if (PARAM_IS ("rf-speed")) {
3111 cumulative_rf_motion = 0;
3114 } else if (PARAM_IS ("click-sound")) {
3116 setup_click_sounds (1);
3118 } else if (PARAM_IS ("click-emphasis-sound")) {
3120 setup_click_sounds (-1);
3122 } else if (PARAM_IS ("clicking")) {
3124 if (Config->get_clicking()) {
3125 if (_click_io && click_data) { // don't require emphasis data
3132 } else if (PARAM_IS ("send-mtc")) {
3134 /* only set the internal flag if we have
3138 if (_mtc_port != 0) {
3139 session_send_mtc = Config->get_send_mtc();
3142 } else if (PARAM_IS ("send-mmc")) {
3144 /* only set the internal flag if we have
3148 if (_mmc_port != 0) {
3149 session_send_mmc = Config->get_send_mmc();
3152 } else if (PARAM_IS ("midi-feedback")) {
3154 /* only set the internal flag if we have
3158 if (_mtc_port != 0) {
3159 session_midi_feedback = Config->get_midi_feedback();
3162 } else if (PARAM_IS ("jack-time-master")) {
3164 engine().reset_timebase ();
3166 } else if (PARAM_IS ("native-file-header-format")) {
3168 if (!first_file_header_format_reset) {
3169 reset_native_file_format ();
3172 first_file_header_format_reset = false;
3174 } else if (PARAM_IS ("native-file-data-format")) {
3176 if (!first_file_data_format_reset) {
3177 reset_native_file_format ();
3180 first_file_data_format_reset = false;