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>
61 #include <ardour/audioengine.h>
62 #include <ardour/configuration.h>
63 #include <ardour/session.h>
64 #include <ardour/session_directory.h>
65 #include <ardour/session_utils.h>
66 #include <ardour/session_state_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.to_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.to_string ());
410 SMFSource::set_search_path (midi_search_path.to_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 sys::path session_file_path(_session_dir->root_path());
444 session_file_path /= _name + statefile_suffix;
448 sys::copy_file (template_path, session_file_path);
450 catch(sys::filesystem_error& ex)
452 error << string_compose (_("Could not use session template %1 to create new session (%2)."),
453 template_path, ex.what())
461 Session::load_diskstreams (const XMLNode& node)
464 XMLNodeConstIterator citer;
466 clist = node.children();
468 for (citer = clist.begin(); citer != clist.end(); ++citer) {
471 /* diskstreams added automatically by DiskstreamCreated handler */
472 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
473 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
474 add_diskstream (dstream);
475 } else if ((*citer)->name() == "MidiDiskstream") {
476 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
477 add_diskstream (dstream);
479 error << _("Session: unknown diskstream type in XML") << endmsg;
483 catch (failed_constructor& err) {
484 error << _("Session: could not load diskstream via XML state") << endmsg;
493 Session::maybe_write_autosave()
495 if (dirty() && record_status() != Recording) {
496 save_state("", true);
501 Session::remove_pending_capture_state ()
503 sys::path pending_state_file_path(_session_dir->root_path());
505 pending_state_file_path /= _current_snapshot_name + pending_suffix;
509 sys::remove (pending_state_file_path);
511 catch(sys::filesystem_error& ex)
513 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
514 pending_state_file_path.to_string(), ex.what()) << endmsg;
518 /** Rename a state file.
519 * @param snapshot_name Snapshot name.
522 Session::rename_state (string old_name, string new_name)
524 if (old_name == _current_snapshot_name || old_name == _name) {
525 /* refuse to rename the current snapshot or the "main" one */
529 const string old_xml_path = _path + old_name + statefile_suffix;
530 const string new_xml_path = _path + new_name + statefile_suffix;
532 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
533 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
537 /** Remove a state file.
538 * @param snapshot_name Snapshot name.
541 Session::remove_state (string snapshot_name)
543 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
544 // refuse to remove the current snapshot or the "main" one
548 sys::path xml_path(_session_dir->root_path());
550 xml_path /= snapshot_name + statefile_suffix;
552 if (!create_backup_file (xml_path)) {
553 // don't remove it if a backup can't be made
554 // create_backup_file will log the error.
559 sys::remove (xml_path);
563 Session::save_state (string snapshot_name, bool pending)
566 sys::path xml_path(_session_dir->root_path());
568 if (_state_of_the_state & CannotSave) {
572 if (!_engine.connected ()) {
573 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
578 /* tell sources we're saving first, in case they write out to a new file
579 * which should be saved with the state rather than the old one */
580 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
581 i->second->session_saved();
583 tree.set_root (&get_state());
585 if (snapshot_name.empty()) {
586 snapshot_name = _current_snapshot_name;
591 /* proper save: use statefile_suffix (.ardour in English) */
593 xml_path /= snapshot_name + statefile_suffix;
595 /* make a backup copy of the old file */
597 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
598 // create_backup_file will log the error
604 /* pending save: use pending_suffix (.pending in English) */
605 xml_path /= snapshot_name + pending_suffix;
608 sys::path tmp_path(_session_dir->root_path());
610 tmp_path /= snapshot_name + temp_suffix;
612 // cerr << "actually writing state to " << xml_path.to_string() << endl;
614 if (!tree.write (tmp_path.to_string())) {
615 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
616 sys::remove (tmp_path);
621 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
622 error << string_compose (_("could not rename temporary session file %1 to %2"),
623 tmp_path.to_string(), xml_path.to_string()) << endmsg;
624 sys::remove (tmp_path);
631 save_history (snapshot_name);
633 bool was_dirty = dirty();
635 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
638 DirtyChanged (); /* EMIT SIGNAL */
641 StateSaved (snapshot_name); /* EMIT SIGNAL */
648 Session::restore_state (string snapshot_name)
650 if (load_state (snapshot_name) == 0) {
651 set_state (*state_tree->root());
658 Session::load_state (string snapshot_name)
665 state_was_pending = false;
667 /* check for leftover pending state from a crashed capture attempt */
669 sys::path xmlpath(_session_dir->root_path());
670 xmlpath /= snapshot_name + pending_suffix;
672 if (sys::exists (xmlpath)) {
674 /* there is pending state from a crashed capture attempt */
676 if (AskAboutPendingState()) {
677 state_was_pending = true;
681 if (!state_was_pending) {
682 xmlpath = _session_dir->root_path();
683 xmlpath /= snapshot_name + statefile_suffix;
686 if (!sys::exists (xmlpath)) {
687 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
691 state_tree = new XMLTree;
695 if (!state_tree->read (xmlpath.to_string())) {
696 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
702 XMLNode& root (*state_tree->root());
704 if (root.name() != X_("Session")) {
705 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
711 const XMLProperty* prop;
714 if ((prop = root.property ("version")) == 0) {
715 /* no version implies very old version of Ardour */
719 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
720 if (major_version < 2) {
727 sys::path backup_path(_session_dir->root_path());
729 backup_path /= snapshot_name + "-1" + statefile_suffix;
731 // only create a backup once
732 if (sys::exists (backup_path)) {
736 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
737 xmlpath.to_string(), backup_path.to_string())
742 sys::copy_file (xmlpath, backup_path);
744 catch(sys::filesystem_error& ex)
746 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
747 xmlpath.to_string(), ex.what())
757 Session::load_options (const XMLNode& node)
761 LocaleGuard lg (X_("POSIX"));
763 Config->set_variables (node, ConfigVariableBase::Session);
765 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
766 if ((prop = child->property ("val")) != 0) {
767 _end_location_is_free = (prop->value() == "yes");
775 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
777 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
778 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
780 return owner & modified_by_session_or_user;
784 Session::get_options () const
787 LocaleGuard lg (X_("POSIX"));
789 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
791 child = option_root.add_child ("end-marker-is-free");
792 child->add_property ("val", _end_location_is_free ? "yes" : "no");
804 Session::get_template()
806 /* if we don't disable rec-enable, diskstreams
807 will believe they need to store their capture
808 sources in their state node.
811 disable_record (false);
817 Session::state(bool full_state)
819 XMLNode* node = new XMLNode("Session");
822 // store libardour version, just in case
824 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
825 libardour_major_version, libardour_minor_version, libardour_micro_version);
826 node->add_property("version", string(buf));
828 /* store configuration settings */
833 node->add_property ("name", _name);
835 if (session_dirs.size() > 1) {
839 vector<space_and_path>::iterator i = session_dirs.begin();
840 vector<space_and_path>::iterator next;
842 ++i; /* skip the first one */
846 while (i != session_dirs.end()) {
850 if (next != session_dirs.end()) {
860 child = node->add_child ("Path");
861 child->add_content (p);
865 /* save the ID counter */
867 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
868 node->add_property ("id-counter", buf);
870 /* various options */
872 node->add_child_nocopy (get_options());
874 child = node->add_child ("Sources");
877 Glib::Mutex::Lock sl (source_lock);
879 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
881 /* Don't save information about AudioFileSources that are empty */
883 boost::shared_ptr<AudioFileSource> fs;
885 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
887 /* Don't save sources that are empty, unless they're destructive (which are OK
888 if they are empty, because we will re-use them every time.)
891 if (!fs->destructive()) {
892 if (fs->length() == 0) {
898 child->add_child_nocopy (siter->second->get_state());
902 child = node->add_child ("Regions");
905 Glib::Mutex::Lock rl (region_lock);
907 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
909 /* only store regions not attached to playlists */
911 if (i->second->playlist() == 0) {
912 child->add_child_nocopy (i->second->state (true));
917 child = node->add_child ("DiskStreams");
920 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
921 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
922 if (!(*i)->hidden()) {
923 child->add_child_nocopy ((*i)->get_state());
929 node->add_child_nocopy (_locations.get_state());
931 // for a template, just create a new Locations, populate it
932 // with the default start and end, and get the state for that.
934 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
935 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
938 end->set_end(compute_initial_length());
940 node->add_child_nocopy (loc.get_state());
943 child = node->add_child ("Connections");
945 Glib::Mutex::Lock lm (bundle_lock);
946 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
947 if (!(*i)->dynamic()) {
948 child->add_child_nocopy ((*i)->get_state());
953 child = node->add_child ("Routes");
955 boost::shared_ptr<RouteList> r = routes.reader ();
957 RoutePublicOrderSorter cmp;
958 RouteList public_order (*r);
959 public_order.sort (cmp);
961 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
962 if (!(*i)->is_hidden()) {
964 child->add_child_nocopy ((*i)->get_state());
966 child->add_child_nocopy ((*i)->get_template());
973 child = node->add_child ("EditGroups");
974 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
975 child->add_child_nocopy ((*i)->get_state());
978 child = node->add_child ("MixGroups");
979 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
980 child->add_child_nocopy ((*i)->get_state());
983 child = node->add_child ("Playlists");
984 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
985 if (!(*i)->hidden()) {
986 if (!(*i)->empty()) {
988 child->add_child_nocopy ((*i)->get_state());
990 child->add_child_nocopy ((*i)->get_template());
996 child = node->add_child ("UnusedPlaylists");
997 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
998 if (!(*i)->hidden()) {
999 if (!(*i)->empty()) {
1001 child->add_child_nocopy ((*i)->get_state());
1003 child->add_child_nocopy ((*i)->get_template());
1011 child = node->add_child ("Click");
1012 child->add_child_nocopy (_click_io->state (full_state));
1016 child = node->add_child ("NamedSelections");
1017 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1019 child->add_child_nocopy ((*i)->get_state());
1024 node->add_child_nocopy (_tempo_map->get_state());
1026 node->add_child_nocopy (get_control_protocol_state());
1029 node->add_child_copy (*_extra_xml);
1036 Session::get_control_protocol_state ()
1038 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1039 return cpm.get_state();
1043 Session::set_state (const XMLNode& node)
1047 const XMLProperty* prop;
1050 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1052 if (node.name() != X_("Session")){
1053 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1057 if ((prop = node.property ("name")) != 0) {
1058 _name = prop->value ();
1061 setup_raid_path(_session_dir->root_path().to_string());
1063 if ((prop = node.property (X_("id-counter"))) != 0) {
1065 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1066 ID::init_counter (x);
1068 /* old sessions used a timebased counter, so fake
1069 the startup ID counter based on a standard
1074 ID::init_counter (now);
1078 IO::disable_ports ();
1079 IO::disable_connecting ();
1081 /* Object loading order:
1099 if (use_config_midi_ports ()) {
1102 if ((child = find_named_node (node, "extra")) != 0) {
1103 _extra_xml = new XMLNode (*child);
1106 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1107 load_options (*child);
1108 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1109 load_options (*child);
1111 error << _("Session: XML state has no options section") << endmsg;
1114 if ((child = find_named_node (node, "Locations")) == 0) {
1115 error << _("Session: XML state has no locations section") << endmsg;
1117 } else if (_locations.set_state (*child)) {
1123 if ((location = _locations.auto_loop_location()) != 0) {
1124 set_auto_loop_location (location);
1127 if ((location = _locations.auto_punch_location()) != 0) {
1128 set_auto_punch_location (location);
1131 if ((location = _locations.end_location()) == 0) {
1132 _locations.add (end_location);
1134 delete end_location;
1135 end_location = location;
1138 if ((location = _locations.start_location()) == 0) {
1139 _locations.add (start_location);
1141 delete start_location;
1142 start_location = location;
1145 AudioFileSource::set_header_position_offset (start_location->start());
1147 if ((child = find_named_node (node, "Sources")) == 0) {
1148 error << _("Session: XML state has no sources section") << endmsg;
1150 } else if (load_sources (*child)) {
1154 if ((child = find_named_node (node, "Regions")) == 0) {
1155 error << _("Session: XML state has no Regions section") << endmsg;
1157 } else if (load_regions (*child)) {
1161 if ((child = find_named_node (node, "Playlists")) == 0) {
1162 error << _("Session: XML state has no playlists section") << endmsg;
1164 } else if (load_playlists (*child)) {
1168 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1170 } else if (load_unused_playlists (*child)) {
1174 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1175 if (load_named_selections (*child)) {
1180 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1181 error << _("Session: XML state has no diskstreams section") << endmsg;
1183 } else if (load_diskstreams (*child)) {
1187 if ((child = find_named_node (node, "Connections")) == 0) {
1188 error << _("Session: XML state has no connections section") << endmsg;
1190 } else if (load_bundles (*child)) {
1194 if ((child = find_named_node (node, "EditGroups")) == 0) {
1195 error << _("Session: XML state has no edit groups section") << endmsg;
1197 } else if (load_edit_groups (*child)) {
1201 if ((child = find_named_node (node, "MixGroups")) == 0) {
1202 error << _("Session: XML state has no mix groups section") << endmsg;
1204 } else if (load_mix_groups (*child)) {
1208 if ((child = find_named_node (node, "TempoMap")) == 0) {
1209 error << _("Session: XML state has no Tempo Map section") << endmsg;
1211 } else if (_tempo_map->set_state (*child)) {
1215 if ((child = find_named_node (node, "Routes")) == 0) {
1216 error << _("Session: XML state has no routes section") << endmsg;
1218 } else if (load_routes (*child)) {
1222 if ((child = find_named_node (node, "Click")) == 0) {
1223 warning << _("Session: XML state has no click section") << endmsg;
1224 } else if (_click_io) {
1225 _click_io->set_state (*child);
1228 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1229 ControlProtocolManager::instance().set_protocol_states (*child);
1232 /* here beginneth the second phase ... */
1234 StateReady (); /* EMIT SIGNAL */
1236 _state_of_the_state = Clean;
1238 if (state_was_pending) {
1239 save_state (_current_snapshot_name);
1240 remove_pending_capture_state ();
1241 state_was_pending = false;
1251 Session::load_routes (const XMLNode& node)
1254 XMLNodeConstIterator niter;
1255 RouteList new_routes;
1257 nlist = node.children();
1261 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1263 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1266 error << _("Session: cannot create Route from XML description.") << endmsg;
1270 new_routes.push_back (route);
1273 add_routes (new_routes);
1278 boost::shared_ptr<Route>
1279 Session::XMLRouteFactory (const XMLNode& node)
1281 if (node.name() != "Route") {
1282 return boost::shared_ptr<Route> ((Route*) 0);
1285 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1287 DataType type = DataType::AUDIO;
1288 const XMLProperty* prop = node.property("default-type");
1290 type = DataType(prop->value());
1292 assert(type != DataType::NIL);
1294 if (has_diskstream) {
1295 if (type == DataType::AUDIO) {
1296 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1299 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1303 boost::shared_ptr<Route> ret (new Route (*this, node));
1309 Session::load_regions (const XMLNode& node)
1312 XMLNodeConstIterator niter;
1313 boost::shared_ptr<Region> region;
1315 nlist = node.children();
1319 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1320 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1321 error << _("Session: cannot create Region from XML description.") << endmsg;
1328 boost::shared_ptr<Region>
1329 Session::XMLRegionFactory (const XMLNode& node, bool full)
1331 const XMLProperty* type = node.property("type");
1335 if ( !type || type->value() == "audio" ) {
1337 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1339 } else if (type->value() == "midi") {
1341 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1345 } catch (failed_constructor& err) {
1346 return boost::shared_ptr<Region> ();
1349 return boost::shared_ptr<Region> ();
1352 boost::shared_ptr<AudioRegion>
1353 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1355 const XMLProperty* prop;
1356 boost::shared_ptr<Source> source;
1357 boost::shared_ptr<AudioSource> as;
1359 uint32_t nchans = 1;
1362 if (node.name() != X_("Region")) {
1363 return boost::shared_ptr<AudioRegion>();
1366 if ((prop = node.property (X_("channels"))) != 0) {
1367 nchans = atoi (prop->value().c_str());
1370 if ((prop = node.property ("name")) == 0) {
1371 cerr << "no name for this region\n";
1375 if ((prop = node.property (X_("source-0"))) == 0) {
1376 if ((prop = node.property ("source")) == 0) {
1377 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1378 return boost::shared_ptr<AudioRegion>();
1382 PBD::ID s_id (prop->value());
1384 if ((source = source_by_id (s_id)) == 0) {
1385 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1386 return boost::shared_ptr<AudioRegion>();
1389 as = boost::dynamic_pointer_cast<AudioSource>(source);
1391 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1392 return boost::shared_ptr<AudioRegion>();
1395 sources.push_back (as);
1397 /* pickup other channels */
1399 for (uint32_t n=1; n < nchans; ++n) {
1400 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1401 if ((prop = node.property (buf)) != 0) {
1403 PBD::ID id2 (prop->value());
1405 if ((source = source_by_id (id2)) == 0) {
1406 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1407 return boost::shared_ptr<AudioRegion>();
1410 as = boost::dynamic_pointer_cast<AudioSource>(source);
1412 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1413 return boost::shared_ptr<AudioRegion>();
1415 sources.push_back (as);
1420 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1422 /* a final detail: this is the one and only place that we know how long missing files are */
1424 if (region->whole_file()) {
1425 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1426 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1428 sfp->set_length (region->length());
1437 catch (failed_constructor& err) {
1438 return boost::shared_ptr<AudioRegion>();
1442 boost::shared_ptr<MidiRegion>
1443 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1445 const XMLProperty* prop;
1446 boost::shared_ptr<Source> source;
1447 boost::shared_ptr<MidiSource> ms;
1449 uint32_t nchans = 1;
1451 if (node.name() != X_("Region")) {
1452 return boost::shared_ptr<MidiRegion>();
1455 if ((prop = node.property (X_("channels"))) != 0) {
1456 nchans = atoi (prop->value().c_str());
1459 if ((prop = node.property ("name")) == 0) {
1460 cerr << "no name for this region\n";
1464 // Multiple midi channels? that's just crazy talk
1465 assert(nchans == 1);
1467 if ((prop = node.property (X_("source-0"))) == 0) {
1468 if ((prop = node.property ("source")) == 0) {
1469 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1470 return boost::shared_ptr<MidiRegion>();
1474 PBD::ID s_id (prop->value());
1476 if ((source = source_by_id (s_id)) == 0) {
1477 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1478 return boost::shared_ptr<MidiRegion>();
1481 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1483 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1484 return boost::shared_ptr<MidiRegion>();
1487 sources.push_back (ms);
1490 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1491 /* a final detail: this is the one and only place that we know how long missing files are */
1493 if (region->whole_file()) {
1494 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1495 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1497 sfp->set_length (region->length());
1505 catch (failed_constructor& err) {
1506 return boost::shared_ptr<MidiRegion>();
1511 Session::get_sources_as_xml ()
1514 XMLNode* node = new XMLNode (X_("Sources"));
1515 Glib::Mutex::Lock lm (source_lock);
1517 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1518 node->add_child_nocopy (i->second->get_state());
1525 Session::path_from_region_name (DataType type, string name, string identifier)
1527 char buf[PATH_MAX+1];
1529 SessionDirectory sdir(get_best_session_directory_for_new_source());
1530 string sound_dir = ((type == DataType::AUDIO)
1531 ? sdir.sound_path().to_string()
1532 : sdir.midi_path().to_string());
1534 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1536 for (n = 0; n < 999999; ++n) {
1537 if (identifier.length()) {
1538 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1539 identifier.c_str(), n, ext.c_str());
1541 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1545 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1550 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1559 Session::load_sources (const XMLNode& node)
1562 XMLNodeConstIterator niter;
1563 boost::shared_ptr<Source> source;
1565 nlist = node.children();
1569 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1572 if ((source = XMLSourceFactory (**niter)) == 0) {
1573 error << _("Session: cannot create Source from XML description.") << endmsg;
1577 catch (non_existent_source& err) {
1578 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1579 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1586 boost::shared_ptr<Source>
1587 Session::XMLSourceFactory (const XMLNode& node)
1589 if (node.name() != "Source") {
1590 return boost::shared_ptr<Source>();
1594 return SourceFactory::create (*this, node);
1597 catch (failed_constructor& err) {
1598 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1599 return boost::shared_ptr<Source>();
1604 Session::save_template (string template_name)
1608 if (_state_of_the_state & CannotSave) {
1612 sys::path user_template_dir(user_template_directory());
1616 sys::create_directories (user_template_dir);
1618 catch(sys::filesystem_error& ex)
1620 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1621 user_template_dir.to_string(), ex.what()) << endmsg;
1625 tree.set_root (&get_template());
1627 sys::path template_file_path(user_template_dir);
1628 template_file_path /= template_name + template_suffix;
1630 if (sys::exists (template_file_path))
1632 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1633 template_file_path.to_string()) << endmsg;
1637 if (!tree.write (template_file_path.to_string())) {
1638 error << _("mix template not saved") << endmsg;
1646 Session::refresh_disk_space ()
1649 struct statfs statfsbuf;
1650 vector<space_and_path>::iterator i;
1651 Glib::Mutex::Lock lm (space_lock);
1654 /* get freespace on every FS that is part of the session path */
1656 _total_free_4k_blocks = 0;
1658 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1659 statfs ((*i).path.c_str(), &statfsbuf);
1661 scale = statfsbuf.f_bsize/4096.0;
1663 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1664 _total_free_4k_blocks += (*i).blocks;
1670 Session::get_best_session_directory_for_new_source ()
1672 vector<space_and_path>::iterator i;
1673 string result = _session_dir->root_path().to_string();
1675 /* handle common case without system calls */
1677 if (session_dirs.size() == 1) {
1681 /* OK, here's the algorithm we're following here:
1683 We want to select which directory to use for
1684 the next file source to be created. Ideally,
1685 we'd like to use a round-robin process so as to
1686 get maximum performance benefits from splitting
1687 the files across multiple disks.
1689 However, in situations without much diskspace, an
1690 RR approach may end up filling up a filesystem
1691 with new files while others still have space.
1692 Its therefore important to pay some attention to
1693 the freespace in the filesystem holding each
1694 directory as well. However, if we did that by
1695 itself, we'd keep creating new files in the file
1696 system with the most space until it was as full
1697 as all others, thus negating any performance
1698 benefits of this RAID-1 like approach.
1700 So, we use a user-configurable space threshold. If
1701 there are at least 2 filesystems with more than this
1702 much space available, we use RR selection between them.
1703 If not, then we pick the filesystem with the most space.
1705 This gets a good balance between the two
1709 refresh_disk_space ();
1711 int free_enough = 0;
1713 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1714 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1719 if (free_enough >= 2) {
1720 /* use RR selection process, ensuring that the one
1724 i = last_rr_session_dir;
1727 if (++i == session_dirs.end()) {
1728 i = session_dirs.begin();
1731 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1732 if (create_session_directory ((*i).path)) {
1734 last_rr_session_dir = i;
1739 } while (i != last_rr_session_dir);
1743 /* pick FS with the most freespace (and that
1744 seems to actually work ...)
1747 vector<space_and_path> sorted;
1748 space_and_path_ascending_cmp cmp;
1750 sorted = session_dirs;
1751 sort (sorted.begin(), sorted.end(), cmp);
1753 for (i = sorted.begin(); i != sorted.end(); ++i) {
1754 if (create_session_directory ((*i).path)) {
1756 last_rr_session_dir = i;
1766 Session::load_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;
1787 Session::load_unused_playlists (const XMLNode& node)
1790 XMLNodeConstIterator niter;
1791 boost::shared_ptr<Playlist> playlist;
1793 nlist = node.children();
1797 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1799 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1800 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1804 // now manually untrack it
1806 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1812 boost::shared_ptr<Playlist>
1813 Session::XMLPlaylistFactory (const XMLNode& node)
1816 return PlaylistFactory::create (*this, node);
1819 catch (failed_constructor& err) {
1820 return boost::shared_ptr<Playlist>();
1825 Session::load_named_selections (const XMLNode& node)
1828 XMLNodeConstIterator niter;
1831 nlist = node.children();
1835 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1837 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1838 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1846 Session::XMLNamedSelectionFactory (const XMLNode& node)
1849 return new NamedSelection (*this, node);
1852 catch (failed_constructor& err) {
1858 Session::automation_dir () const
1861 res += "automation/";
1866 Session::load_bundles (const XMLNode& node)
1868 XMLNodeList nlist = node.children();
1869 XMLNodeConstIterator niter;
1873 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1874 if ((*niter)->name() == "InputConnection") {
1875 add_bundle (new ARDOUR::InputBundle (**niter));
1876 } else if ((*niter)->name() == "OutputConnection") {
1877 add_bundle (new ARDOUR::OutputBundle (**niter));
1879 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1888 Session::load_edit_groups (const XMLNode& node)
1890 return load_route_groups (node, true);
1894 Session::load_mix_groups (const XMLNode& node)
1896 return load_route_groups (node, false);
1900 Session::load_route_groups (const XMLNode& node, bool edit)
1902 XMLNodeList nlist = node.children();
1903 XMLNodeConstIterator niter;
1908 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1909 if ((*niter)->name() == "RouteGroup") {
1911 rg = add_edit_group ("");
1912 rg->set_state (**niter);
1914 rg = add_mix_group ("");
1915 rg->set_state (**niter);
1924 Session::auto_save()
1926 save_state (_current_snapshot_name);
1930 Session::add_edit_group (string name)
1932 RouteGroup* rg = new RouteGroup (*this, name);
1933 edit_groups.push_back (rg);
1934 edit_group_added (rg); /* EMIT SIGNAL */
1940 Session::add_mix_group (string name)
1942 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
1943 mix_groups.push_back (rg);
1944 mix_group_added (rg); /* EMIT SIGNAL */
1950 Session::remove_edit_group (RouteGroup& rg)
1952 list<RouteGroup*>::iterator i;
1954 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
1955 (*i)->apply (&Route::drop_edit_group, this);
1956 edit_groups.erase (i);
1957 edit_group_removed (); /* EMIT SIGNAL */
1964 Session::remove_mix_group (RouteGroup& rg)
1966 list<RouteGroup*>::iterator i;
1968 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
1969 (*i)->apply (&Route::drop_mix_group, this);
1970 mix_groups.erase (i);
1971 mix_group_removed (); /* EMIT SIGNAL */
1978 Session::mix_group_by_name (string name)
1980 list<RouteGroup *>::iterator i;
1982 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1983 if ((*i)->name() == name) {
1991 Session::edit_group_by_name (string name)
1993 list<RouteGroup *>::iterator i;
1995 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1996 if ((*i)->name() == name) {
2004 Session::begin_reversible_command (const string& name)
2006 current_trans = new UndoTransaction;
2007 current_trans->set_name (name);
2011 Session::commit_reversible_command (Command *cmd)
2016 current_trans->add_command (cmd);
2019 gettimeofday (&now, 0);
2020 current_trans->set_timestamp (now);
2022 _history.add (current_trans);
2025 Session::GlobalRouteBooleanState
2026 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2028 GlobalRouteBooleanState s;
2029 boost::shared_ptr<RouteList> r = routes.reader ();
2031 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2032 if (!(*i)->is_hidden()) {
2033 RouteBooleanState v;
2036 Route* r = (*i).get();
2037 v.second = (r->*method)();
2046 Session::GlobalRouteMeterState
2047 Session::get_global_route_metering ()
2049 GlobalRouteMeterState s;
2050 boost::shared_ptr<RouteList> r = routes.reader ();
2052 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2053 if (!(*i)->is_hidden()) {
2057 v.second = (*i)->meter_point();
2067 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2069 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2071 boost::shared_ptr<Route> r = (i->first.lock());
2074 r->set_meter_point (i->second, arg);
2080 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2082 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2084 boost::shared_ptr<Route> r = (i->first.lock());
2087 Route* rp = r.get();
2088 (rp->*method) (i->second, arg);
2094 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2096 set_global_route_boolean (s, &Route::set_mute, src);
2100 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2102 set_global_route_boolean (s, &Route::set_solo, src);
2106 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2108 set_global_route_boolean (s, &Route::set_record_enable, src);
2113 Session::global_mute_memento (void* src)
2115 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2119 Session::global_metering_memento (void* src)
2121 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2125 Session::global_solo_memento (void* src)
2127 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2131 Session::global_record_enable_memento (void* src)
2133 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2138 accept_all_non_peak_files (const string& path, void *arg)
2140 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2144 accept_all_state_files (const string& path, void *arg)
2146 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2150 Session::find_all_sources (string path, set<string>& result)
2155 if (!tree.read (path)) {
2159 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2164 XMLNodeConstIterator niter;
2166 nlist = node->children();
2170 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2174 if ((prop = (*niter)->property (X_("name"))) == 0) {
2178 if (prop->value()[0] == '/') {
2179 /* external file, ignore */
2183 sys::path source_path = _session_dir->sound_path ();
2185 source_path /= prop->value ();
2187 result.insert (source_path.to_string ());
2194 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2196 PathScanner scanner;
2197 vector<string*>* state_files;
2199 string this_snapshot_path;
2205 if (ripped[ripped.length()-1] == '/') {
2206 ripped = ripped.substr (0, ripped.length() - 1);
2209 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2211 if (state_files == 0) {
2216 this_snapshot_path = _path;
2217 this_snapshot_path += _current_snapshot_name;
2218 this_snapshot_path += statefile_suffix;
2220 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2222 if (exclude_this_snapshot && **i == this_snapshot_path) {
2226 if (find_all_sources (**i, result) < 0) {
2234 struct RegionCounter {
2235 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2236 AudioSourceList::iterator iter;
2237 boost::shared_ptr<Region> region;
2240 RegionCounter() : count (0) {}
2244 Session::cleanup_sources (Session::cleanup_report& rep)
2246 // FIXME: needs adaptation to midi
2248 vector<boost::shared_ptr<Source> > dead_sources;
2249 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2250 PathScanner scanner;
2252 vector<space_and_path>::iterator i;
2253 vector<space_and_path>::iterator nexti;
2254 vector<string*>* soundfiles;
2255 vector<string> unused;
2256 set<string> all_sources;
2261 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2263 /* step 1: consider deleting all unused playlists */
2265 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2268 status = AskAboutPlaylistDeletion (*x);
2277 playlists_tbd.push_back (*x);
2281 /* leave it alone */
2286 /* now delete any that were marked for deletion */
2288 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2289 (*x)->drop_references ();
2292 playlists_tbd.clear ();
2294 /* step 2: find all un-used sources */
2299 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2301 SourceMap::iterator tmp;
2306 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2310 if (!i->second->used() && i->second->length() > 0) {
2311 dead_sources.push_back (i->second);
2312 i->second->GoingAway();
2318 /* build a list of all the possible sound directories for the session */
2320 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2325 SessionDirectory sdir ((*i).path);
2326 sound_path += sdir.sound_path().to_string();
2328 if (nexti != session_dirs.end()) {
2335 /* now do the same thing for the files that ended up in the sounds dir(s)
2336 but are not referenced as sources in any snapshot.
2339 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2341 if (soundfiles == 0) {
2345 /* find all sources, but don't use this snapshot because the
2346 state file on disk still references sources we may have already
2350 find_all_sources_across_snapshots (all_sources, true);
2352 /* add our current source list
2355 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2356 boost::shared_ptr<AudioFileSource> fs;
2358 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2359 all_sources.insert (fs->path());
2363 char tmppath1[PATH_MAX+1];
2364 char tmppath2[PATH_MAX+1];
2366 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2371 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2373 realpath(spath.c_str(), tmppath1);
2374 realpath((*i).c_str(), tmppath2);
2376 if (strcmp(tmppath1, tmppath2) == 0) {
2383 unused.push_back (spath);
2387 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2389 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2390 struct stat statbuf;
2392 rep.paths.push_back (*x);
2393 if (stat ((*x).c_str(), &statbuf) == 0) {
2394 rep.space += statbuf.st_size;
2399 /* don't move the file across filesystems, just
2400 stick it in the `dead_sound_dir_name' directory
2401 on whichever filesystem it was already on.
2404 if ((*x).find ("/sounds/") != string::npos) {
2406 /* old school, go up 1 level */
2408 newpath = Glib::path_get_dirname (*x); // "sounds"
2409 newpath = Glib::path_get_dirname (newpath); // "session-name"
2413 /* new school, go up 4 levels */
2415 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2416 newpath = Glib::path_get_dirname (newpath); // "session-name"
2417 newpath = Glib::path_get_dirname (newpath); // "interchange"
2418 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2422 newpath += dead_sound_dir_name;
2424 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2425 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2430 newpath += Glib::path_get_basename ((*x));
2432 if (access (newpath.c_str(), F_OK) == 0) {
2434 /* the new path already exists, try versioning */
2436 char buf[PATH_MAX+1];
2440 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2443 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2444 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2448 if (version == 999) {
2449 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2453 newpath = newpath_v;
2458 /* it doesn't exist, or we can't read it or something */
2462 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2463 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2464 (*x), newpath, strerror (errno))
2469 /* see if there an easy to find peakfile for this file, and remove it.
2472 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2473 peakpath += peakfile_suffix;
2475 if (access (peakpath.c_str(), W_OK) == 0) {
2476 if (::unlink (peakpath.c_str()) != 0) {
2477 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2478 peakpath, _path, strerror (errno))
2480 /* try to back out */
2481 rename (newpath.c_str(), _path.c_str());
2489 /* dump the history list */
2493 /* save state so we don't end up a session file
2494 referring to non-existent sources.
2500 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2505 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2507 // FIXME: needs adaptation for MIDI
2509 vector<space_and_path>::iterator i;
2510 string dead_sound_dir;
2511 struct dirent* dentry;
2512 struct stat statbuf;
2518 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2520 dead_sound_dir = (*i).path;
2521 dead_sound_dir += dead_sound_dir_name;
2523 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2527 while ((dentry = readdir (dead)) != 0) {
2529 /* avoid '.' and '..' */
2531 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2532 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2538 fullpath = dead_sound_dir;
2540 fullpath += dentry->d_name;
2542 if (stat (fullpath.c_str(), &statbuf)) {
2546 if (!S_ISREG (statbuf.st_mode)) {
2550 if (unlink (fullpath.c_str())) {
2551 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2552 fullpath, strerror (errno))
2556 rep.paths.push_back (dentry->d_name);
2557 rep.space += statbuf.st_size;
2568 Session::set_dirty ()
2570 bool was_dirty = dirty();
2572 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2575 DirtyChanged(); /* EMIT SIGNAL */
2581 Session::set_clean ()
2583 bool was_dirty = dirty();
2585 _state_of_the_state = Clean;
2588 DirtyChanged(); /* EMIT SIGNAL */
2593 Session::set_deletion_in_progress ()
2595 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2599 Session::add_controllable (boost::shared_ptr<Controllable> c)
2601 /* this adds a controllable to the list managed by the Session.
2602 this is a subset of those managed by the Controllable class
2603 itself, and represents the only ones whose state will be saved
2604 as part of the session.
2607 Glib::Mutex::Lock lm (controllables_lock);
2608 controllables.insert (c);
2611 struct null_deleter { void operator()(void const *) const {} };
2614 Session::remove_controllable (Controllable* c)
2616 if (_state_of_the_state | Deletion) {
2620 Glib::Mutex::Lock lm (controllables_lock);
2622 Controllables::iterator x = controllables.find(
2623 boost::shared_ptr<Controllable>(c, null_deleter()));
2625 if (x != controllables.end()) {
2626 controllables.erase (x);
2630 boost::shared_ptr<Controllable>
2631 Session::controllable_by_id (const PBD::ID& id)
2633 Glib::Mutex::Lock lm (controllables_lock);
2635 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2636 if ((*i)->id() == id) {
2641 return boost::shared_ptr<Controllable>();
2645 Session::add_instant_xml (XMLNode& node)
2647 Stateful::add_instant_xml (node, _path);
2648 Config->add_instant_xml (node);
2652 Session::instant_xml (const string& node_name)
2654 return Stateful::instant_xml (node_name, _path);
2658 Session::save_history (string snapshot_name)
2662 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2664 if (snapshot_name.empty()) {
2665 snapshot_name = _current_snapshot_name;
2668 const string history_filename = snapshot_name + history_suffix;
2669 const string backup_filename = history_filename + backup_suffix;
2670 const sys::path xml_path = _session_dir->root_path() / history_filename;
2671 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2673 if (sys::exists (xml_path)) {
2676 sys::rename (xml_path, backup_path);
2678 catch (const sys::filesystem_error& err)
2680 error << _("could not backup old history file, current history not saved") << endmsg;
2685 if (!tree.write (xml_path.to_string()))
2687 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2691 sys::remove (xml_path);
2692 sys::rename (backup_path, xml_path);
2694 catch (const sys::filesystem_error& err)
2696 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2697 backup_path.to_string(), err.what()) << endmsg;
2707 Session::restore_history (string snapshot_name)
2711 if (snapshot_name.empty()) {
2712 snapshot_name = _current_snapshot_name;
2715 const string xml_filename = snapshot_name + history_suffix;
2716 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2718 info << string_compose(_("Loading history from '%1'."), xml_path.to_string()) << endmsg;
2720 if (!sys::exists (xml_path)) {
2721 info << string_compose (_("%1: no history file \"%2\" for this session."),
2722 _name, xml_path.to_string()) << endmsg;
2726 if (!tree.read (xml_path.to_string())) {
2727 error << string_compose (_("Could not understand session history file \"%1\""),
2728 xml_path.to_string()) << endmsg;
2735 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2738 UndoTransaction* ut = new UndoTransaction ();
2741 ut->set_name(t->property("name")->value());
2742 stringstream ss(t->property("tv_sec")->value());
2744 ss.str(t->property("tv_usec")->value());
2746 ut->set_timestamp(tv);
2748 for (XMLNodeConstIterator child_it = t->children().begin();
2749 child_it != t->children().end();
2752 XMLNode *n = *child_it;
2755 if (n->name() == "MementoCommand" ||
2756 n->name() == "MementoUndoCommand" ||
2757 n->name() == "MementoRedoCommand") {
2759 if ((c = memento_command_factory(n))) {
2763 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2765 if ((c = global_state_command_factory (*n))) {
2766 ut->add_command (c);
2771 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2782 Session::config_changed (const char* parameter_name)
2784 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2786 if (PARAM_IS ("seamless-loop")) {
2788 } else if (PARAM_IS ("rf-speed")) {
2790 } else if (PARAM_IS ("auto-loop")) {
2792 } else if (PARAM_IS ("auto-input")) {
2794 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2795 /* auto-input only makes a difference if we're rolling */
2797 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2799 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2800 if ((*i)->record_enabled ()) {
2801 (*i)->monitor_input (!Config->get_auto_input());
2806 } else if (PARAM_IS ("punch-in")) {
2810 if ((location = _locations.auto_punch_location()) != 0) {
2812 if (Config->get_punch_in ()) {
2813 replace_event (Event::PunchIn, location->start());
2815 remove_event (location->start(), Event::PunchIn);
2819 } else if (PARAM_IS ("punch-out")) {
2823 if ((location = _locations.auto_punch_location()) != 0) {
2825 if (Config->get_punch_out()) {
2826 replace_event (Event::PunchOut, location->end());
2828 clear_events (Event::PunchOut);
2832 } else if (PARAM_IS ("edit-mode")) {
2834 Glib::Mutex::Lock lm (playlist_lock);
2836 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2837 (*i)->set_edit_mode (Config->get_edit_mode ());
2840 } else if (PARAM_IS ("use-video-sync")) {
2842 waiting_for_sync_offset = Config->get_use_video_sync();
2844 } else if (PARAM_IS ("mmc-control")) {
2846 //poke_midi_thread ();
2848 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
2851 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
2854 } else if (PARAM_IS ("mmc-send-id")) {
2857 mmc->set_send_device_id (Config->get_mmc_send_device_id());
2860 } else if (PARAM_IS ("midi-control")) {
2862 //poke_midi_thread ();
2864 } else if (PARAM_IS ("raid-path")) {
2866 setup_raid_path (Config->get_raid_path());
2868 } else if (PARAM_IS ("smpte-format")) {
2872 } else if (PARAM_IS ("video-pullup")) {
2876 } else if (PARAM_IS ("seamless-loop")) {
2878 if (play_loop && transport_rolling()) {
2879 // to reset diskstreams etc
2880 request_play_loop (true);
2883 } else if (PARAM_IS ("rf-speed")) {
2885 cumulative_rf_motion = 0;
2888 } else if (PARAM_IS ("click-sound")) {
2890 setup_click_sounds (1);
2892 } else if (PARAM_IS ("click-emphasis-sound")) {
2894 setup_click_sounds (-1);
2896 } else if (PARAM_IS ("clicking")) {
2898 if (Config->get_clicking()) {
2899 if (_click_io && click_data) { // don't require emphasis data
2906 } else if (PARAM_IS ("send-mtc")) {
2908 /* only set the internal flag if we have
2912 if (_mtc_port != 0) {
2913 session_send_mtc = Config->get_send_mtc();
2914 if (session_send_mtc) {
2915 /* mark us ready to send */
2916 next_quarter_frame_to_send = 0;
2919 session_send_mtc = false;
2922 } else if (PARAM_IS ("send-mmc")) {
2924 /* only set the internal flag if we have
2928 if (_mmc_port != 0) {
2929 session_send_mmc = Config->get_send_mmc();
2932 session_send_mmc = false;
2935 } else if (PARAM_IS ("midi-feedback")) {
2937 /* only set the internal flag if we have
2941 if (_mtc_port != 0) {
2942 session_midi_feedback = Config->get_midi_feedback();
2945 } else if (PARAM_IS ("jack-time-master")) {
2947 engine().reset_timebase ();
2949 } else if (PARAM_IS ("native-file-header-format")) {
2951 if (!first_file_header_format_reset) {
2952 reset_native_file_format ();
2955 first_file_header_format_reset = false;
2957 } else if (PARAM_IS ("native-file-data-format")) {
2959 if (!first_file_data_format_reset) {
2960 reset_native_file_format ();
2963 first_file_data_format_reset = false;
2965 } else if (PARAM_IS ("slave-source")) {
2966 set_slave_source (Config->get_slave_source());
2967 } else if (PARAM_IS ("remote-model")) {
2968 set_remote_control_ids ();
2969 } else if (PARAM_IS ("denormal-model")) {