2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #define __STDC_FORMAT_MACROS 1
28 #include <sigc++/bind.h>
30 #include <cstdio> /* snprintf(3) ... grrr */
45 #include <sys/param.h>
46 #include <sys/mount.h>
51 #include <midi++/mmc.h>
52 #include <midi++/port.h>
53 #include <pbd/error.h>
55 #include <glibmm/thread.h>
56 #include <pbd/pathscanner.h>
57 #include <pbd/pthread_utils.h>
58 #include <pbd/search_path.h>
59 #include <pbd/stacktrace.h>
60 #include <pbd/copyfile.h>
62 #include <ardour/audioengine.h>
63 #include <ardour/configuration.h>
64 #include <ardour/session.h>
65 #include <ardour/session_directory.h>
66 #include <ardour/session_utils.h>
67 #include <ardour/buffer.h>
68 #include <ardour/audio_diskstream.h>
69 #include <ardour/midi_diskstream.h>
70 #include <ardour/utils.h>
71 #include <ardour/audioplaylist.h>
72 #include <ardour/midi_playlist.h>
73 #include <ardour/smf_source.h>
74 #include <ardour/audiofilesource.h>
75 #include <ardour/silentfilesource.h>
76 #include <ardour/sndfilesource.h>
77 #include <ardour/midi_source.h>
78 #include <ardour/sndfile_helpers.h>
79 #include <ardour/auditioner.h>
80 #include <ardour/export.h>
81 #include <ardour/io_processor.h>
82 #include <ardour/send.h>
83 #include <ardour/processor.h>
84 #include <ardour/bundle.h>
85 #include <ardour/slave.h>
86 #include <ardour/tempo.h>
87 #include <ardour/audio_track.h>
88 #include <ardour/midi_track.h>
89 #include <ardour/cycle_timer.h>
90 #include <ardour/utils.h>
91 #include <ardour/named_selection.h>
92 #include <ardour/version.h>
93 #include <ardour/location.h>
94 #include <ardour/audioregion.h>
95 #include <ardour/midi_region.h>
96 #include <ardour/crossfade.h>
97 #include <ardour/control_protocol_manager.h>
98 #include <ardour/region_factory.h>
99 #include <ardour/source_factory.h>
100 #include <ardour/playlist_factory.h>
101 #include <ardour/filename_extensions.h>
102 #include <ardour/directory_names.h>
103 #include <ardour/template_utils.h>
105 #include <control_protocol/control_protocol.h>
111 using namespace ARDOUR;
115 Session::first_stage_init (string fullpath, string snapshot_name)
117 if (fullpath.length() == 0) {
119 throw failed_constructor();
122 char buf[PATH_MAX+1];
123 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
124 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
126 throw failed_constructor();
131 if (_path[_path.length()-1] != '/') {
135 /* these two are just provisional settings. set_state()
136 will likely override them.
139 _name = _current_snapshot_name = snapshot_name;
141 _current_frame_rate = _engine.frame_rate ();
142 _tempo_map = new TempoMap (_current_frame_rate);
143 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
145 g_atomic_int_set (&processing_prohibited, 0);
147 _transport_speed = 0;
148 _last_transport_speed = 0;
149 auto_play_legal = false;
150 transport_sub_state = 0;
151 _transport_frame = 0;
153 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
154 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
155 _end_location_is_free = true;
156 g_atomic_int_set (&_record_status, Disabled);
157 loop_changing = false;
159 _last_roll_location = 0;
160 _last_record_location = 0;
161 pending_locate_frame = 0;
162 pending_locate_roll = false;
163 pending_locate_flush = false;
164 dstream_buffer_size = 0;
166 state_was_pending = false;
168 outbound_mtc_smpte_frame = 0;
169 next_quarter_frame_to_send = -1;
170 current_block_size = 0;
171 solo_update_disabled = false;
172 currently_soloing = false;
173 _have_captured = false;
174 _worst_output_latency = 0;
175 _worst_input_latency = 0;
176 _worst_track_latency = 0;
177 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
179 butler_mixdown_buffer = 0;
180 butler_gain_buffer = 0;
182 session_send_mmc = false;
183 session_send_mtc = false;
184 post_transport_work = PostTransportWork (0);
185 g_atomic_int_set (&butler_should_do_transport_work, 0);
186 g_atomic_int_set (&butler_active, 0);
187 g_atomic_int_set (&_playback_load, 100);
188 g_atomic_int_set (&_capture_load, 100);
189 g_atomic_int_set (&_playback_load_min, 100);
190 g_atomic_int_set (&_capture_load_min, 100);
192 waiting_to_start = false;
194 _gain_automation_buffer = 0;
195 _pan_automation_buffer = 0;
197 pending_abort = false;
198 destructive_index = 0;
200 first_file_data_format_reset = true;
201 first_file_header_format_reset = true;
202 butler_thread = (pthread_t) 0;
203 //midi_thread = (pthread_t) 0;
205 AudioDiskstream::allocate_working_buffers();
207 /* default short fade = 15ms */
209 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
210 SndFileSource::setup_standard_crossfades (frame_rate());
212 last_mmc_step.tv_sec = 0;
213 last_mmc_step.tv_usec = 0;
216 /* click sounds are unset by default, which causes us to internal
217 waveforms for clicks.
221 click_emphasis_data = 0;
223 click_emphasis_length = 0;
226 process_function = &Session::process_with_events;
228 if (Config->get_use_video_sync()) {
229 waiting_for_sync_offset = true;
231 waiting_for_sync_offset = false;
234 _current_frame_rate = 48000;
235 _base_frame_rate = 48000;
239 _smpte_offset_negative = true;
240 last_smpte_valid = false;
244 last_rr_session_dir = session_dirs.begin();
245 refresh_disk_space ();
247 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
251 average_slave_delta = 1800;
252 have_first_delta_accumulator = false;
253 delta_accumulator_cnt = 0;
254 slave_state = Stopped;
256 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
258 /* These are all static "per-class" signals */
260 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
261 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
262 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
263 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
264 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
265 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
267 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
269 IO::MoreChannels.connect (mem_fun (*this, &Session::ensure_buffers));
271 /* stop IO objects from doing stuff until we're ready for them */
273 IO::disable_panners ();
274 IO::disable_ports ();
275 IO::disable_connecting ();
279 Session::second_stage_init (bool new_session)
281 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
284 if (load_state (_current_snapshot_name)) {
287 remove_empty_sounds ();
290 if (start_butler_thread()) {
294 /*if (start_midi_thread ()) {
298 // set_state() will call setup_raid_path(), but if it's a new session we need
299 // to call setup_raid_path() here.
301 if (set_state (*state_tree->root())) {
305 setup_raid_path(_path);
308 /* we can't save till after ::when_engine_running() is called,
309 because otherwise we save state with no connections made.
310 therefore, we reset _state_of_the_state because ::set_state()
311 will have cleared it.
313 we also have to include Loading so that any events that get
314 generated between here and the end of ::when_engine_running()
315 will be processed directly rather than queued.
318 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
320 // set_auto_input (true);
321 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
322 _locations.added.connect (mem_fun (this, &Session::locations_added));
323 setup_click_sounds (0);
324 setup_midi_control ();
326 /* Pay attention ... */
328 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
329 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
332 when_engine_running();
335 /* handle this one in a different way than all others, so that its clear what happened */
337 catch (AudioEngine::PortRegistrationFailure& err) {
338 error << _("Unable to create all required ports")
347 //send_full_time_code ();
348 _engine.transport_locate (0);
349 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
350 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
352 ControlProtocolManager::instance().set_session (*this);
355 _end_location_is_free = true;
357 _end_location_is_free = false;
364 Session::raid_path () const
366 SearchPath raid_search_path;
368 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
369 raid_search_path += sys::path((*i).path);
372 return raid_search_path.get_string ();
376 Session::setup_raid_path (string path)
385 session_dirs.clear ();
387 SearchPath search_path(path);
388 SearchPath sound_search_path;
389 SearchPath midi_search_path;
392 SearchPath::const_iterator i = search_path.begin();
393 i != search_path.end();
397 sp.path = (*i).to_string ();
398 sp.blocks = 0; // not needed
399 session_dirs.push_back (sp);
401 SessionDirectory sdir(sp.path);
403 sound_search_path += sdir.sound_path ();
404 midi_search_path += sdir.midi_path ();
407 // set the AudioFileSource and SMFSource search path
409 AudioFileSource::set_search_path (sound_search_path.get_string ());
410 SMFSource::set_search_path (midi_search_path.get_string ());
412 // reset the round-robin soundfile path thingie
414 last_rr_session_dir = session_dirs.begin();
418 Session::initialize_start_and_end_locations (nframes_t start, nframes_t end)
420 start_location->set_end (start);
421 _locations.add (start_location);
423 end_location->set_end (end);
424 _locations.add (end_location);
428 Session::create_session_file ()
430 _state_of_the_state = Clean;
432 if (save_state (_current_snapshot_name)) {
433 error << "Could not create new session file" << endmsg;
440 Session::create_session_file_from_template (const string& template_path)
442 string out_path = _path + _name + statefile_suffix;
444 if(!copy_file (template_path, out_path)) {
445 error << string_compose (_("Could not use session template %1 to create new session."), template_path)
453 Session::load_diskstreams (const XMLNode& node)
456 XMLNodeConstIterator citer;
458 clist = node.children();
460 for (citer = clist.begin(); citer != clist.end(); ++citer) {
463 /* diskstreams added automatically by DiskstreamCreated handler */
464 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
465 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
466 add_diskstream (dstream);
467 } else if ((*citer)->name() == "MidiDiskstream") {
468 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
469 add_diskstream (dstream);
471 error << _("Session: unknown diskstream type in XML") << endmsg;
475 catch (failed_constructor& err) {
476 error << _("Session: could not load diskstream via XML state") << endmsg;
485 Session::maybe_write_autosave()
487 if (dirty() && record_status() != Recording) {
488 save_state("", true);
493 Session::remove_pending_capture_state ()
498 xml_path += _current_snapshot_name;
499 xml_path += pending_suffix;
501 unlink (xml_path.c_str());
504 /** Rename a state file.
505 * @param snapshot_name Snapshot name.
508 Session::rename_state (string old_name, string new_name)
510 if (old_name == _current_snapshot_name || old_name == _name) {
511 /* refuse to rename the current snapshot or the "main" one */
515 const string old_xml_path = _path + old_name + statefile_suffix;
516 const string new_xml_path = _path + new_name + statefile_suffix;
518 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
519 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
523 /** Remove a state file.
524 * @param snapshot_name Snapshot name.
527 Session::remove_state (string snapshot_name)
529 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
530 /* refuse to remove the current snapshot or the "main" one */
534 const string xml_path = _path + snapshot_name + statefile_suffix;
536 /* make a backup copy of the state file */
537 const string bak_path = xml_path + ".bak";
538 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
539 copy_file (xml_path, bak_path);
543 unlink (xml_path.c_str());
547 Session::save_state (string snapshot_name, bool pending)
553 if (_state_of_the_state & CannotSave) {
557 if (!_engine.connected ()) {
558 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
563 /* tell sources we're saving first, in case they write out to a new file
564 * which should be saved with the state rather than the old one */
565 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
566 i->second->session_saved();
568 tree.set_root (&get_state());
570 if (snapshot_name.empty()) {
571 snapshot_name = _current_snapshot_name;
576 /* proper save: use statefile_suffix (.ardour in English) */
578 xml_path += snapshot_name;
579 xml_path += statefile_suffix;
581 /* make a backup copy of the old file */
585 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
586 copy_file (xml_path, bak_path);
591 /* pending save: use pending_suffix (.pending in English) */
593 xml_path += snapshot_name;
594 xml_path += pending_suffix;
601 tmp_path += snapshot_name;
604 // cerr << "actually writing state to " << xml_path << endl;
606 if (!tree.write (tmp_path)) {
607 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
608 unlink (tmp_path.c_str());
613 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
614 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
615 unlink (tmp_path.c_str());
622 save_history (snapshot_name);
624 bool was_dirty = dirty();
626 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
629 DirtyChanged (); /* EMIT SIGNAL */
632 StateSaved (snapshot_name); /* EMIT SIGNAL */
639 Session::restore_state (string snapshot_name)
641 if (load_state (snapshot_name) == 0) {
642 set_state (*state_tree->root());
649 Session::load_state (string snapshot_name)
656 state_was_pending = false;
658 /* check for leftover pending state from a crashed capture attempt */
660 sys::path xmlpath(_session_dir->root_path());
661 xmlpath /= snapshot_name + pending_suffix;
663 if (sys::exists (xmlpath)) {
665 /* there is pending state from a crashed capture attempt */
667 if (AskAboutPendingState()) {
668 state_was_pending = true;
672 if (!state_was_pending) {
673 xmlpath = _session_dir->root_path();
674 xmlpath /= snapshot_name + statefile_suffix;
677 if (!sys::exists (xmlpath)) {
678 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
682 state_tree = new XMLTree;
686 if (!state_tree->read (xmlpath.to_string())) {
687 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
693 XMLNode& root (*state_tree->root());
695 if (root.name() != X_("Session")) {
696 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
702 const XMLProperty* prop;
705 if ((prop = root.property ("version")) == 0) {
706 /* no version implies very old version of Ardour */
710 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
711 if (major_version < 2) {
718 sys::path backup_path(_session_dir->root_path());
720 backup_path /= snapshot_name + "-1" + statefile_suffix;
722 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
723 xmlpath.to_string(), backup_path.to_string())
726 copy_file (xmlpath.to_string(), backup_path.to_string());
728 /* if it fails, don't worry. right? */
735 Session::load_options (const XMLNode& node)
739 LocaleGuard lg (X_("POSIX"));
741 Config->set_variables (node, ConfigVariableBase::Session);
743 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
744 if ((prop = child->property ("val")) != 0) {
745 _end_location_is_free = (prop->value() == "yes");
753 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
755 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
756 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
758 return owner & modified_by_session_or_user;
762 Session::get_options () const
765 LocaleGuard lg (X_("POSIX"));
767 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
769 child = option_root.add_child ("end-marker-is-free");
770 child->add_property ("val", _end_location_is_free ? "yes" : "no");
782 Session::get_template()
784 /* if we don't disable rec-enable, diskstreams
785 will believe they need to store their capture
786 sources in their state node.
789 disable_record (false);
795 Session::state(bool full_state)
797 XMLNode* node = new XMLNode("Session");
800 // store libardour version, just in case
802 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
803 libardour_major_version, libardour_minor_version, libardour_micro_version);
804 node->add_property("version", string(buf));
806 /* store configuration settings */
811 node->add_property ("name", _name);
813 if (session_dirs.size() > 1) {
817 vector<space_and_path>::iterator i = session_dirs.begin();
818 vector<space_and_path>::iterator next;
820 ++i; /* skip the first one */
824 while (i != session_dirs.end()) {
828 if (next != session_dirs.end()) {
838 child = node->add_child ("Path");
839 child->add_content (p);
843 /* save the ID counter */
845 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
846 node->add_property ("id-counter", buf);
848 /* various options */
850 node->add_child_nocopy (get_options());
852 child = node->add_child ("Sources");
855 Glib::Mutex::Lock sl (source_lock);
857 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
859 /* Don't save information about AudioFileSources that are empty */
861 boost::shared_ptr<AudioFileSource> fs;
863 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
865 /* Don't save sources that are empty, unless they're destructive (which are OK
866 if they are empty, because we will re-use them every time.)
869 if (!fs->destructive()) {
870 if (fs->length() == 0) {
876 child->add_child_nocopy (siter->second->get_state());
880 child = node->add_child ("Regions");
883 Glib::Mutex::Lock rl (region_lock);
885 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
887 /* only store regions not attached to playlists */
889 if (i->second->playlist() == 0) {
890 child->add_child_nocopy (i->second->state (true));
895 child = node->add_child ("DiskStreams");
898 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
899 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
900 if (!(*i)->hidden()) {
901 child->add_child_nocopy ((*i)->get_state());
907 node->add_child_nocopy (_locations.get_state());
909 // for a template, just create a new Locations, populate it
910 // with the default start and end, and get the state for that.
912 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
913 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
916 end->set_end(compute_initial_length());
918 node->add_child_nocopy (loc.get_state());
921 child = node->add_child ("Connections");
923 Glib::Mutex::Lock lm (bundle_lock);
924 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
925 if (!(*i)->dynamic()) {
926 child->add_child_nocopy ((*i)->get_state());
931 child = node->add_child ("Routes");
933 boost::shared_ptr<RouteList> r = routes.reader ();
935 RoutePublicOrderSorter cmp;
936 RouteList public_order (*r);
937 public_order.sort (cmp);
939 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
940 if (!(*i)->is_hidden()) {
942 child->add_child_nocopy ((*i)->get_state());
944 child->add_child_nocopy ((*i)->get_template());
951 child = node->add_child ("EditGroups");
952 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
953 child->add_child_nocopy ((*i)->get_state());
956 child = node->add_child ("MixGroups");
957 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
958 child->add_child_nocopy ((*i)->get_state());
961 child = node->add_child ("Playlists");
962 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
963 if (!(*i)->hidden()) {
964 if (!(*i)->empty()) {
966 child->add_child_nocopy ((*i)->get_state());
968 child->add_child_nocopy ((*i)->get_template());
974 child = node->add_child ("UnusedPlaylists");
975 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
976 if (!(*i)->hidden()) {
977 if (!(*i)->empty()) {
979 child->add_child_nocopy ((*i)->get_state());
981 child->add_child_nocopy ((*i)->get_template());
989 child = node->add_child ("Click");
990 child->add_child_nocopy (_click_io->state (full_state));
994 child = node->add_child ("NamedSelections");
995 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
997 child->add_child_nocopy ((*i)->get_state());
1002 node->add_child_nocopy (_tempo_map->get_state());
1004 node->add_child_nocopy (get_control_protocol_state());
1007 node->add_child_copy (*_extra_xml);
1014 Session::get_control_protocol_state ()
1016 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1017 return cpm.get_state();
1021 Session::set_state (const XMLNode& node)
1025 const XMLProperty* prop;
1028 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1030 if (node.name() != X_("Session")){
1031 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1035 if ((prop = node.property ("name")) != 0) {
1036 _name = prop->value ();
1039 setup_raid_path(_path);
1041 if ((prop = node.property (X_("id-counter"))) != 0) {
1043 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1044 ID::init_counter (x);
1046 /* old sessions used a timebased counter, so fake
1047 the startup ID counter based on a standard
1052 ID::init_counter (now);
1056 IO::disable_ports ();
1057 IO::disable_connecting ();
1059 /* Object loading order:
1077 if (use_config_midi_ports ()) {
1080 if ((child = find_named_node (node, "extra")) != 0) {
1081 _extra_xml = new XMLNode (*child);
1084 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1085 load_options (*child);
1086 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1087 load_options (*child);
1089 error << _("Session: XML state has no options section") << endmsg;
1092 if ((child = find_named_node (node, "Locations")) == 0) {
1093 error << _("Session: XML state has no locations section") << endmsg;
1095 } else if (_locations.set_state (*child)) {
1101 if ((location = _locations.auto_loop_location()) != 0) {
1102 set_auto_loop_location (location);
1105 if ((location = _locations.auto_punch_location()) != 0) {
1106 set_auto_punch_location (location);
1109 if ((location = _locations.end_location()) == 0) {
1110 _locations.add (end_location);
1112 delete end_location;
1113 end_location = location;
1116 if ((location = _locations.start_location()) == 0) {
1117 _locations.add (start_location);
1119 delete start_location;
1120 start_location = location;
1123 AudioFileSource::set_header_position_offset (start_location->start());
1125 if ((child = find_named_node (node, "Sources")) == 0) {
1126 error << _("Session: XML state has no sources section") << endmsg;
1128 } else if (load_sources (*child)) {
1132 if ((child = find_named_node (node, "Regions")) == 0) {
1133 error << _("Session: XML state has no Regions section") << endmsg;
1135 } else if (load_regions (*child)) {
1139 if ((child = find_named_node (node, "Playlists")) == 0) {
1140 error << _("Session: XML state has no playlists section") << endmsg;
1142 } else if (load_playlists (*child)) {
1146 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1148 } else if (load_unused_playlists (*child)) {
1152 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1153 if (load_named_selections (*child)) {
1158 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1159 error << _("Session: XML state has no diskstreams section") << endmsg;
1161 } else if (load_diskstreams (*child)) {
1165 if ((child = find_named_node (node, "Connections")) == 0) {
1166 error << _("Session: XML state has no connections section") << endmsg;
1168 } else if (load_bundles (*child)) {
1172 if ((child = find_named_node (node, "EditGroups")) == 0) {
1173 error << _("Session: XML state has no edit groups section") << endmsg;
1175 } else if (load_edit_groups (*child)) {
1179 if ((child = find_named_node (node, "MixGroups")) == 0) {
1180 error << _("Session: XML state has no mix groups section") << endmsg;
1182 } else if (load_mix_groups (*child)) {
1186 if ((child = find_named_node (node, "TempoMap")) == 0) {
1187 error << _("Session: XML state has no Tempo Map section") << endmsg;
1189 } else if (_tempo_map->set_state (*child)) {
1193 if ((child = find_named_node (node, "Routes")) == 0) {
1194 error << _("Session: XML state has no routes section") << endmsg;
1196 } else if (load_routes (*child)) {
1200 if ((child = find_named_node (node, "Click")) == 0) {
1201 warning << _("Session: XML state has no click section") << endmsg;
1202 } else if (_click_io) {
1203 _click_io->set_state (*child);
1206 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1207 ControlProtocolManager::instance().set_protocol_states (*child);
1210 /* here beginneth the second phase ... */
1212 StateReady (); /* EMIT SIGNAL */
1214 _state_of_the_state = Clean;
1216 if (state_was_pending) {
1217 save_state (_current_snapshot_name);
1218 remove_pending_capture_state ();
1219 state_was_pending = 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());
1348 if ((prop = node.property ("name")) == 0) {
1349 cerr << "no name for this region\n";
1353 if ((prop = node.property (X_("source-0"))) == 0) {
1354 if ((prop = node.property ("source")) == 0) {
1355 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1356 return boost::shared_ptr<AudioRegion>();
1360 PBD::ID s_id (prop->value());
1362 if ((source = source_by_id (s_id)) == 0) {
1363 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1364 return boost::shared_ptr<AudioRegion>();
1367 as = boost::dynamic_pointer_cast<AudioSource>(source);
1369 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1370 return boost::shared_ptr<AudioRegion>();
1373 sources.push_back (as);
1375 /* pickup other channels */
1377 for (uint32_t n=1; n < nchans; ++n) {
1378 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1379 if ((prop = node.property (buf)) != 0) {
1381 PBD::ID id2 (prop->value());
1383 if ((source = source_by_id (id2)) == 0) {
1384 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1385 return boost::shared_ptr<AudioRegion>();
1388 as = boost::dynamic_pointer_cast<AudioSource>(source);
1390 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1391 return boost::shared_ptr<AudioRegion>();
1393 sources.push_back (as);
1398 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1400 /* a final detail: this is the one and only place that we know how long missing files are */
1402 if (region->whole_file()) {
1403 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1404 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1406 sfp->set_length (region->length());
1415 catch (failed_constructor& err) {
1416 return boost::shared_ptr<AudioRegion>();
1420 boost::shared_ptr<MidiRegion>
1421 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1423 const XMLProperty* prop;
1424 boost::shared_ptr<Source> source;
1425 boost::shared_ptr<MidiSource> ms;
1427 uint32_t nchans = 1;
1429 if (node.name() != X_("Region")) {
1430 return boost::shared_ptr<MidiRegion>();
1433 if ((prop = node.property (X_("channels"))) != 0) {
1434 nchans = atoi (prop->value().c_str());
1437 if ((prop = node.property ("name")) == 0) {
1438 cerr << "no name for this region\n";
1442 // Multiple midi channels? that's just crazy talk
1443 assert(nchans == 1);
1445 if ((prop = node.property (X_("source-0"))) == 0) {
1446 if ((prop = node.property ("source")) == 0) {
1447 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1448 return boost::shared_ptr<MidiRegion>();
1452 PBD::ID s_id (prop->value());
1454 if ((source = source_by_id (s_id)) == 0) {
1455 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1456 return boost::shared_ptr<MidiRegion>();
1459 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1461 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1462 return boost::shared_ptr<MidiRegion>();
1465 sources.push_back (ms);
1468 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1469 /* a final detail: this is the one and only place that we know how long missing files are */
1471 if (region->whole_file()) {
1472 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1473 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1475 sfp->set_length (region->length());
1483 catch (failed_constructor& err) {
1484 return boost::shared_ptr<MidiRegion>();
1489 Session::get_sources_as_xml ()
1492 XMLNode* node = new XMLNode (X_("Sources"));
1493 Glib::Mutex::Lock lm (source_lock);
1495 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1496 node->add_child_nocopy (i->second->get_state());
1503 Session::path_from_region_name (DataType type, string name, string identifier)
1505 char buf[PATH_MAX+1];
1507 SessionDirectory sdir(get_best_session_directory_for_new_source());
1508 string sound_dir = ((type == DataType::AUDIO)
1509 ? sdir.sound_path().to_string()
1510 : sdir.midi_path().to_string());
1512 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1514 for (n = 0; n < 999999; ++n) {
1515 if (identifier.length()) {
1516 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1517 identifier.c_str(), n, ext.c_str());
1519 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1523 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1528 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1537 Session::load_sources (const XMLNode& node)
1540 XMLNodeConstIterator niter;
1541 boost::shared_ptr<Source> source;
1543 nlist = node.children();
1547 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1550 if ((source = XMLSourceFactory (**niter)) == 0) {
1551 error << _("Session: cannot create Source from XML description.") << endmsg;
1555 catch (non_existent_source& err) {
1556 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1557 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1564 boost::shared_ptr<Source>
1565 Session::XMLSourceFactory (const XMLNode& node)
1567 if (node.name() != "Source") {
1568 return boost::shared_ptr<Source>();
1572 return SourceFactory::create (*this, node);
1575 catch (failed_constructor& err) {
1576 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1577 return boost::shared_ptr<Source>();
1582 Session::save_template (string template_name)
1585 string xml_path, bak_path, template_path;
1587 if (_state_of_the_state & CannotSave) {
1591 sys::path user_template_dir(user_template_directory());
1595 sys::create_directories (user_template_dir);
1597 catch(sys::filesystem_error& ex)
1599 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1600 user_template_dir.to_string(), ex.what()) << endmsg;
1604 tree.set_root (&get_template());
1606 sys::path template_file_path(user_template_dir);
1607 template_file_path /= template_name + template_suffix;
1609 if (sys::exists (template_file_path))
1611 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1612 template_file_path.to_string()) << endmsg;
1616 if (!tree.write (template_file_path.to_string())) {
1617 error << _("mix template not saved") << endmsg;
1625 Session::refresh_disk_space ()
1628 struct statfs statfsbuf;
1629 vector<space_and_path>::iterator i;
1630 Glib::Mutex::Lock lm (space_lock);
1633 /* get freespace on every FS that is part of the session path */
1635 _total_free_4k_blocks = 0;
1637 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1638 statfs ((*i).path.c_str(), &statfsbuf);
1640 scale = statfsbuf.f_bsize/4096.0;
1642 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1643 _total_free_4k_blocks += (*i).blocks;
1649 Session::get_best_session_directory_for_new_source ()
1651 vector<space_and_path>::iterator i;
1652 string result = _session_dir->root_path().to_string();
1654 /* handle common case without system calls */
1656 if (session_dirs.size() == 1) {
1660 /* OK, here's the algorithm we're following here:
1662 We want to select which directory to use for
1663 the next file source to be created. Ideally,
1664 we'd like to use a round-robin process so as to
1665 get maximum performance benefits from splitting
1666 the files across multiple disks.
1668 However, in situations without much diskspace, an
1669 RR approach may end up filling up a filesystem
1670 with new files while others still have space.
1671 Its therefore important to pay some attention to
1672 the freespace in the filesystem holding each
1673 directory as well. However, if we did that by
1674 itself, we'd keep creating new files in the file
1675 system with the most space until it was as full
1676 as all others, thus negating any performance
1677 benefits of this RAID-1 like approach.
1679 So, we use a user-configurable space threshold. If
1680 there are at least 2 filesystems with more than this
1681 much space available, we use RR selection between them.
1682 If not, then we pick the filesystem with the most space.
1684 This gets a good balance between the two
1688 refresh_disk_space ();
1690 int free_enough = 0;
1692 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1693 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1698 if (free_enough >= 2) {
1699 /* use RR selection process, ensuring that the one
1703 i = last_rr_session_dir;
1706 if (++i == session_dirs.end()) {
1707 i = session_dirs.begin();
1710 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1711 if (create_session_directory ((*i).path)) {
1713 last_rr_session_dir = i;
1718 } while (i != last_rr_session_dir);
1722 /* pick FS with the most freespace (and that
1723 seems to actually work ...)
1726 vector<space_and_path> sorted;
1727 space_and_path_ascending_cmp cmp;
1729 sorted = session_dirs;
1730 sort (sorted.begin(), sorted.end(), cmp);
1732 for (i = sorted.begin(); i != sorted.end(); ++i) {
1733 if (create_session_directory ((*i).path)) {
1735 last_rr_session_dir = i;
1745 Session::load_playlists (const XMLNode& node)
1748 XMLNodeConstIterator niter;
1749 boost::shared_ptr<Playlist> playlist;
1751 nlist = node.children();
1755 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1757 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1758 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1766 Session::load_unused_playlists (const XMLNode& node)
1769 XMLNodeConstIterator niter;
1770 boost::shared_ptr<Playlist> playlist;
1772 nlist = node.children();
1776 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1778 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1779 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1783 // now manually untrack it
1785 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1791 boost::shared_ptr<Playlist>
1792 Session::XMLPlaylistFactory (const XMLNode& node)
1795 return PlaylistFactory::create (*this, node);
1798 catch (failed_constructor& err) {
1799 return boost::shared_ptr<Playlist>();
1804 Session::load_named_selections (const XMLNode& node)
1807 XMLNodeConstIterator niter;
1810 nlist = node.children();
1814 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1816 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1817 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1825 Session::XMLNamedSelectionFactory (const XMLNode& node)
1828 return new NamedSelection (*this, node);
1831 catch (failed_constructor& err) {
1837 Session::automation_dir () const
1840 res += "automation/";
1845 Session::load_bundles (const XMLNode& node)
1847 XMLNodeList nlist = node.children();
1848 XMLNodeConstIterator niter;
1852 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1853 if ((*niter)->name() == "InputConnection") {
1854 add_bundle (new ARDOUR::InputBundle (**niter));
1855 } else if ((*niter)->name() == "OutputConnection") {
1856 add_bundle (new ARDOUR::OutputBundle (**niter));
1858 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1867 Session::load_edit_groups (const XMLNode& node)
1869 return load_route_groups (node, true);
1873 Session::load_mix_groups (const XMLNode& node)
1875 return load_route_groups (node, false);
1879 Session::load_route_groups (const XMLNode& node, bool edit)
1881 XMLNodeList nlist = node.children();
1882 XMLNodeConstIterator niter;
1887 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1888 if ((*niter)->name() == "RouteGroup") {
1890 rg = add_edit_group ("");
1891 rg->set_state (**niter);
1893 rg = add_mix_group ("");
1894 rg->set_state (**niter);
1903 state_file_filter (const string &str, void *arg)
1905 return (str.length() > strlen(statefile_suffix) &&
1906 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
1910 bool operator()(const string* a, const string* b) {
1916 remove_end(string* state)
1918 string statename(*state);
1920 string::size_type start,end;
1921 if ((start = statename.find_last_of ('/')) != string::npos) {
1922 statename = statename.substr (start+1);
1925 if ((end = statename.rfind(".ardour")) == string::npos) {
1926 end = statename.length();
1929 return new string(statename.substr (0, end));
1933 Session::possible_states (string path)
1935 PathScanner scanner;
1936 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
1938 transform(states->begin(), states->end(), states->begin(), remove_end);
1941 sort (states->begin(), states->end(), cmp);
1947 Session::possible_states () const
1949 return possible_states(_path);
1953 Session::auto_save()
1955 save_state (_current_snapshot_name);
1959 Session::add_edit_group (string name)
1961 RouteGroup* rg = new RouteGroup (*this, name);
1962 edit_groups.push_back (rg);
1963 edit_group_added (rg); /* EMIT SIGNAL */
1969 Session::add_mix_group (string name)
1971 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
1972 mix_groups.push_back (rg);
1973 mix_group_added (rg); /* EMIT SIGNAL */
1979 Session::remove_edit_group (RouteGroup& rg)
1981 list<RouteGroup*>::iterator i;
1983 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
1984 (*i)->apply (&Route::drop_edit_group, this);
1985 edit_groups.erase (i);
1986 edit_group_removed (); /* EMIT SIGNAL */
1993 Session::remove_mix_group (RouteGroup& rg)
1995 list<RouteGroup*>::iterator i;
1997 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
1998 (*i)->apply (&Route::drop_mix_group, this);
1999 mix_groups.erase (i);
2000 mix_group_removed (); /* EMIT SIGNAL */
2007 Session::mix_group_by_name (string name)
2009 list<RouteGroup *>::iterator i;
2011 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2012 if ((*i)->name() == name) {
2020 Session::edit_group_by_name (string name)
2022 list<RouteGroup *>::iterator i;
2024 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2025 if ((*i)->name() == name) {
2033 Session::begin_reversible_command (const string& name)
2035 current_trans = new UndoTransaction;
2036 current_trans->set_name (name);
2040 Session::commit_reversible_command (Command *cmd)
2045 current_trans->add_command (cmd);
2048 gettimeofday (&now, 0);
2049 current_trans->set_timestamp (now);
2051 _history.add (current_trans);
2054 Session::GlobalRouteBooleanState
2055 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2057 GlobalRouteBooleanState s;
2058 boost::shared_ptr<RouteList> r = routes.reader ();
2060 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2061 if (!(*i)->is_hidden()) {
2062 RouteBooleanState v;
2065 Route* r = (*i).get();
2066 v.second = (r->*method)();
2075 Session::GlobalRouteMeterState
2076 Session::get_global_route_metering ()
2078 GlobalRouteMeterState s;
2079 boost::shared_ptr<RouteList> r = routes.reader ();
2081 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2082 if (!(*i)->is_hidden()) {
2086 v.second = (*i)->meter_point();
2096 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2098 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2100 boost::shared_ptr<Route> r = (i->first.lock());
2103 r->set_meter_point (i->second, arg);
2109 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2111 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2113 boost::shared_ptr<Route> r = (i->first.lock());
2116 Route* rp = r.get();
2117 (rp->*method) (i->second, arg);
2123 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2125 set_global_route_boolean (s, &Route::set_mute, src);
2129 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2131 set_global_route_boolean (s, &Route::set_solo, src);
2135 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2137 set_global_route_boolean (s, &Route::set_record_enable, src);
2142 Session::global_mute_memento (void* src)
2144 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2148 Session::global_metering_memento (void* src)
2150 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2154 Session::global_solo_memento (void* src)
2156 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2160 Session::global_record_enable_memento (void* src)
2162 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2167 accept_all_non_peak_files (const string& path, void *arg)
2169 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2173 accept_all_state_files (const string& path, void *arg)
2175 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2179 Session::find_all_sources (string path, set<string>& result)
2184 if (!tree.read (path)) {
2188 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2193 XMLNodeConstIterator niter;
2195 nlist = node->children();
2199 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2203 if ((prop = (*niter)->property (X_("name"))) == 0) {
2207 if (prop->value()[0] == '/') {
2208 /* external file, ignore */
2212 sys::path source_path = _session_dir->sound_path ();
2214 source_path /= prop->value ();
2216 result.insert (source_path.to_string ());
2223 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2225 PathScanner scanner;
2226 vector<string*>* state_files;
2228 string this_snapshot_path;
2234 if (ripped[ripped.length()-1] == '/') {
2235 ripped = ripped.substr (0, ripped.length() - 1);
2238 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2240 if (state_files == 0) {
2245 this_snapshot_path = _path;
2246 this_snapshot_path += _current_snapshot_name;
2247 this_snapshot_path += statefile_suffix;
2249 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2251 if (exclude_this_snapshot && **i == this_snapshot_path) {
2255 if (find_all_sources (**i, result) < 0) {
2263 struct RegionCounter {
2264 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2265 AudioSourceList::iterator iter;
2266 boost::shared_ptr<Region> region;
2269 RegionCounter() : count (0) {}
2273 Session::cleanup_sources (Session::cleanup_report& rep)
2275 // FIXME: needs adaptation to midi
2277 vector<boost::shared_ptr<Source> > dead_sources;
2278 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2279 PathScanner scanner;
2281 vector<space_and_path>::iterator i;
2282 vector<space_and_path>::iterator nexti;
2283 vector<string*>* soundfiles;
2284 vector<string> unused;
2285 set<string> all_sources;
2290 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2292 /* step 1: consider deleting all unused playlists */
2294 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2297 status = AskAboutPlaylistDeletion (*x);
2306 playlists_tbd.push_back (*x);
2310 /* leave it alone */
2315 /* now delete any that were marked for deletion */
2317 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2318 (*x)->drop_references ();
2321 playlists_tbd.clear ();
2323 /* step 2: find all un-used sources */
2328 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2330 SourceMap::iterator tmp;
2335 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2339 if (!i->second->used() && i->second->length() > 0) {
2340 dead_sources.push_back (i->second);
2341 i->second->GoingAway();
2347 /* build a list of all the possible sound directories for the session */
2349 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2354 SessionDirectory sdir ((*i).path);
2355 sound_path += sdir.sound_path().to_string();
2357 if (nexti != session_dirs.end()) {
2364 /* now do the same thing for the files that ended up in the sounds dir(s)
2365 but are not referenced as sources in any snapshot.
2368 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2370 if (soundfiles == 0) {
2374 /* find all sources, but don't use this snapshot because the
2375 state file on disk still references sources we may have already
2379 find_all_sources_across_snapshots (all_sources, true);
2381 /* add our current source list
2384 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2385 boost::shared_ptr<AudioFileSource> fs;
2387 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2388 all_sources.insert (fs->path());
2392 char tmppath1[PATH_MAX+1];
2393 char tmppath2[PATH_MAX+1];
2395 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2400 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2402 realpath(spath.c_str(), tmppath1);
2403 realpath((*i).c_str(), tmppath2);
2405 if (strcmp(tmppath1, tmppath2) == 0) {
2412 unused.push_back (spath);
2416 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2418 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2419 struct stat statbuf;
2421 rep.paths.push_back (*x);
2422 if (stat ((*x).c_str(), &statbuf) == 0) {
2423 rep.space += statbuf.st_size;
2428 /* don't move the file across filesystems, just
2429 stick it in the `dead_sound_dir_name' directory
2430 on whichever filesystem it was already on.
2433 if ((*x).find ("/sounds/") != string::npos) {
2435 /* old school, go up 1 level */
2437 newpath = Glib::path_get_dirname (*x); // "sounds"
2438 newpath = Glib::path_get_dirname (newpath); // "session-name"
2442 /* new school, go up 4 levels */
2444 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2445 newpath = Glib::path_get_dirname (newpath); // "session-name"
2446 newpath = Glib::path_get_dirname (newpath); // "interchange"
2447 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2451 newpath += dead_sound_dir_name;
2453 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2454 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2459 newpath += Glib::path_get_basename ((*x));
2461 if (access (newpath.c_str(), F_OK) == 0) {
2463 /* the new path already exists, try versioning */
2465 char buf[PATH_MAX+1];
2469 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2472 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2473 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2477 if (version == 999) {
2478 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2482 newpath = newpath_v;
2487 /* it doesn't exist, or we can't read it or something */
2491 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2492 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2493 (*x), newpath, strerror (errno))
2498 /* see if there an easy to find peakfile for this file, and remove it.
2501 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2502 peakpath += peakfile_suffix;
2504 if (access (peakpath.c_str(), W_OK) == 0) {
2505 if (::unlink (peakpath.c_str()) != 0) {
2506 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2507 peakpath, _path, strerror (errno))
2509 /* try to back out */
2510 rename (newpath.c_str(), _path.c_str());
2518 /* dump the history list */
2522 /* save state so we don't end up a session file
2523 referring to non-existent sources.
2529 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2534 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2536 // FIXME: needs adaptation for MIDI
2538 vector<space_and_path>::iterator i;
2539 string dead_sound_dir;
2540 struct dirent* dentry;
2541 struct stat statbuf;
2547 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2549 dead_sound_dir = (*i).path;
2550 dead_sound_dir += dead_sound_dir_name;
2552 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2556 while ((dentry = readdir (dead)) != 0) {
2558 /* avoid '.' and '..' */
2560 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2561 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2567 fullpath = dead_sound_dir;
2569 fullpath += dentry->d_name;
2571 if (stat (fullpath.c_str(), &statbuf)) {
2575 if (!S_ISREG (statbuf.st_mode)) {
2579 if (unlink (fullpath.c_str())) {
2580 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2581 fullpath, strerror (errno))
2585 rep.paths.push_back (dentry->d_name);
2586 rep.space += statbuf.st_size;
2597 Session::set_dirty ()
2599 bool was_dirty = dirty();
2601 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2604 DirtyChanged(); /* EMIT SIGNAL */
2610 Session::set_clean ()
2612 bool was_dirty = dirty();
2614 _state_of_the_state = Clean;
2617 DirtyChanged(); /* EMIT SIGNAL */
2622 Session::set_deletion_in_progress ()
2624 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2628 Session::add_controllable (boost::shared_ptr<Controllable> c)
2630 /* this adds a controllable to the list managed by the Session.
2631 this is a subset of those managed by the Controllable class
2632 itself, and represents the only ones whose state will be saved
2633 as part of the session.
2636 Glib::Mutex::Lock lm (controllables_lock);
2637 controllables.insert (c);
2640 struct null_deleter { void operator()(void const *) const {} };
2643 Session::remove_controllable (Controllable* c)
2645 if (_state_of_the_state | Deletion) {
2649 Glib::Mutex::Lock lm (controllables_lock);
2651 Controllables::iterator x = controllables.find(
2652 boost::shared_ptr<Controllable>(c, null_deleter()));
2654 if (x != controllables.end()) {
2655 controllables.erase (x);
2659 boost::shared_ptr<Controllable>
2660 Session::controllable_by_id (const PBD::ID& id)
2662 Glib::Mutex::Lock lm (controllables_lock);
2664 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2665 if ((*i)->id() == id) {
2670 return boost::shared_ptr<Controllable>();
2674 Session::add_instant_xml (XMLNode& node)
2676 Stateful::add_instant_xml (node, _path);
2677 Config->add_instant_xml (node);
2681 Session::instant_xml (const string& node_name)
2683 return Stateful::instant_xml (node_name, _path);
2687 Session::save_history (string snapshot_name)
2693 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2695 if (snapshot_name.empty()) {
2696 snapshot_name = _current_snapshot_name;
2699 xml_path = _path + snapshot_name + ".history";
2701 bak_path = xml_path + ".bak";
2703 if ((access (xml_path.c_str(), F_OK) == 0) &&
2704 (rename (xml_path.c_str(), bak_path.c_str())))
2706 error << _("could not backup old history file, current history not saved.") << endmsg;
2710 if (!tree.write (xml_path))
2712 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2714 /* don't leave a corrupt file lying around if it is
2718 if (unlink (xml_path.c_str())) {
2719 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2721 if (rename (bak_path.c_str(), xml_path.c_str()))
2723 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2734 Session::restore_history (string snapshot_name)
2739 if (snapshot_name.empty()) {
2740 snapshot_name = _current_snapshot_name;
2744 xmlpath = _path + snapshot_name + ".history";
2745 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2747 if (access (xmlpath.c_str(), F_OK)) {
2748 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2752 if (!tree.read (xmlpath)) {
2753 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2757 /* replace history */
2760 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2763 UndoTransaction* ut = new UndoTransaction ();
2766 ut->set_name(t->property("name")->value());
2767 stringstream ss(t->property("tv_sec")->value());
2769 ss.str(t->property("tv_usec")->value());
2771 ut->set_timestamp(tv);
2773 for (XMLNodeConstIterator child_it = t->children().begin();
2774 child_it != t->children().end();
2777 XMLNode *n = *child_it;
2780 if (n->name() == "MementoCommand" ||
2781 n->name() == "MementoUndoCommand" ||
2782 n->name() == "MementoRedoCommand") {
2784 if ((c = memento_command_factory(n))) {
2788 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2790 if ((c = global_state_command_factory (*n))) {
2791 ut->add_command (c);
2796 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2807 Session::config_changed (const char* parameter_name)
2809 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2811 if (PARAM_IS ("seamless-loop")) {
2813 } else if (PARAM_IS ("rf-speed")) {
2815 } else if (PARAM_IS ("auto-loop")) {
2817 } else if (PARAM_IS ("auto-input")) {
2819 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2820 /* auto-input only makes a difference if we're rolling */
2822 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2824 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2825 if ((*i)->record_enabled ()) {
2826 (*i)->monitor_input (!Config->get_auto_input());
2831 } else if (PARAM_IS ("punch-in")) {
2835 if ((location = _locations.auto_punch_location()) != 0) {
2837 if (Config->get_punch_in ()) {
2838 replace_event (Event::PunchIn, location->start());
2840 remove_event (location->start(), Event::PunchIn);
2844 } else if (PARAM_IS ("punch-out")) {
2848 if ((location = _locations.auto_punch_location()) != 0) {
2850 if (Config->get_punch_out()) {
2851 replace_event (Event::PunchOut, location->end());
2853 clear_events (Event::PunchOut);
2857 } else if (PARAM_IS ("edit-mode")) {
2859 Glib::Mutex::Lock lm (playlist_lock);
2861 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2862 (*i)->set_edit_mode (Config->get_edit_mode ());
2865 } else if (PARAM_IS ("use-video-sync")) {
2867 waiting_for_sync_offset = Config->get_use_video_sync();
2869 } else if (PARAM_IS ("mmc-control")) {
2871 //poke_midi_thread ();
2873 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
2876 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
2879 } else if (PARAM_IS ("mmc-send-id")) {
2882 mmc->set_send_device_id (Config->get_mmc_send_device_id());
2885 } else if (PARAM_IS ("midi-control")) {
2887 //poke_midi_thread ();
2889 } else if (PARAM_IS ("raid-path")) {
2891 setup_raid_path (Config->get_raid_path());
2893 } else if (PARAM_IS ("smpte-format")) {
2897 } else if (PARAM_IS ("video-pullup")) {
2901 } else if (PARAM_IS ("seamless-loop")) {
2903 if (play_loop && transport_rolling()) {
2904 // to reset diskstreams etc
2905 request_play_loop (true);
2908 } else if (PARAM_IS ("rf-speed")) {
2910 cumulative_rf_motion = 0;
2913 } else if (PARAM_IS ("click-sound")) {
2915 setup_click_sounds (1);
2917 } else if (PARAM_IS ("click-emphasis-sound")) {
2919 setup_click_sounds (-1);
2921 } else if (PARAM_IS ("clicking")) {
2923 if (Config->get_clicking()) {
2924 if (_click_io && click_data) { // don't require emphasis data
2931 } else if (PARAM_IS ("send-mtc")) {
2933 /* only set the internal flag if we have
2937 if (_mtc_port != 0) {
2938 session_send_mtc = Config->get_send_mtc();
2939 if (session_send_mtc) {
2940 /* mark us ready to send */
2941 next_quarter_frame_to_send = 0;
2944 session_send_mtc = false;
2947 } else if (PARAM_IS ("send-mmc")) {
2949 /* only set the internal flag if we have
2953 if (_mmc_port != 0) {
2954 session_send_mmc = Config->get_send_mmc();
2957 session_send_mmc = false;
2960 } else if (PARAM_IS ("midi-feedback")) {
2962 /* only set the internal flag if we have
2966 if (_mtc_port != 0) {
2967 session_midi_feedback = Config->get_midi_feedback();
2970 } else if (PARAM_IS ("jack-time-master")) {
2972 engine().reset_timebase ();
2974 } else if (PARAM_IS ("native-file-header-format")) {
2976 if (!first_file_header_format_reset) {
2977 reset_native_file_format ();
2980 first_file_header_format_reset = false;
2982 } else if (PARAM_IS ("native-file-data-format")) {
2984 if (!first_file_data_format_reset) {
2985 reset_native_file_format ();
2988 first_file_data_format_reset = false;
2990 } else if (PARAM_IS ("slave-source")) {
2991 set_slave_source (Config->get_slave_source());
2992 } else if (PARAM_IS ("remote-model")) {
2993 set_remote_control_ids ();
2994 } else if (PARAM_IS ("denormal-model")) {