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/param.h>
47 #include <sys/mount.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>
60 #include <pbd/stacktrace.h>
61 #include <pbd/copyfile.h>
63 #include <ardour/audioengine.h>
64 #include <ardour/configuration.h>
65 #include <ardour/session.h>
66 #include <ardour/buffer.h>
67 #include <ardour/audio_diskstream.h>
68 #include <ardour/midi_diskstream.h>
69 #include <ardour/utils.h>
70 #include <ardour/audioplaylist.h>
71 #include <ardour/midi_playlist.h>
72 #include <ardour/smf_source.h>
73 #include <ardour/audiofilesource.h>
74 #include <ardour/destructive_filesource.h>
75 #include <ardour/midi_source.h>
76 #include <ardour/sndfile_helpers.h>
77 #include <ardour/auditioner.h>
78 #include <ardour/export.h>
79 #include <ardour/redirect.h>
80 #include <ardour/send.h>
81 #include <ardour/insert.h>
82 #include <ardour/connection.h>
83 #include <ardour/slave.h>
84 #include <ardour/tempo.h>
85 #include <ardour/audio_track.h>
86 #include <ardour/midi_track.h>
87 #include <ardour/cycle_timer.h>
88 #include <ardour/utils.h>
89 #include <ardour/named_selection.h>
90 #include <ardour/version.h>
91 #include <ardour/location.h>
92 #include <ardour/audioregion.h>
93 #include <ardour/midi_region.h>
94 #include <ardour/crossfade.h>
95 #include <ardour/control_protocol_manager.h>
96 #include <ardour/region_factory.h>
97 #include <ardour/source_factory.h>
98 #include <ardour/playlist_factory.h>
100 #include <control_protocol/control_protocol.h>
106 using namespace ARDOUR;
110 Session::first_stage_init (string fullpath, string snapshot_name)
112 if (fullpath.length() == 0) {
114 throw failed_constructor();
117 char buf[PATH_MAX+1];
118 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
119 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
121 throw failed_constructor();
126 if (_path[_path.length()-1] != '/') {
130 /* these two are just provisional settings. set_state()
131 will likely override them.
134 _name = _current_snapshot_name = snapshot_name;
136 _current_frame_rate = _engine.frame_rate ();
137 _tempo_map = new TempoMap (_current_frame_rate);
138 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
140 g_atomic_int_set (&processing_prohibited, 0);
142 _transport_speed = 0;
143 _last_transport_speed = 0;
144 transport_sub_state = 0;
145 _transport_frame = 0;
147 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
148 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
149 _end_location_is_free = true;
150 g_atomic_int_set (&_record_status, Disabled);
151 loop_changing = false;
153 _last_roll_location = 0;
154 _last_record_location = 0;
155 pending_locate_frame = 0;
156 pending_locate_roll = false;
157 pending_locate_flush = false;
158 dstream_buffer_size = 0;
160 state_was_pending = false;
162 outbound_mtc_smpte_frame = 0;
163 next_quarter_frame_to_send = -1;
164 current_block_size = 0;
165 solo_update_disabled = false;
166 currently_soloing = false;
167 _have_captured = false;
168 _worst_output_latency = 0;
169 _worst_input_latency = 0;
170 _worst_track_latency = 0;
171 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
173 butler_mixdown_buffer = 0;
174 butler_gain_buffer = 0;
176 session_send_mmc = false;
177 session_send_mtc = false;
178 post_transport_work = PostTransportWork (0);
179 g_atomic_int_set (&butler_should_do_transport_work, 0);
180 g_atomic_int_set (&butler_active, 0);
181 g_atomic_int_set (&_playback_load, 100);
182 g_atomic_int_set (&_capture_load, 100);
183 g_atomic_int_set (&_playback_load_min, 100);
184 g_atomic_int_set (&_capture_load_min, 100);
186 waiting_to_start = false;
188 _gain_automation_buffer = 0;
189 _pan_automation_buffer = 0;
191 pending_abort = false;
192 destructive_index = 0;
194 first_file_data_format_reset = true;
195 first_file_header_format_reset = true;
197 AudioDiskstream::allocate_working_buffers();
199 /* default short fade = 15ms */
201 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
202 SndFileSource::setup_standard_crossfades (frame_rate());
204 last_mmc_step.tv_sec = 0;
205 last_mmc_step.tv_usec = 0;
208 /* click sounds are unset by default, which causes us to internal
209 waveforms for clicks.
213 click_emphasis_data = 0;
215 click_emphasis_length = 0;
218 process_function = &Session::process_with_events;
220 if (Config->get_use_video_sync()) {
221 waiting_for_sync_offset = true;
223 waiting_for_sync_offset = false;
226 _current_frame_rate = 48000;
227 _base_frame_rate = 48000;
231 _smpte_offset_negative = true;
232 last_smpte_valid = false;
236 last_rr_session_dir = session_dirs.begin();
237 refresh_disk_space ();
239 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
243 average_slave_delta = 1800;
244 have_first_delta_accumulator = false;
245 delta_accumulator_cnt = 0;
246 slave_state = Stopped;
248 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
250 /* These are all static "per-class" signals */
252 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
253 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
254 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
255 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
256 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
257 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
259 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
261 IO::MoreChannels.connect (mem_fun (*this, &Session::ensure_buffers));
263 /* stop IO objects from doing stuff until we're ready for them */
265 IO::disable_panners ();
266 IO::disable_ports ();
267 IO::disable_connecting ();
271 Session::second_stage_init (bool new_session)
273 AudioFileSource::set_peak_dir (peak_dir());
276 if (load_state (_current_snapshot_name)) {
279 remove_empty_sounds ();
282 if (start_butler_thread()) {
286 /*if (start_midi_thread ()) {
290 // set_state() will call setup_raid_path(), but if it's a new session we need
291 // to call setup_raid_path() here.
293 if (set_state (*state_tree->root())) {
297 setup_raid_path(_path);
300 /* we can't save till after ::when_engine_running() is called,
301 because otherwise we save state with no connections made.
302 therefore, we reset _state_of_the_state because ::set_state()
303 will have cleared it.
305 we also have to include Loading so that any events that get
306 generated between here and the end of ::when_engine_running()
307 will be processed directly rather than queued.
310 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
312 // set_auto_input (true);
313 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
314 _locations.added.connect (mem_fun (this, &Session::locations_added));
315 setup_click_sounds (0);
316 setup_midi_control ();
318 /* Pay attention ... */
320 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
321 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
324 when_engine_running();
327 /* handle this one in a different way than all others, so that its clear what happened */
329 catch (AudioEngine::PortRegistrationFailure& err) {
330 error << _("Unable to create all required ports")
339 //send_full_time_code ();
340 _engine.transport_locate (0);
341 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
342 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
344 ControlProtocolManager::instance().set_session (*this);
347 _end_location_is_free = true;
349 _end_location_is_free = false;
356 Session::raid_path () const
360 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
365 return path.substr (0, path.length() - 1); // drop final colon
369 Session::setup_raid_path (string path)
371 string::size_type colon;
375 string::size_type len = path.length();
380 if (path.length() == 0) {
384 session_dirs.clear ();
386 for (string::size_type n = 0; n < len; ++n) {
387 if (path[n] == ':') {
394 /* no multiple search path, just one location (common case) */
398 session_dirs.push_back (sp);
405 if (fspath[fspath.length()-1] != '/') {
409 fspath += sound_dir (false);
411 AudioFileSource::set_search_path (fspath);
412 SMFSource::set_search_path (fspath); // FIXME: should be different
419 while ((colon = remaining.find_first_of (':')) != string::npos) {
422 sp.path = remaining.substr (0, colon);
423 session_dirs.push_back (sp);
425 /* add sounds to file search path */
428 if (fspath[fspath.length()-1] != '/') {
431 fspath += sound_dir (false);
434 remaining = remaining.substr (colon+1);
437 if (remaining.length()) {
444 if (fspath[fspath.length()-1] != '/') {
447 fspath += sound_dir (false);
450 session_dirs.push_back (sp);
453 /* set the AudioFileSource search path */
455 AudioFileSource::set_search_path (fspath);
456 SMFSource::set_search_path (fspath); // FIXME: should be different
458 /* reset the round-robin soundfile path thingie */
460 last_rr_session_dir = session_dirs.begin();
464 Session::create (bool& new_session, string* mix_template, nframes_t initial_length)
468 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
469 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
475 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
476 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
482 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
483 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
487 dir = dead_sound_dir ();
489 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
490 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
494 dir = automation_dir ();
496 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
497 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
502 /* check new_session so we don't overwrite an existing one */
505 std::string in_path = *mix_template;
507 ifstream in(in_path.c_str());
510 string out_path = _path;
512 out_path += _statefile_suffix;
514 ofstream out(out_path.c_str());
519 // okay, session is set up. Treat like normal saved
520 // session from now on.
526 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
532 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
539 /* set initial start + end point */
541 start_location->set_end (0);
542 _locations.add (start_location);
544 end_location->set_end (initial_length);
545 _locations.add (end_location);
547 _state_of_the_state = Clean;
549 if (save_state (_current_snapshot_name)) {
557 Session::load_diskstreams (const XMLNode& node)
560 XMLNodeConstIterator citer;
562 clist = node.children();
564 for (citer = clist.begin(); citer != clist.end(); ++citer) {
567 /* diskstreams added automatically by DiskstreamCreated handler */
568 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
569 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
570 add_diskstream (dstream);
571 } else if ((*citer)->name() == "MidiDiskstream") {
572 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
573 add_diskstream (dstream);
575 error << _("Session: unknown diskstream type in XML") << endmsg;
579 catch (failed_constructor& err) {
580 error << _("Session: could not load diskstream via XML state") << endmsg;
589 Session::remove_pending_capture_state ()
594 xml_path += _current_snapshot_name;
595 xml_path += _pending_suffix;
597 unlink (xml_path.c_str());
601 Session::save_state (string snapshot_name, bool pending)
607 if (_state_of_the_state & CannotSave) {
611 tree.set_root (&get_state());
613 if (snapshot_name.empty()) {
614 snapshot_name = _current_snapshot_name;
620 xml_path += snapshot_name;
621 xml_path += _statefile_suffix;
626 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
627 copy_file (xml_path, bak_path);
633 xml_path += snapshot_name;
634 xml_path += _pending_suffix;
641 tmp_path += snapshot_name;
644 cerr << "actually writing state\n";
646 if (!tree.write (tmp_path)) {
647 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
648 unlink (tmp_path.c_str());
653 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
654 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
655 unlink (tmp_path.c_str());
662 save_history (snapshot_name);
664 bool was_dirty = dirty();
666 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
669 DirtyChanged (); /* EMIT SIGNAL */
672 StateSaved (snapshot_name); /* EMIT SIGNAL */
679 Session::restore_state (string snapshot_name)
681 if (load_state (snapshot_name) == 0) {
682 set_state (*state_tree->root());
689 Session::load_state (string snapshot_name)
698 state_was_pending = false;
700 /* check for leftover pending state from a crashed capture attempt */
703 xmlpath += snapshot_name;
704 xmlpath += _pending_suffix;
706 if (!access (xmlpath.c_str(), F_OK)) {
708 /* there is pending state from a crashed capture attempt */
710 if (AskAboutPendingState()) {
711 state_was_pending = true;
715 if (!state_was_pending) {
718 xmlpath += snapshot_name;
719 xmlpath += _statefile_suffix;
722 if (access (xmlpath.c_str(), F_OK)) {
723 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
727 state_tree = new XMLTree;
731 if (!state_tree->read (xmlpath)) {
732 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
738 XMLNode& root (*state_tree->root());
740 if (root.name() != X_("Session")) {
741 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
747 const XMLProperty* prop;
750 if ((prop = root.property ("version")) == 0) {
751 /* no version implies very old version of Ardour */
755 major_version = atoi (prop->value()); // grab just the first number before the period
756 if (major_version < 2) {
764 backup_path = xmlpath;
767 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
768 xmlpath, backup_path)
771 copy_file (xmlpath, backup_path);
773 /* if it fails, don't worry. right? */
780 Session::load_options (const XMLNode& node)
784 LocaleGuard lg (X_("POSIX"));
786 Config->set_variables (node, ConfigVariableBase::Session);
788 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
789 if ((prop = child->property ("val")) != 0) {
790 _end_location_is_free = (prop->value() == "yes");
798 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
800 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
801 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
803 return owner & modified_by_session_or_user;
807 Session::get_options () const
810 LocaleGuard lg (X_("POSIX"));
812 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
814 child = option_root.add_child ("end-marker-is-free");
815 child->add_property ("val", _end_location_is_free ? "yes" : "no");
827 Session::get_template()
829 /* if we don't disable rec-enable, diskstreams
830 will believe they need to store their capture
831 sources in their state node.
834 disable_record (false);
840 Session::state(bool full_state)
842 XMLNode* node = new XMLNode("Session");
845 // store libardour version, just in case
847 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
848 libardour_major_version, libardour_minor_version, libardour_micro_version);
849 node->add_property("version", string(buf));
851 /* store configuration settings */
856 node->add_property ("name", _name);
858 if (session_dirs.size() > 1) {
862 vector<space_and_path>::iterator i = session_dirs.begin();
863 vector<space_and_path>::iterator next;
865 ++i; /* skip the first one */
869 while (i != session_dirs.end()) {
873 if (next != session_dirs.end()) {
883 child = node->add_child ("Path");
884 child->add_content (p);
888 /* save the ID counter */
890 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
891 node->add_property ("id-counter", buf);
893 /* various options */
895 node->add_child_nocopy (get_options());
897 child = node->add_child ("Sources");
900 Glib::Mutex::Lock sl (source_lock);
902 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
904 /* Don't save information about AudioFileSources that are empty */
906 boost::shared_ptr<AudioFileSource> fs;
908 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
910 /* Don't save sources that are empty, unless they're destructive (which are OK
911 if they are empty, because we will re-use them every time.)
914 if (!fs->destructive()) {
915 if (fs->length() == 0) {
921 child->add_child_nocopy (siter->second->get_state());
925 child = node->add_child ("Regions");
928 Glib::Mutex::Lock rl (region_lock);
930 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
932 /* only store regions not attached to playlists */
934 if (i->second->playlist() == 0) {
935 child->add_child_nocopy (i->second->state (true));
940 child = node->add_child ("DiskStreams");
943 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
944 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
945 if (!(*i)->hidden()) {
946 child->add_child_nocopy ((*i)->get_state());
952 node->add_child_nocopy (_locations.get_state());
954 // for a template, just create a new Locations, populate it
955 // with the default start and end, and get the state for that.
957 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
958 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
961 end->set_end(compute_initial_length());
963 node->add_child_nocopy (loc.get_state());
966 child = node->add_child ("Connections");
968 Glib::Mutex::Lock lm (connection_lock);
969 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
970 if (!(*i)->system_dependent()) {
971 child->add_child_nocopy ((*i)->get_state());
976 child = node->add_child ("Routes");
978 boost::shared_ptr<RouteList> r = routes.reader ();
980 RoutePublicOrderSorter cmp;
981 RouteList public_order (*r);
982 public_order.sort (cmp);
984 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
985 if (!(*i)->hidden()) {
987 child->add_child_nocopy ((*i)->get_state());
989 child->add_child_nocopy ((*i)->get_template());
996 child = node->add_child ("EditGroups");
997 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
998 child->add_child_nocopy ((*i)->get_state());
1001 child = node->add_child ("MixGroups");
1002 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1003 child->add_child_nocopy ((*i)->get_state());
1006 child = node->add_child ("Playlists");
1007 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1008 if (!(*i)->hidden()) {
1009 if (!(*i)->empty()) {
1011 child->add_child_nocopy ((*i)->get_state());
1013 child->add_child_nocopy ((*i)->get_template());
1019 child = node->add_child ("UnusedPlaylists");
1020 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1021 if (!(*i)->hidden()) {
1022 if (!(*i)->empty()) {
1024 child->add_child_nocopy ((*i)->get_state());
1026 child->add_child_nocopy ((*i)->get_template());
1034 child = node->add_child ("Click");
1035 child->add_child_nocopy (_click_io->state (full_state));
1039 child = node->add_child ("NamedSelections");
1040 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1042 child->add_child_nocopy ((*i)->get_state());
1047 node->add_child_nocopy (_tempo_map->get_state());
1049 node->add_child_nocopy (get_control_protocol_state());
1052 node->add_child_copy (*_extra_xml);
1059 Session::get_control_protocol_state ()
1061 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1062 XMLNode* node = new XMLNode (X_("ControlProtocols"));
1064 cpm.foreach_known_protocol (bind (mem_fun (*this, &Session::add_control_protocol), node));
1070 Session::add_control_protocol (const ControlProtocolInfo* const cpi, XMLNode* node)
1072 if (cpi->protocol) {
1073 node->add_child_nocopy (cpi->protocol->get_state());
1078 Session::set_state (const XMLNode& node)
1082 const XMLProperty* prop;
1085 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1087 if (node.name() != X_("Session")){
1088 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1092 if ((prop = node.property ("name")) != 0) {
1093 _name = prop->value ();
1096 setup_raid_path(_path);
1098 if ((prop = node.property (X_("id-counter"))) != 0) {
1100 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1101 ID::init_counter (x);
1103 /* old sessions used a timebased counter, so fake
1104 the startup ID counter based on a standard
1109 ID::init_counter (now);
1113 IO::disable_ports ();
1114 IO::disable_connecting ();
1116 /* Object loading order:
1134 if (use_config_midi_ports ()) {
1137 if ((child = find_named_node (node, "extra")) != 0) {
1138 _extra_xml = new XMLNode (*child);
1141 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1142 load_options (*child);
1143 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1144 load_options (*child);
1146 error << _("Session: XML state has no options section") << endmsg;
1149 if ((child = find_named_node (node, "Locations")) == 0) {
1150 error << _("Session: XML state has no locations section") << endmsg;
1152 } else if (_locations.set_state (*child)) {
1158 if ((location = _locations.auto_loop_location()) != 0) {
1159 set_auto_loop_location (location);
1162 if ((location = _locations.auto_punch_location()) != 0) {
1163 set_auto_punch_location (location);
1166 if ((location = _locations.end_location()) == 0) {
1167 _locations.add (end_location);
1169 delete end_location;
1170 end_location = location;
1173 if ((location = _locations.start_location()) == 0) {
1174 _locations.add (start_location);
1176 delete start_location;
1177 start_location = location;
1180 AudioFileSource::set_header_position_offset (start_location->start());
1182 if ((child = find_named_node (node, "Sources")) == 0) {
1183 error << _("Session: XML state has no sources section") << endmsg;
1185 } else if (load_sources (*child)) {
1189 if ((child = find_named_node (node, "Regions")) == 0) {
1190 error << _("Session: XML state has no Regions section") << endmsg;
1192 } else if (load_regions (*child)) {
1196 if ((child = find_named_node (node, "Playlists")) == 0) {
1197 error << _("Session: XML state has no playlists section") << endmsg;
1199 } else if (load_playlists (*child)) {
1203 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1205 } else if (load_unused_playlists (*child)) {
1209 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1210 if (load_named_selections (*child)) {
1215 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1216 error << _("Session: XML state has no diskstreams section") << endmsg;
1218 } else if (load_diskstreams (*child)) {
1222 if ((child = find_named_node (node, "Connections")) == 0) {
1223 error << _("Session: XML state has no connections section") << endmsg;
1225 } else if (load_connections (*child)) {
1229 if ((child = find_named_node (node, "EditGroups")) == 0) {
1230 error << _("Session: XML state has no edit groups section") << endmsg;
1232 } else if (load_edit_groups (*child)) {
1236 if ((child = find_named_node (node, "MixGroups")) == 0) {
1237 error << _("Session: XML state has no mix groups section") << endmsg;
1239 } else if (load_mix_groups (*child)) {
1243 if ((child = find_named_node (node, "TempoMap")) == 0) {
1244 error << _("Session: XML state has no Tempo Map section") << endmsg;
1246 } else if (_tempo_map->set_state (*child)) {
1250 if ((child = find_named_node (node, "Routes")) == 0) {
1251 error << _("Session: XML state has no routes section") << endmsg;
1253 } else if (load_routes (*child)) {
1257 if ((child = find_named_node (node, "Click")) == 0) {
1258 warning << _("Session: XML state has no click section") << endmsg;
1259 } else if (_click_io) {
1260 _click_io->set_state (*child);
1263 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1264 ControlProtocolManager::instance().set_protocol_states (*child);
1267 /* here beginneth the second phase ... */
1269 StateReady (); /* EMIT SIGNAL */
1271 _state_of_the_state = Clean;
1273 if (state_was_pending) {
1274 save_state (_current_snapshot_name);
1275 remove_pending_capture_state ();
1276 state_was_pending = false;
1286 Session::load_routes (const XMLNode& node)
1289 XMLNodeConstIterator niter;
1290 RouteList new_routes;
1292 nlist = node.children();
1296 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1298 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1301 error << _("Session: cannot create Route from XML description.") << endmsg;
1305 new_routes.push_back (route);
1308 add_routes (new_routes);
1313 boost::shared_ptr<Route>
1314 Session::XMLRouteFactory (const XMLNode& node)
1316 if (node.name() != "Route") {
1317 return boost::shared_ptr<Route> ((Route*) 0);
1320 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1322 DataType type = DataType::AUDIO;
1323 const XMLProperty* prop = node.property("default-type");
1325 type = DataType(prop->value());
1327 assert(type != DataType::NIL);
1329 if (has_diskstream) {
1330 if (type == DataType::AUDIO) {
1331 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1334 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1338 boost::shared_ptr<Route> ret (new Route (*this, node));
1344 Session::load_regions (const XMLNode& node)
1347 XMLNodeConstIterator niter;
1348 boost::shared_ptr<Region> region;
1350 nlist = node.children();
1354 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1355 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1356 error << _("Session: cannot create Region from XML description.") << endmsg;
1363 boost::shared_ptr<Region>
1364 Session::XMLRegionFactory (const XMLNode& node, bool full)
1366 const XMLProperty* type = node.property("type");
1370 if ( !type || type->value() == "audio" ) {
1372 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1374 } else if (type->value() == "midi") {
1376 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1380 } catch (failed_constructor& err) {
1381 return boost::shared_ptr<Region> ();
1384 return boost::shared_ptr<Region> ();
1387 boost::shared_ptr<AudioRegion>
1388 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1390 const XMLProperty* prop;
1391 boost::shared_ptr<Source> source;
1392 boost::shared_ptr<AudioSource> as;
1394 uint32_t nchans = 1;
1397 if (node.name() != X_("Region")) {
1398 return boost::shared_ptr<AudioRegion>();
1401 if ((prop = node.property (X_("channels"))) != 0) {
1402 nchans = atoi (prop->value().c_str());
1406 if ((prop = node.property ("name")) == 0) {
1407 cerr << "no name for this region\n";
1411 if ((prop = node.property (X_("source-0"))) == 0) {
1412 if ((prop = node.property ("source")) == 0) {
1413 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1414 return boost::shared_ptr<AudioRegion>();
1418 PBD::ID s_id (prop->value());
1420 if ((source = source_by_id (s_id)) == 0) {
1421 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1422 return boost::shared_ptr<AudioRegion>();
1425 as = boost::dynamic_pointer_cast<AudioSource>(source);
1427 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1428 return boost::shared_ptr<AudioRegion>();
1431 sources.push_back (as);
1433 /* pickup other channels */
1435 for (uint32_t n=1; n < nchans; ++n) {
1436 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1437 if ((prop = node.property (buf)) != 0) {
1439 PBD::ID id2 (prop->value());
1441 if ((source = source_by_id (id2)) == 0) {
1442 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1443 return boost::shared_ptr<AudioRegion>();
1446 as = boost::dynamic_pointer_cast<AudioSource>(source);
1448 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1449 return boost::shared_ptr<AudioRegion>();
1451 sources.push_back (as);
1456 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1461 catch (failed_constructor& err) {
1462 return boost::shared_ptr<AudioRegion>();
1466 boost::shared_ptr<MidiRegion>
1467 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1469 const XMLProperty* prop;
1470 boost::shared_ptr<Source> source;
1471 boost::shared_ptr<MidiSource> ms;
1472 MidiRegion::SourceList sources;
1473 uint32_t nchans = 1;
1475 if (node.name() != X_("Region")) {
1476 return boost::shared_ptr<MidiRegion>();
1479 if ((prop = node.property (X_("channels"))) != 0) {
1480 nchans = atoi (prop->value().c_str());
1483 // Multiple midi channels? that's just crazy talk
1484 assert(nchans == 1);
1486 if ((prop = node.property (X_("source-0"))) == 0) {
1487 if ((prop = node.property ("source")) == 0) {
1488 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1489 return boost::shared_ptr<MidiRegion>();
1493 PBD::ID s_id (prop->value());
1495 if ((source = source_by_id (s_id)) == 0) {
1496 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1497 return boost::shared_ptr<MidiRegion>();
1500 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1502 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1503 return boost::shared_ptr<MidiRegion>();
1506 sources.push_back (ms);
1509 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1513 catch (failed_constructor& err) {
1514 return boost::shared_ptr<MidiRegion>();
1519 Session::get_sources_as_xml ()
1522 XMLNode* node = new XMLNode (X_("Sources"));
1523 Glib::Mutex::Lock lm (source_lock);
1525 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1526 node->add_child_nocopy (i->second->get_state());
1529 /* XXX get MIDI and other sources here */
1535 Session::path_from_region_name (string name, string identifier)
1537 char buf[PATH_MAX+1];
1539 string dir = discover_best_sound_dir ();
1541 for (n = 0; n < 999999; ++n) {
1542 if (identifier.length()) {
1543 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1544 identifier.c_str(), n);
1546 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1548 if (access (buf, F_OK) != 0) {
1558 Session::load_sources (const XMLNode& node)
1561 XMLNodeConstIterator niter;
1562 boost::shared_ptr<Source> source;
1564 nlist = node.children();
1568 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1570 if ((source = XMLSourceFactory (**niter)) == 0) {
1571 error << _("Session: cannot create Source from XML description.") << endmsg;
1579 boost::shared_ptr<Source>
1580 Session::XMLSourceFactory (const XMLNode& node)
1582 if (node.name() != "Source") {
1583 return boost::shared_ptr<Source>();
1587 return SourceFactory::create (*this, node);
1590 catch (failed_constructor& err) {
1591 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1592 return boost::shared_ptr<Source>();
1597 Session::save_template (string template_name)
1600 string xml_path, bak_path, template_path;
1602 if (_state_of_the_state & CannotSave) {
1607 string dir = template_dir();
1609 if ((dp = opendir (dir.c_str()))) {
1612 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1613 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1618 tree.set_root (&get_template());
1621 xml_path += template_name;
1622 xml_path += _template_suffix;
1624 ifstream in(xml_path.c_str());
1627 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1633 if (!tree.write (xml_path)) {
1634 error << _("mix template not saved") << endmsg;
1642 Session::rename_template (string old_name, string new_name)
1644 string old_path = template_dir() + old_name + _template_suffix;
1645 string new_path = template_dir() + new_name + _template_suffix;
1647 return rename (old_path.c_str(), new_path.c_str());
1651 Session::delete_template (string name)
1653 string template_path = template_dir();
1654 template_path += name;
1655 template_path += _template_suffix;
1657 return remove (template_path.c_str());
1661 Session::refresh_disk_space ()
1664 struct statfs statfsbuf;
1665 vector<space_and_path>::iterator i;
1666 Glib::Mutex::Lock lm (space_lock);
1669 /* get freespace on every FS that is part of the session path */
1671 _total_free_4k_blocks = 0;
1673 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1674 statfs ((*i).path.c_str(), &statfsbuf);
1676 scale = statfsbuf.f_bsize/4096.0;
1678 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1679 _total_free_4k_blocks += (*i).blocks;
1685 Session::ensure_sound_dir (string path, string& result)
1690 /* Ensure that the parent directory exists */
1692 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1693 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1697 /* Ensure that the sounds directory exists */
1701 result += sound_dir_name;
1703 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1704 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1710 dead += dead_sound_dir_name;
1712 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1713 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1719 peak += peak_dir_name;
1721 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1722 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1726 /* callers expect this to be terminated ... */
1733 Session::discover_best_sound_dir (bool destructive)
1735 vector<space_and_path>::iterator i;
1738 /* handle common case without system calls */
1740 if (session_dirs.size() == 1) {
1744 /* OK, here's the algorithm we're following here:
1746 We want to select which directory to use for
1747 the next file source to be created. Ideally,
1748 we'd like to use a round-robin process so as to
1749 get maximum performance benefits from splitting
1750 the files across multiple disks.
1752 However, in situations without much diskspace, an
1753 RR approach may end up filling up a filesystem
1754 with new files while others still have space.
1755 Its therefore important to pay some attention to
1756 the freespace in the filesystem holding each
1757 directory as well. However, if we did that by
1758 itself, we'd keep creating new files in the file
1759 system with the most space until it was as full
1760 as all others, thus negating any performance
1761 benefits of this RAID-1 like approach.
1763 So, we use a user-configurable space threshold. If
1764 there are at least 2 filesystems with more than this
1765 much space available, we use RR selection between them.
1766 If not, then we pick the filesystem with the most space.
1768 This gets a good balance between the two
1772 refresh_disk_space ();
1774 int free_enough = 0;
1776 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1777 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1782 if (free_enough >= 2) {
1784 bool found_it = false;
1786 /* use RR selection process, ensuring that the one
1790 i = last_rr_session_dir;
1793 if (++i == session_dirs.end()) {
1794 i = session_dirs.begin();
1797 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1798 if (ensure_sound_dir ((*i).path, result) == 0) {
1799 last_rr_session_dir = i;
1805 } while (i != last_rr_session_dir);
1808 result = sound_dir();
1813 /* pick FS with the most freespace (and that
1814 seems to actually work ...)
1817 vector<space_and_path> sorted;
1818 space_and_path_ascending_cmp cmp;
1820 sorted = session_dirs;
1821 sort (sorted.begin(), sorted.end(), cmp);
1823 for (i = sorted.begin(); i != sorted.end(); ++i) {
1824 if (ensure_sound_dir ((*i).path, result) == 0) {
1825 last_rr_session_dir = i;
1830 /* if the above fails, fall back to the most simplistic solution */
1832 if (i == sorted.end()) {
1841 Session::load_playlists (const XMLNode& node)
1844 XMLNodeConstIterator niter;
1845 boost::shared_ptr<Playlist> playlist;
1847 nlist = node.children();
1851 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1853 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1854 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1862 Session::load_unused_playlists (const XMLNode& node)
1865 XMLNodeConstIterator niter;
1866 boost::shared_ptr<Playlist> playlist;
1868 nlist = node.children();
1872 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1874 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1875 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1879 // now manually untrack it
1881 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1887 boost::shared_ptr<Playlist>
1888 Session::XMLPlaylistFactory (const XMLNode& node)
1891 return PlaylistFactory::create (*this, node);
1894 catch (failed_constructor& err) {
1895 return boost::shared_ptr<Playlist>();
1900 Session::load_named_selections (const XMLNode& node)
1903 XMLNodeConstIterator niter;
1906 nlist = node.children();
1910 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1912 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1913 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1921 Session::XMLNamedSelectionFactory (const XMLNode& node)
1924 return new NamedSelection (*this, node);
1927 catch (failed_constructor& err) {
1933 Session::dead_sound_dir () const
1936 res += dead_sound_dir_name;
1942 Session::sound_dir (bool with_path) const
1944 /* support old session structure */
1946 struct stat statbuf;
1948 string old_withpath;
1950 old_nopath += old_sound_dir_name;
1953 old_withpath = _path;
1954 old_withpath += old_sound_dir_name;
1956 if (stat (old_withpath.c_str(), &statbuf) == 0) {
1958 return old_withpath;
1969 res += interchange_dir_name;
1971 res += legalize_for_path (_name);
1973 res += sound_dir_name;
1979 Session::peak_dir () const
1982 res += peak_dir_name;
1988 Session::automation_dir () const
1991 res += "automation/";
1996 Session::template_dir ()
1998 string path = get_user_ardour_path();
1999 path += "templates/";
2005 Session::suffixed_search_path (string suffix, bool data)
2009 path += get_user_ardour_path();
2010 if (path[path.length()-1] != ':') {
2015 path += get_system_data_path();
2017 path += get_system_module_path();
2020 vector<string> split_path;
2022 split (path, split_path, ':');
2025 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2030 if (distance (i, split_path.end()) != 1) {
2039 Session::template_path ()
2041 return suffixed_search_path (X_("templates"), true);
2045 Session::control_protocol_path ()
2047 return suffixed_search_path (X_("surfaces"), false);
2051 Session::load_connections (const XMLNode& node)
2053 XMLNodeList nlist = node.children();
2054 XMLNodeConstIterator niter;
2058 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2059 if ((*niter)->name() == "InputConnection") {
2060 add_connection (new ARDOUR::InputConnection (**niter));
2061 } else if ((*niter)->name() == "OutputConnection") {
2062 add_connection (new ARDOUR::OutputConnection (**niter));
2064 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2073 Session::load_edit_groups (const XMLNode& node)
2075 return load_route_groups (node, true);
2079 Session::load_mix_groups (const XMLNode& node)
2081 return load_route_groups (node, false);
2085 Session::load_route_groups (const XMLNode& node, bool edit)
2087 XMLNodeList nlist = node.children();
2088 XMLNodeConstIterator niter;
2093 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2094 if ((*niter)->name() == "RouteGroup") {
2096 rg = add_edit_group ("");
2097 rg->set_state (**niter);
2099 rg = add_mix_group ("");
2100 rg->set_state (**niter);
2109 state_file_filter (const string &str, void *arg)
2111 return (str.length() > strlen(Session::statefile_suffix()) &&
2112 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2116 bool operator()(const string* a, const string* b) {
2122 remove_end(string* state)
2124 string statename(*state);
2126 string::size_type start,end;
2127 if ((start = statename.find_last_of ('/')) != string::npos) {
2128 statename = statename.substr (start+1);
2131 if ((end = statename.rfind(".ardour")) == string::npos) {
2132 end = statename.length();
2135 return new string(statename.substr (0, end));
2139 Session::possible_states (string path)
2141 PathScanner scanner;
2142 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2144 transform(states->begin(), states->end(), states->begin(), remove_end);
2147 sort (states->begin(), states->end(), cmp);
2153 Session::possible_states () const
2155 return possible_states(_path);
2159 Session::auto_save()
2161 save_state (_current_snapshot_name);
2165 Session::add_edit_group (string name)
2167 RouteGroup* rg = new RouteGroup (*this, name);
2168 edit_groups.push_back (rg);
2169 edit_group_added (rg); /* EMIT SIGNAL */
2175 Session::add_mix_group (string name)
2177 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2178 mix_groups.push_back (rg);
2179 mix_group_added (rg); /* EMIT SIGNAL */
2185 Session::remove_edit_group (RouteGroup& rg)
2187 list<RouteGroup*>::iterator i;
2189 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2190 (*i)->apply (&Route::drop_edit_group, this);
2191 edit_groups.erase (i);
2192 edit_group_removed (); /* EMIT SIGNAL */
2199 Session::remove_mix_group (RouteGroup& rg)
2201 list<RouteGroup*>::iterator i;
2203 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2204 (*i)->apply (&Route::drop_mix_group, this);
2205 mix_groups.erase (i);
2206 mix_group_removed (); /* EMIT SIGNAL */
2213 Session::mix_group_by_name (string name)
2215 list<RouteGroup *>::iterator i;
2217 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2218 if ((*i)->name() == name) {
2226 Session::edit_group_by_name (string name)
2228 list<RouteGroup *>::iterator i;
2230 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2231 if ((*i)->name() == name) {
2239 Session::begin_reversible_command (string name)
2241 current_trans = new UndoTransaction;
2242 current_trans->set_name (name);
2246 Session::commit_reversible_command (Command *cmd)
2251 current_trans->add_command (cmd);
2254 gettimeofday (&now, 0);
2255 current_trans->set_timestamp (now);
2257 _history.add (current_trans);
2260 Session::GlobalRouteBooleanState
2261 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2263 GlobalRouteBooleanState s;
2264 boost::shared_ptr<RouteList> r = routes.reader ();
2266 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2267 if (!(*i)->hidden()) {
2268 RouteBooleanState v;
2271 Route* r = (*i).get();
2272 v.second = (r->*method)();
2281 Session::GlobalRouteMeterState
2282 Session::get_global_route_metering ()
2284 GlobalRouteMeterState s;
2285 boost::shared_ptr<RouteList> r = routes.reader ();
2287 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2288 if (!(*i)->hidden()) {
2292 v.second = (*i)->meter_point();
2302 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2304 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2306 boost::shared_ptr<Route> r = (i->first.lock());
2309 r->set_meter_point (i->second, arg);
2315 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2317 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2319 boost::shared_ptr<Route> r = (i->first.lock());
2322 Route* rp = r.get();
2323 (rp->*method) (i->second, arg);
2329 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2331 set_global_route_boolean (s, &Route::set_mute, src);
2335 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2337 set_global_route_boolean (s, &Route::set_solo, src);
2341 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2343 set_global_route_boolean (s, &Route::set_record_enable, src);
2348 Session::global_mute_memento (void* src)
2350 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2354 Session::global_metering_memento (void* src)
2356 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2360 Session::global_solo_memento (void* src)
2362 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2366 Session::global_record_enable_memento (void* src)
2368 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2373 template_filter (const string &str, void *arg)
2375 return (str.length() > strlen(Session::template_suffix()) &&
2376 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2380 Session::get_template_list (list<string> &template_names)
2382 vector<string *> *templates;
2383 PathScanner scanner;
2386 path = template_path ();
2388 templates = scanner (path, template_filter, 0, false, true);
2390 vector<string*>::iterator i;
2391 for (i = templates->begin(); i != templates->end(); ++i) {
2392 string fullpath = *(*i);
2395 start = fullpath.find_last_of ('/') + 1;
2396 if ((end = fullpath.find_last_of ('.')) <0) {
2397 end = fullpath.length();
2400 template_names.push_back(fullpath.substr(start, (end-start)));
2405 Session::read_favorite_dirs (FavoriteDirs & favs)
2407 string path = get_user_ardour_path();
2408 path += "/favorite_dirs";
2410 ifstream fav (path.c_str());
2415 if (errno != ENOENT) {
2416 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2427 getline(fav, newfav);
2433 favs.push_back (newfav);
2440 Session::write_favorite_dirs (FavoriteDirs & favs)
2442 string path = get_user_ardour_path();
2443 path += "/favorite_dirs";
2445 ofstream fav (path.c_str());
2451 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2452 fav << (*i) << endl;
2459 accept_all_non_peak_files (const string& path, void *arg)
2461 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2465 accept_all_state_files (const string& path, void *arg)
2467 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2471 Session::find_all_sources (string path, set<string>& result)
2476 if (!tree.read (path)) {
2480 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2485 XMLNodeConstIterator niter;
2487 nlist = node->children();
2491 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2495 if ((prop = (*niter)->property (X_("name"))) == 0) {
2499 if (prop->value()[0] == '/') {
2500 /* external file, ignore */
2504 string path = _path; /* /-terminated */
2505 path += sound_dir_name;
2507 path += prop->value();
2509 result.insert (path);
2516 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2518 PathScanner scanner;
2519 vector<string*>* state_files;
2521 string this_snapshot_path;
2527 if (ripped[ripped.length()-1] == '/') {
2528 ripped = ripped.substr (0, ripped.length() - 1);
2531 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2533 if (state_files == 0) {
2538 this_snapshot_path = _path;
2539 this_snapshot_path += _current_snapshot_name;
2540 this_snapshot_path += _statefile_suffix;
2542 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2544 if (exclude_this_snapshot && **i == this_snapshot_path) {
2548 if (find_all_sources (**i, result) < 0) {
2556 struct RegionCounter {
2557 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2558 AudioSourceList::iterator iter;
2559 boost::shared_ptr<Region> region;
2562 RegionCounter() : count (0) {}
2566 Session::cleanup_sources (Session::cleanup_report& rep)
2568 vector<boost::shared_ptr<Source> > dead_sources;
2569 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2570 PathScanner scanner;
2572 vector<space_and_path>::iterator i;
2573 vector<space_and_path>::iterator nexti;
2574 vector<string*>* soundfiles;
2575 vector<string> unused;
2576 set<string> all_sources;
2581 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2583 /* step 1: consider deleting all unused playlists */
2585 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2588 status = AskAboutPlaylistDeletion (*x);
2597 playlists_tbd.push_back (*x);
2601 /* leave it alone */
2606 /* now delete any that were marked for deletion */
2608 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2609 (*x)->drop_references ();
2612 playlists_tbd.clear ();
2614 /* step 2: find all un-used sources */
2619 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2621 SourceMap::iterator tmp;
2626 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2630 if (!i->second->used() && i->second->length() > 0) {
2631 dead_sources.push_back (i->second);
2632 i->second->GoingAway();
2638 /* build a list of all the possible sound directories for the session */
2640 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2645 sound_path += (*i).path;
2646 sound_path += sound_dir (false);
2648 if (nexti != session_dirs.end()) {
2655 /* now do the same thing for the files that ended up in the sounds dir(s)
2656 but are not referenced as sources in any snapshot.
2659 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2661 if (soundfiles == 0) {
2665 /* find all sources, but don't use this snapshot because the
2666 state file on disk still references sources we may have already
2670 find_all_sources_across_snapshots (all_sources, true);
2672 /* add our current source list
2675 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2676 boost::shared_ptr<AudioFileSource> fs;
2678 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2679 all_sources.insert (fs->path());
2683 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2688 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2697 unused.push_back (spath);
2701 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2703 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2704 struct stat statbuf;
2706 rep.paths.push_back (*x);
2707 if (stat ((*x).c_str(), &statbuf) == 0) {
2708 rep.space += statbuf.st_size;
2713 /* don't move the file across filesystems, just
2714 stick it in the `dead_sound_dir_name' directory
2715 on whichever filesystem it was already on.
2718 if (_path.find ("/sounds/")) {
2720 /* old school, go up 1 level */
2722 newpath = Glib::path_get_dirname (*x); // "sounds"
2723 newpath = Glib::path_get_dirname (newpath); // "session-name"
2727 /* new school, go up 4 levels */
2729 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2730 newpath = Glib::path_get_dirname (newpath); // "session-name"
2731 newpath = Glib::path_get_dirname (newpath); // "interchange"
2732 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2736 newpath += dead_sound_dir_name;
2738 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2739 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2744 newpath += Glib::path_get_basename ((*x));
2746 if (access (newpath.c_str(), F_OK) == 0) {
2748 /* the new path already exists, try versioning */
2750 char buf[PATH_MAX+1];
2754 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2757 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2758 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2762 if (version == 999) {
2763 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2767 newpath = newpath_v;
2772 /* it doesn't exist, or we can't read it or something */
2776 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2777 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2778 (*x), newpath, strerror (errno))
2783 /* see if there an easy to find peakfile for this file, and remove it.
2786 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2787 peakpath += ".peak";
2789 if (access (peakpath.c_str(), W_OK) == 0) {
2790 if (::unlink (peakpath.c_str()) != 0) {
2791 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2792 peakpath, _path, strerror (errno))
2794 /* try to back out */
2795 rename (newpath.c_str(), _path.c_str());
2803 /* dump the history list */
2807 /* save state so we don't end up a session file
2808 referring to non-existent sources.
2814 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2819 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2821 vector<space_and_path>::iterator i;
2822 string dead_sound_dir;
2823 struct dirent* dentry;
2824 struct stat statbuf;
2830 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2832 dead_sound_dir = (*i).path;
2833 dead_sound_dir += dead_sound_dir_name;
2835 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2839 while ((dentry = readdir (dead)) != 0) {
2841 /* avoid '.' and '..' */
2843 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2844 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2850 fullpath = dead_sound_dir;
2852 fullpath += dentry->d_name;
2854 if (stat (fullpath.c_str(), &statbuf)) {
2858 if (!S_ISREG (statbuf.st_mode)) {
2862 if (unlink (fullpath.c_str())) {
2863 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2864 fullpath, strerror (errno))
2868 rep.paths.push_back (dentry->d_name);
2869 rep.space += statbuf.st_size;
2880 Session::set_dirty ()
2882 bool was_dirty = dirty();
2884 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2887 DirtyChanged(); /* EMIT SIGNAL */
2893 Session::set_clean ()
2895 bool was_dirty = dirty();
2897 _state_of_the_state = Clean;
2900 DirtyChanged(); /* EMIT SIGNAL */
2905 Session::set_deletion_in_progress ()
2907 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2911 Session::add_controllable (Controllable* c)
2913 Glib::Mutex::Lock lm (controllables_lock);
2914 controllables.insert (c);
2918 Session::remove_controllable (Controllable* c)
2920 if (_state_of_the_state | Deletion) {
2924 Glib::Mutex::Lock lm (controllables_lock);
2926 Controllables::iterator x = controllables.find (c);
2928 if (x != controllables.end()) {
2929 controllables.erase (x);
2934 Session::controllable_by_id (const PBD::ID& id)
2936 Glib::Mutex::Lock lm (controllables_lock);
2938 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2939 if ((*i)->id() == id) {
2948 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2950 Stateful::add_instant_xml (node, dir);
2951 Config->add_instant_xml (node, get_user_ardour_path());
2956 Session::save_history (string snapshot_name)
2962 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2964 if (snapshot_name.empty()) {
2965 snapshot_name = _current_snapshot_name;
2968 xml_path = _path + snapshot_name + ".history";
2970 bak_path = xml_path + ".bak";
2972 if ((access (xml_path.c_str(), F_OK) == 0) &&
2973 (rename (xml_path.c_str(), bak_path.c_str())))
2975 error << _("could not backup old history file, current history not saved.") << endmsg;
2979 if (!tree.write (xml_path))
2981 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2983 /* don't leave a corrupt file lying around if it is
2987 if (unlink (xml_path.c_str())) {
2988 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2990 if (rename (bak_path.c_str(), xml_path.c_str()))
2992 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
3003 Session::restore_history (string snapshot_name)
3008 if (snapshot_name.empty()) {
3009 snapshot_name = _current_snapshot_name;
3013 xmlpath = _path + snapshot_name + ".history";
3014 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
3016 if (access (xmlpath.c_str(), F_OK)) {
3017 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
3021 if (!tree.read (xmlpath)) {
3022 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
3026 /* replace history */
3029 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3032 UndoTransaction* ut = new UndoTransaction ();
3035 ut->set_name(t->property("name")->value());
3036 stringstream ss(t->property("tv_sec")->value());
3038 ss.str(t->property("tv_usec")->value());
3040 ut->set_timestamp(tv);
3042 for (XMLNodeConstIterator child_it = t->children().begin();
3043 child_it != t->children().end();
3046 XMLNode *n = *child_it;
3049 if (n->name() == "MementoCommand" ||
3050 n->name() == "MementoUndoCommand" ||
3051 n->name() == "MementoRedoCommand") {
3053 if ((c = memento_command_factory(n))) {
3057 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3059 if ((c = global_state_command_factory (*n))) {
3060 ut->add_command (c);
3065 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3076 Session::config_changed (const char* parameter_name)
3078 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3080 if (PARAM_IS ("seamless-loop")) {
3082 } else if (PARAM_IS ("rf-speed")) {
3084 } else if (PARAM_IS ("auto-loop")) {
3086 } else if (PARAM_IS ("auto-input")) {
3088 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3089 /* auto-input only makes a difference if we're rolling */
3091 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3093 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3094 if ((*i)->record_enabled ()) {
3095 (*i)->monitor_input (!Config->get_auto_input());
3100 } else if (PARAM_IS ("punch-in")) {
3104 if ((location = _locations.auto_punch_location()) != 0) {
3106 if (Config->get_punch_in ()) {
3107 replace_event (Event::PunchIn, location->start());
3109 remove_event (location->start(), Event::PunchIn);
3113 } else if (PARAM_IS ("punch-out")) {
3117 if ((location = _locations.auto_punch_location()) != 0) {
3119 if (Config->get_punch_out()) {
3120 replace_event (Event::PunchOut, location->end());
3122 clear_events (Event::PunchOut);
3126 } else if (PARAM_IS ("edit-mode")) {
3128 Glib::Mutex::Lock lm (playlist_lock);
3130 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3131 (*i)->set_edit_mode (Config->get_edit_mode ());
3134 } else if (PARAM_IS ("use-video-sync")) {
3136 if (transport_stopped()) {
3137 if (Config->get_use_video_sync()) {
3138 waiting_for_sync_offset = true;
3142 } else if (PARAM_IS ("mmc-control")) {
3144 //poke_midi_thread ();
3146 } else if (PARAM_IS ("midi-control")) {
3148 //poke_midi_thread ();
3150 } else if (PARAM_IS ("raid-path")) {
3152 setup_raid_path (Config->get_raid_path());
3154 } else if (PARAM_IS ("smpte-format")) {
3158 } else if (PARAM_IS ("video-pullup")) {
3162 } else if (PARAM_IS ("seamless-loop")) {
3164 if (play_loop && transport_rolling()) {
3165 // to reset diskstreams etc
3166 request_play_loop (true);
3169 } else if (PARAM_IS ("rf-speed")) {
3171 cumulative_rf_motion = 0;
3174 } else if (PARAM_IS ("click-sound")) {
3176 setup_click_sounds (1);
3178 } else if (PARAM_IS ("click-emphasis-sound")) {
3180 setup_click_sounds (-1);
3182 } else if (PARAM_IS ("clicking")) {
3184 if (Config->get_clicking()) {
3185 if (_click_io && click_data) { // don't require emphasis data
3192 } else if (PARAM_IS ("send-mtc")) {
3194 /* only set the internal flag if we have
3198 if (_mtc_port != 0) {
3199 session_send_mtc = Config->get_send_mtc();
3200 if (session_send_mtc) {
3201 /* mark us ready to send */
3202 next_quarter_frame_to_send = 0;
3206 } else if (PARAM_IS ("send-mmc")) {
3208 /* only set the internal flag if we have
3212 if (_mmc_port != 0) {
3213 session_send_mmc = Config->get_send_mmc();
3216 } else if (PARAM_IS ("midi-feedback")) {
3218 /* only set the internal flag if we have
3222 if (_mtc_port != 0) {
3223 session_midi_feedback = Config->get_midi_feedback();
3226 } else if (PARAM_IS ("jack-time-master")) {
3228 engine().reset_timebase ();
3230 } else if (PARAM_IS ("native-file-header-format")) {
3232 if (!first_file_header_format_reset) {
3233 reset_native_file_format ();
3236 first_file_header_format_reset = false;
3238 } else if (PARAM_IS ("native-file-data-format")) {
3240 if (!first_file_data_format_reset) {
3241 reset_native_file_format ();
3244 first_file_data_format_reset = false;