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/buffer.h>
67 #include <ardour/audio_diskstream.h>
68 #include <ardour/midi_diskstream.h>
69 #include <ardour/utils.h>
70 #include <ardour/audioplaylist.h>
71 #include <ardour/midi_playlist.h>
72 #include <ardour/smf_source.h>
73 #include <ardour/audiofilesource.h>
74 #include <ardour/silentfilesource.h>
75 #include <ardour/sndfilesource.h>
76 #include <ardour/midi_source.h>
77 #include <ardour/sndfile_helpers.h>
78 #include <ardour/auditioner.h>
79 #include <ardour/export.h>
80 #include <ardour/io_processor.h>
81 #include <ardour/send.h>
82 #include <ardour/processor.h>
83 #include <ardour/bundle.h>
84 #include <ardour/slave.h>
85 #include <ardour/tempo.h>
86 #include <ardour/audio_track.h>
87 #include <ardour/midi_track.h>
88 #include <ardour/cycle_timer.h>
89 #include <ardour/utils.h>
90 #include <ardour/named_selection.h>
91 #include <ardour/version.h>
92 #include <ardour/location.h>
93 #include <ardour/audioregion.h>
94 #include <ardour/midi_region.h>
95 #include <ardour/crossfade.h>
96 #include <ardour/control_protocol_manager.h>
97 #include <ardour/region_factory.h>
98 #include <ardour/source_factory.h>
99 #include <ardour/playlist_factory.h>
100 #include <ardour/filename_extensions.h>
101 #include <ardour/directory_names.h>
102 #include <ardour/template_utils.h>
104 #include <control_protocol/control_protocol.h>
110 using namespace ARDOUR;
114 Session::first_stage_init (string fullpath, string snapshot_name)
116 if (fullpath.length() == 0) {
118 throw failed_constructor();
121 char buf[PATH_MAX+1];
122 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
123 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
125 throw failed_constructor();
130 if (_path[_path.length()-1] != '/') {
134 /* these two are just provisional settings. set_state()
135 will likely override them.
138 _name = _current_snapshot_name = snapshot_name;
140 _current_frame_rate = _engine.frame_rate ();
141 _tempo_map = new TempoMap (_current_frame_rate);
142 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
144 g_atomic_int_set (&processing_prohibited, 0);
146 _transport_speed = 0;
147 _last_transport_speed = 0;
148 auto_play_legal = false;
149 transport_sub_state = 0;
150 _transport_frame = 0;
152 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
153 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
154 _end_location_is_free = true;
155 g_atomic_int_set (&_record_status, Disabled);
156 loop_changing = false;
158 _last_roll_location = 0;
159 _last_record_location = 0;
160 pending_locate_frame = 0;
161 pending_locate_roll = false;
162 pending_locate_flush = false;
163 dstream_buffer_size = 0;
165 state_was_pending = false;
167 outbound_mtc_smpte_frame = 0;
168 next_quarter_frame_to_send = -1;
169 current_block_size = 0;
170 solo_update_disabled = false;
171 currently_soloing = false;
172 _have_captured = false;
173 _worst_output_latency = 0;
174 _worst_input_latency = 0;
175 _worst_track_latency = 0;
176 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
178 butler_mixdown_buffer = 0;
179 butler_gain_buffer = 0;
181 session_send_mmc = false;
182 session_send_mtc = false;
183 post_transport_work = PostTransportWork (0);
184 g_atomic_int_set (&butler_should_do_transport_work, 0);
185 g_atomic_int_set (&butler_active, 0);
186 g_atomic_int_set (&_playback_load, 100);
187 g_atomic_int_set (&_capture_load, 100);
188 g_atomic_int_set (&_playback_load_min, 100);
189 g_atomic_int_set (&_capture_load_min, 100);
191 waiting_to_start = false;
193 _gain_automation_buffer = 0;
194 _pan_automation_buffer = 0;
196 pending_abort = false;
197 destructive_index = 0;
199 first_file_data_format_reset = true;
200 first_file_header_format_reset = true;
201 butler_thread = (pthread_t) 0;
202 //midi_thread = (pthread_t) 0;
204 AudioDiskstream::allocate_working_buffers();
206 /* default short fade = 15ms */
208 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
209 SndFileSource::setup_standard_crossfades (frame_rate());
211 last_mmc_step.tv_sec = 0;
212 last_mmc_step.tv_usec = 0;
215 /* click sounds are unset by default, which causes us to internal
216 waveforms for clicks.
220 click_emphasis_data = 0;
222 click_emphasis_length = 0;
225 process_function = &Session::process_with_events;
227 if (Config->get_use_video_sync()) {
228 waiting_for_sync_offset = true;
230 waiting_for_sync_offset = false;
233 _current_frame_rate = 48000;
234 _base_frame_rate = 48000;
238 _smpte_offset_negative = true;
239 last_smpte_valid = false;
243 last_rr_session_dir = session_dirs.begin();
244 refresh_disk_space ();
246 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
250 average_slave_delta = 1800;
251 have_first_delta_accumulator = false;
252 delta_accumulator_cnt = 0;
253 slave_state = Stopped;
255 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
257 /* These are all static "per-class" signals */
259 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
260 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
261 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
262 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
263 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
264 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
266 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
268 IO::MoreChannels.connect (mem_fun (*this, &Session::ensure_buffers));
270 /* stop IO objects from doing stuff until we're ready for them */
272 IO::disable_panners ();
273 IO::disable_ports ();
274 IO::disable_connecting ();
278 Session::second_stage_init (bool new_session)
280 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
283 if (load_state (_current_snapshot_name)) {
286 remove_empty_sounds ();
289 if (start_butler_thread()) {
293 /*if (start_midi_thread ()) {
297 // set_state() will call setup_raid_path(), but if it's a new session we need
298 // to call setup_raid_path() here.
300 if (set_state (*state_tree->root())) {
304 setup_raid_path(_path);
307 /* we can't save till after ::when_engine_running() is called,
308 because otherwise we save state with no connections made.
309 therefore, we reset _state_of_the_state because ::set_state()
310 will have cleared it.
312 we also have to include Loading so that any events that get
313 generated between here and the end of ::when_engine_running()
314 will be processed directly rather than queued.
317 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
319 // set_auto_input (true);
320 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
321 _locations.added.connect (mem_fun (this, &Session::locations_added));
322 setup_click_sounds (0);
323 setup_midi_control ();
325 /* Pay attention ... */
327 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
328 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
331 when_engine_running();
334 /* handle this one in a different way than all others, so that its clear what happened */
336 catch (AudioEngine::PortRegistrationFailure& err) {
337 error << _("Unable to create all required ports")
346 //send_full_time_code ();
347 _engine.transport_locate (0);
348 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
349 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
351 ControlProtocolManager::instance().set_session (*this);
354 _end_location_is_free = true;
356 _end_location_is_free = false;
363 Session::raid_path () const
365 SearchPath raid_search_path;
367 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
368 raid_search_path += sys::path((*i).path);
371 return raid_search_path.to_string ();
375 Session::setup_raid_path (string path)
384 session_dirs.clear ();
386 SearchPath search_path(path);
387 SearchPath sound_search_path;
388 SearchPath midi_search_path;
391 SearchPath::const_iterator i = search_path.begin();
392 i != search_path.end();
396 sp.path = (*i).to_string ();
397 sp.blocks = 0; // not needed
398 session_dirs.push_back (sp);
400 SessionDirectory sdir(sp.path);
402 sound_search_path += sdir.sound_path ();
403 midi_search_path += sdir.midi_path ();
406 // set the AudioFileSource and SMFSource search path
408 AudioFileSource::set_search_path (sound_search_path.to_string ());
409 SMFSource::set_search_path (midi_search_path.to_string ());
411 // reset the round-robin soundfile path thingie
413 last_rr_session_dir = session_dirs.begin();
417 Session::initialize_start_and_end_locations (nframes_t start, nframes_t end)
419 start_location->set_end (start);
420 _locations.add (start_location);
422 end_location->set_end (end);
423 _locations.add (end_location);
427 Session::create_session_file ()
429 _state_of_the_state = Clean;
431 if (save_state (_current_snapshot_name)) {
432 error << "Could not create new session file" << endmsg;
439 Session::create_session_file_from_template (const string& template_path)
441 sys::path session_file_path(_session_dir->root_path());
443 session_file_path /= _name + statefile_suffix;
447 sys::copy_file (template_path, session_file_path);
449 catch(sys::filesystem_error& ex)
451 error << string_compose (_("Could not use session template %1 to create new session (%2)."),
452 template_path, ex.what())
460 Session::load_diskstreams (const XMLNode& node)
463 XMLNodeConstIterator citer;
465 clist = node.children();
467 for (citer = clist.begin(); citer != clist.end(); ++citer) {
470 /* diskstreams added automatically by DiskstreamCreated handler */
471 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
472 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
473 add_diskstream (dstream);
474 } else if ((*citer)->name() == "MidiDiskstream") {
475 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
476 add_diskstream (dstream);
478 error << _("Session: unknown diskstream type in XML") << endmsg;
482 catch (failed_constructor& err) {
483 error << _("Session: could not load diskstream via XML state") << endmsg;
492 Session::maybe_write_autosave()
494 if (dirty() && record_status() != Recording) {
495 save_state("", true);
500 Session::remove_pending_capture_state ()
502 sys::path pending_state_file_path(_session_dir->root_path());
504 pending_state_file_path /= _current_snapshot_name + pending_suffix;
508 sys::remove (pending_state_file_path);
510 catch(sys::filesystem_error& ex)
512 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
513 pending_state_file_path.to_string(), ex.what()) << endmsg;
517 /** Rename a state file.
518 * @param snapshot_name Snapshot name.
521 Session::rename_state (string old_name, string new_name)
523 if (old_name == _current_snapshot_name || old_name == _name) {
524 /* refuse to rename the current snapshot or the "main" one */
528 const string old_xml_path = _path + old_name + statefile_suffix;
529 const string new_xml_path = _path + new_name + statefile_suffix;
531 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
532 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
536 /** Remove a state file.
537 * @param snapshot_name Snapshot name.
540 Session::remove_state (string snapshot_name)
542 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
543 // refuse to remove the current snapshot or the "main" one
547 sys::path xml_path(_session_dir->root_path());
549 xml_path /= snapshot_name + statefile_suffix;
551 sys::path backup_path(xml_path.to_string() + backup_suffix);
553 // make a backup copy of the state file
554 if (sys::exists (xml_path)) {
557 sys::copy_file (xml_path, backup_path);
559 catch(sys::filesystem_error& ex)
561 error << string_compose (_("Not removing state file %1 because a backup could not be made (%2)"),
562 xml_path.to_string(), ex.what())
569 sys::remove (xml_path);
573 Session::save_state (string snapshot_name, bool pending)
576 sys::path xml_path(_session_dir->root_path());
577 sys::path bak_path(xml_path);
579 if (_state_of_the_state & CannotSave) {
583 if (!_engine.connected ()) {
584 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
589 /* tell sources we're saving first, in case they write out to a new file
590 * which should be saved with the state rather than the old one */
591 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
592 i->second->session_saved();
594 tree.set_root (&get_state());
596 if (snapshot_name.empty()) {
597 snapshot_name = _current_snapshot_name;
602 /* proper save: use statefile_suffix (.ardour in English) */
604 xml_path /= snapshot_name + statefile_suffix;
606 /* make a backup copy of the old file */
607 bak_path /= snapshot_name + statefile_suffix + backup_suffix;
609 if (sys::exists (xml_path)) {
612 sys::copy_file (xml_path, bak_path);
614 catch(sys::filesystem_error& ex)
616 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
617 xml_path.to_string(), ex.what())
625 /* pending save: use pending_suffix (.pending in English) */
626 xml_path /= snapshot_name + pending_suffix;
629 sys::path tmp_path(_session_dir->root_path());
631 tmp_path /= snapshot_name + temp_suffix;
633 // cerr << "actually writing state to " << xml_path.to_string() << endl;
635 if (!tree.write (tmp_path.to_string())) {
636 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
637 sys::remove (tmp_path);
642 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
643 error << string_compose (_("could not rename temporary session file %1 to %2"),
644 tmp_path.to_string(), xml_path.to_string()) << endmsg;
645 sys::remove (tmp_path);
652 save_history (snapshot_name);
654 bool was_dirty = dirty();
656 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
659 DirtyChanged (); /* EMIT SIGNAL */
662 StateSaved (snapshot_name); /* EMIT SIGNAL */
669 Session::restore_state (string snapshot_name)
671 if (load_state (snapshot_name) == 0) {
672 set_state (*state_tree->root());
679 Session::load_state (string snapshot_name)
686 state_was_pending = false;
688 /* check for leftover pending state from a crashed capture attempt */
690 sys::path xmlpath(_session_dir->root_path());
691 xmlpath /= snapshot_name + pending_suffix;
693 if (sys::exists (xmlpath)) {
695 /* there is pending state from a crashed capture attempt */
697 if (AskAboutPendingState()) {
698 state_was_pending = true;
702 if (!state_was_pending) {
703 xmlpath = _session_dir->root_path();
704 xmlpath /= snapshot_name + statefile_suffix;
707 if (!sys::exists (xmlpath)) {
708 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
712 state_tree = new XMLTree;
716 if (!state_tree->read (xmlpath.to_string())) {
717 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
723 XMLNode& root (*state_tree->root());
725 if (root.name() != X_("Session")) {
726 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
732 const XMLProperty* prop;
735 if ((prop = root.property ("version")) == 0) {
736 /* no version implies very old version of Ardour */
740 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
741 if (major_version < 2) {
748 sys::path backup_path(_session_dir->root_path());
750 backup_path /= snapshot_name + "-1" + statefile_suffix;
752 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
753 xmlpath.to_string(), backup_path.to_string())
758 sys::copy_file (xmlpath, backup_path);
760 catch(sys::filesystem_error& ex)
762 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
763 xmlpath.to_string(), ex.what())
773 Session::load_options (const XMLNode& node)
777 LocaleGuard lg (X_("POSIX"));
779 Config->set_variables (node, ConfigVariableBase::Session);
781 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
782 if ((prop = child->property ("val")) != 0) {
783 _end_location_is_free = (prop->value() == "yes");
791 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
793 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
794 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
796 return owner & modified_by_session_or_user;
800 Session::get_options () const
803 LocaleGuard lg (X_("POSIX"));
805 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
807 child = option_root.add_child ("end-marker-is-free");
808 child->add_property ("val", _end_location_is_free ? "yes" : "no");
820 Session::get_template()
822 /* if we don't disable rec-enable, diskstreams
823 will believe they need to store their capture
824 sources in their state node.
827 disable_record (false);
833 Session::state(bool full_state)
835 XMLNode* node = new XMLNode("Session");
838 // store libardour version, just in case
840 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
841 libardour_major_version, libardour_minor_version, libardour_micro_version);
842 node->add_property("version", string(buf));
844 /* store configuration settings */
849 node->add_property ("name", _name);
851 if (session_dirs.size() > 1) {
855 vector<space_and_path>::iterator i = session_dirs.begin();
856 vector<space_and_path>::iterator next;
858 ++i; /* skip the first one */
862 while (i != session_dirs.end()) {
866 if (next != session_dirs.end()) {
876 child = node->add_child ("Path");
877 child->add_content (p);
881 /* save the ID counter */
883 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
884 node->add_property ("id-counter", buf);
886 /* various options */
888 node->add_child_nocopy (get_options());
890 child = node->add_child ("Sources");
893 Glib::Mutex::Lock sl (source_lock);
895 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
897 /* Don't save information about AudioFileSources that are empty */
899 boost::shared_ptr<AudioFileSource> fs;
901 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
903 /* Don't save sources that are empty, unless they're destructive (which are OK
904 if they are empty, because we will re-use them every time.)
907 if (!fs->destructive()) {
908 if (fs->length() == 0) {
914 child->add_child_nocopy (siter->second->get_state());
918 child = node->add_child ("Regions");
921 Glib::Mutex::Lock rl (region_lock);
923 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
925 /* only store regions not attached to playlists */
927 if (i->second->playlist() == 0) {
928 child->add_child_nocopy (i->second->state (true));
933 child = node->add_child ("DiskStreams");
936 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
937 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
938 if (!(*i)->hidden()) {
939 child->add_child_nocopy ((*i)->get_state());
945 node->add_child_nocopy (_locations.get_state());
947 // for a template, just create a new Locations, populate it
948 // with the default start and end, and get the state for that.
950 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
951 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
954 end->set_end(compute_initial_length());
956 node->add_child_nocopy (loc.get_state());
959 child = node->add_child ("Connections");
961 Glib::Mutex::Lock lm (bundle_lock);
962 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
963 if (!(*i)->dynamic()) {
964 child->add_child_nocopy ((*i)->get_state());
969 child = node->add_child ("Routes");
971 boost::shared_ptr<RouteList> r = routes.reader ();
973 RoutePublicOrderSorter cmp;
974 RouteList public_order (*r);
975 public_order.sort (cmp);
977 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
978 if (!(*i)->is_hidden()) {
980 child->add_child_nocopy ((*i)->get_state());
982 child->add_child_nocopy ((*i)->get_template());
989 child = node->add_child ("EditGroups");
990 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
991 child->add_child_nocopy ((*i)->get_state());
994 child = node->add_child ("MixGroups");
995 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
996 child->add_child_nocopy ((*i)->get_state());
999 child = node->add_child ("Playlists");
1000 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1001 if (!(*i)->hidden()) {
1002 if (!(*i)->empty()) {
1004 child->add_child_nocopy ((*i)->get_state());
1006 child->add_child_nocopy ((*i)->get_template());
1012 child = node->add_child ("UnusedPlaylists");
1013 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1014 if (!(*i)->hidden()) {
1015 if (!(*i)->empty()) {
1017 child->add_child_nocopy ((*i)->get_state());
1019 child->add_child_nocopy ((*i)->get_template());
1027 child = node->add_child ("Click");
1028 child->add_child_nocopy (_click_io->state (full_state));
1032 child = node->add_child ("NamedSelections");
1033 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1035 child->add_child_nocopy ((*i)->get_state());
1040 node->add_child_nocopy (_tempo_map->get_state());
1042 node->add_child_nocopy (get_control_protocol_state());
1045 node->add_child_copy (*_extra_xml);
1052 Session::get_control_protocol_state ()
1054 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1055 return cpm.get_state();
1059 Session::set_state (const XMLNode& node)
1063 const XMLProperty* prop;
1066 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1068 if (node.name() != X_("Session")){
1069 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1073 if ((prop = node.property ("name")) != 0) {
1074 _name = prop->value ();
1077 setup_raid_path(_path);
1079 if ((prop = node.property (X_("id-counter"))) != 0) {
1081 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1082 ID::init_counter (x);
1084 /* old sessions used a timebased counter, so fake
1085 the startup ID counter based on a standard
1090 ID::init_counter (now);
1094 IO::disable_ports ();
1095 IO::disable_connecting ();
1097 /* Object loading order:
1115 if (use_config_midi_ports ()) {
1118 if ((child = find_named_node (node, "extra")) != 0) {
1119 _extra_xml = new XMLNode (*child);
1122 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1123 load_options (*child);
1124 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1125 load_options (*child);
1127 error << _("Session: XML state has no options section") << endmsg;
1130 if ((child = find_named_node (node, "Locations")) == 0) {
1131 error << _("Session: XML state has no locations section") << endmsg;
1133 } else if (_locations.set_state (*child)) {
1139 if ((location = _locations.auto_loop_location()) != 0) {
1140 set_auto_loop_location (location);
1143 if ((location = _locations.auto_punch_location()) != 0) {
1144 set_auto_punch_location (location);
1147 if ((location = _locations.end_location()) == 0) {
1148 _locations.add (end_location);
1150 delete end_location;
1151 end_location = location;
1154 if ((location = _locations.start_location()) == 0) {
1155 _locations.add (start_location);
1157 delete start_location;
1158 start_location = location;
1161 AudioFileSource::set_header_position_offset (start_location->start());
1163 if ((child = find_named_node (node, "Sources")) == 0) {
1164 error << _("Session: XML state has no sources section") << endmsg;
1166 } else if (load_sources (*child)) {
1170 if ((child = find_named_node (node, "Regions")) == 0) {
1171 error << _("Session: XML state has no Regions section") << endmsg;
1173 } else if (load_regions (*child)) {
1177 if ((child = find_named_node (node, "Playlists")) == 0) {
1178 error << _("Session: XML state has no playlists section") << endmsg;
1180 } else if (load_playlists (*child)) {
1184 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1186 } else if (load_unused_playlists (*child)) {
1190 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1191 if (load_named_selections (*child)) {
1196 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1197 error << _("Session: XML state has no diskstreams section") << endmsg;
1199 } else if (load_diskstreams (*child)) {
1203 if ((child = find_named_node (node, "Connections")) == 0) {
1204 error << _("Session: XML state has no connections section") << endmsg;
1206 } else if (load_bundles (*child)) {
1210 if ((child = find_named_node (node, "EditGroups")) == 0) {
1211 error << _("Session: XML state has no edit groups section") << endmsg;
1213 } else if (load_edit_groups (*child)) {
1217 if ((child = find_named_node (node, "MixGroups")) == 0) {
1218 error << _("Session: XML state has no mix groups section") << endmsg;
1220 } else if (load_mix_groups (*child)) {
1224 if ((child = find_named_node (node, "TempoMap")) == 0) {
1225 error << _("Session: XML state has no Tempo Map section") << endmsg;
1227 } else if (_tempo_map->set_state (*child)) {
1231 if ((child = find_named_node (node, "Routes")) == 0) {
1232 error << _("Session: XML state has no routes section") << endmsg;
1234 } else if (load_routes (*child)) {
1238 if ((child = find_named_node (node, "Click")) == 0) {
1239 warning << _("Session: XML state has no click section") << endmsg;
1240 } else if (_click_io) {
1241 _click_io->set_state (*child);
1244 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1245 ControlProtocolManager::instance().set_protocol_states (*child);
1248 /* here beginneth the second phase ... */
1250 StateReady (); /* EMIT SIGNAL */
1252 _state_of_the_state = Clean;
1254 if (state_was_pending) {
1255 save_state (_current_snapshot_name);
1256 remove_pending_capture_state ();
1257 state_was_pending = false;
1267 Session::load_routes (const XMLNode& node)
1270 XMLNodeConstIterator niter;
1271 RouteList new_routes;
1273 nlist = node.children();
1277 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1279 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1282 error << _("Session: cannot create Route from XML description.") << endmsg;
1286 new_routes.push_back (route);
1289 add_routes (new_routes);
1294 boost::shared_ptr<Route>
1295 Session::XMLRouteFactory (const XMLNode& node)
1297 if (node.name() != "Route") {
1298 return boost::shared_ptr<Route> ((Route*) 0);
1301 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1303 DataType type = DataType::AUDIO;
1304 const XMLProperty* prop = node.property("default-type");
1306 type = DataType(prop->value());
1308 assert(type != DataType::NIL);
1310 if (has_diskstream) {
1311 if (type == DataType::AUDIO) {
1312 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1315 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1319 boost::shared_ptr<Route> ret (new Route (*this, node));
1325 Session::load_regions (const XMLNode& node)
1328 XMLNodeConstIterator niter;
1329 boost::shared_ptr<Region> region;
1331 nlist = node.children();
1335 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1336 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1337 error << _("Session: cannot create Region from XML description.") << endmsg;
1344 boost::shared_ptr<Region>
1345 Session::XMLRegionFactory (const XMLNode& node, bool full)
1347 const XMLProperty* type = node.property("type");
1351 if ( !type || type->value() == "audio" ) {
1353 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1355 } else if (type->value() == "midi") {
1357 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1361 } catch (failed_constructor& err) {
1362 return boost::shared_ptr<Region> ();
1365 return boost::shared_ptr<Region> ();
1368 boost::shared_ptr<AudioRegion>
1369 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1371 const XMLProperty* prop;
1372 boost::shared_ptr<Source> source;
1373 boost::shared_ptr<AudioSource> as;
1375 uint32_t nchans = 1;
1378 if (node.name() != X_("Region")) {
1379 return boost::shared_ptr<AudioRegion>();
1382 if ((prop = node.property (X_("channels"))) != 0) {
1383 nchans = atoi (prop->value().c_str());
1386 if ((prop = node.property ("name")) == 0) {
1387 cerr << "no name for this region\n";
1391 if ((prop = node.property (X_("source-0"))) == 0) {
1392 if ((prop = node.property ("source")) == 0) {
1393 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1394 return boost::shared_ptr<AudioRegion>();
1398 PBD::ID s_id (prop->value());
1400 if ((source = source_by_id (s_id)) == 0) {
1401 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1402 return boost::shared_ptr<AudioRegion>();
1405 as = boost::dynamic_pointer_cast<AudioSource>(source);
1407 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1408 return boost::shared_ptr<AudioRegion>();
1411 sources.push_back (as);
1413 /* pickup other channels */
1415 for (uint32_t n=1; n < nchans; ++n) {
1416 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1417 if ((prop = node.property (buf)) != 0) {
1419 PBD::ID id2 (prop->value());
1421 if ((source = source_by_id (id2)) == 0) {
1422 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1423 return boost::shared_ptr<AudioRegion>();
1426 as = boost::dynamic_pointer_cast<AudioSource>(source);
1428 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1429 return boost::shared_ptr<AudioRegion>();
1431 sources.push_back (as);
1436 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1438 /* a final detail: this is the one and only place that we know how long missing files are */
1440 if (region->whole_file()) {
1441 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1442 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1444 sfp->set_length (region->length());
1453 catch (failed_constructor& err) {
1454 return boost::shared_ptr<AudioRegion>();
1458 boost::shared_ptr<MidiRegion>
1459 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1461 const XMLProperty* prop;
1462 boost::shared_ptr<Source> source;
1463 boost::shared_ptr<MidiSource> ms;
1465 uint32_t nchans = 1;
1467 if (node.name() != X_("Region")) {
1468 return boost::shared_ptr<MidiRegion>();
1471 if ((prop = node.property (X_("channels"))) != 0) {
1472 nchans = atoi (prop->value().c_str());
1475 if ((prop = node.property ("name")) == 0) {
1476 cerr << "no name for this region\n";
1480 // Multiple midi channels? that's just crazy talk
1481 assert(nchans == 1);
1483 if ((prop = node.property (X_("source-0"))) == 0) {
1484 if ((prop = node.property ("source")) == 0) {
1485 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1486 return boost::shared_ptr<MidiRegion>();
1490 PBD::ID s_id (prop->value());
1492 if ((source = source_by_id (s_id)) == 0) {
1493 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1494 return boost::shared_ptr<MidiRegion>();
1497 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1499 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1500 return boost::shared_ptr<MidiRegion>();
1503 sources.push_back (ms);
1506 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1507 /* a final detail: this is the one and only place that we know how long missing files are */
1509 if (region->whole_file()) {
1510 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1511 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1513 sfp->set_length (region->length());
1521 catch (failed_constructor& err) {
1522 return boost::shared_ptr<MidiRegion>();
1527 Session::get_sources_as_xml ()
1530 XMLNode* node = new XMLNode (X_("Sources"));
1531 Glib::Mutex::Lock lm (source_lock);
1533 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1534 node->add_child_nocopy (i->second->get_state());
1541 Session::path_from_region_name (DataType type, string name, string identifier)
1543 char buf[PATH_MAX+1];
1545 SessionDirectory sdir(get_best_session_directory_for_new_source());
1546 string sound_dir = ((type == DataType::AUDIO)
1547 ? sdir.sound_path().to_string()
1548 : sdir.midi_path().to_string());
1550 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1552 for (n = 0; n < 999999; ++n) {
1553 if (identifier.length()) {
1554 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1555 identifier.c_str(), n, ext.c_str());
1557 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1561 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1566 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1575 Session::load_sources (const XMLNode& node)
1578 XMLNodeConstIterator niter;
1579 boost::shared_ptr<Source> source;
1581 nlist = node.children();
1585 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1588 if ((source = XMLSourceFactory (**niter)) == 0) {
1589 error << _("Session: cannot create Source from XML description.") << endmsg;
1593 catch (non_existent_source& err) {
1594 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1595 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1602 boost::shared_ptr<Source>
1603 Session::XMLSourceFactory (const XMLNode& node)
1605 if (node.name() != "Source") {
1606 return boost::shared_ptr<Source>();
1610 return SourceFactory::create (*this, node);
1613 catch (failed_constructor& err) {
1614 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1615 return boost::shared_ptr<Source>();
1620 Session::save_template (string template_name)
1623 string xml_path, bak_path, template_path;
1625 if (_state_of_the_state & CannotSave) {
1629 sys::path user_template_dir(user_template_directory());
1633 sys::create_directories (user_template_dir);
1635 catch(sys::filesystem_error& ex)
1637 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1638 user_template_dir.to_string(), ex.what()) << endmsg;
1642 tree.set_root (&get_template());
1644 sys::path template_file_path(user_template_dir);
1645 template_file_path /= template_name + template_suffix;
1647 if (sys::exists (template_file_path))
1649 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1650 template_file_path.to_string()) << endmsg;
1654 if (!tree.write (template_file_path.to_string())) {
1655 error << _("mix template not saved") << endmsg;
1663 Session::refresh_disk_space ()
1666 struct statfs statfsbuf;
1667 vector<space_and_path>::iterator i;
1668 Glib::Mutex::Lock lm (space_lock);
1671 /* get freespace on every FS that is part of the session path */
1673 _total_free_4k_blocks = 0;
1675 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1676 statfs ((*i).path.c_str(), &statfsbuf);
1678 scale = statfsbuf.f_bsize/4096.0;
1680 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1681 _total_free_4k_blocks += (*i).blocks;
1687 Session::get_best_session_directory_for_new_source ()
1689 vector<space_and_path>::iterator i;
1690 string result = _session_dir->root_path().to_string();
1692 /* handle common case without system calls */
1694 if (session_dirs.size() == 1) {
1698 /* OK, here's the algorithm we're following here:
1700 We want to select which directory to use for
1701 the next file source to be created. Ideally,
1702 we'd like to use a round-robin process so as to
1703 get maximum performance benefits from splitting
1704 the files across multiple disks.
1706 However, in situations without much diskspace, an
1707 RR approach may end up filling up a filesystem
1708 with new files while others still have space.
1709 Its therefore important to pay some attention to
1710 the freespace in the filesystem holding each
1711 directory as well. However, if we did that by
1712 itself, we'd keep creating new files in the file
1713 system with the most space until it was as full
1714 as all others, thus negating any performance
1715 benefits of this RAID-1 like approach.
1717 So, we use a user-configurable space threshold. If
1718 there are at least 2 filesystems with more than this
1719 much space available, we use RR selection between them.
1720 If not, then we pick the filesystem with the most space.
1722 This gets a good balance between the two
1726 refresh_disk_space ();
1728 int free_enough = 0;
1730 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1731 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1736 if (free_enough >= 2) {
1737 /* use RR selection process, ensuring that the one
1741 i = last_rr_session_dir;
1744 if (++i == session_dirs.end()) {
1745 i = session_dirs.begin();
1748 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1749 if (create_session_directory ((*i).path)) {
1751 last_rr_session_dir = i;
1756 } while (i != last_rr_session_dir);
1760 /* pick FS with the most freespace (and that
1761 seems to actually work ...)
1764 vector<space_and_path> sorted;
1765 space_and_path_ascending_cmp cmp;
1767 sorted = session_dirs;
1768 sort (sorted.begin(), sorted.end(), cmp);
1770 for (i = sorted.begin(); i != sorted.end(); ++i) {
1771 if (create_session_directory ((*i).path)) {
1773 last_rr_session_dir = i;
1783 Session::load_playlists (const XMLNode& node)
1786 XMLNodeConstIterator niter;
1787 boost::shared_ptr<Playlist> playlist;
1789 nlist = node.children();
1793 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1795 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1796 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1804 Session::load_unused_playlists (const XMLNode& node)
1807 XMLNodeConstIterator niter;
1808 boost::shared_ptr<Playlist> playlist;
1810 nlist = node.children();
1814 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1816 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1817 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1821 // now manually untrack it
1823 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1829 boost::shared_ptr<Playlist>
1830 Session::XMLPlaylistFactory (const XMLNode& node)
1833 return PlaylistFactory::create (*this, node);
1836 catch (failed_constructor& err) {
1837 return boost::shared_ptr<Playlist>();
1842 Session::load_named_selections (const XMLNode& node)
1845 XMLNodeConstIterator niter;
1848 nlist = node.children();
1852 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1854 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1855 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1863 Session::XMLNamedSelectionFactory (const XMLNode& node)
1866 return new NamedSelection (*this, node);
1869 catch (failed_constructor& err) {
1875 Session::automation_dir () const
1878 res += "automation/";
1883 Session::load_bundles (const XMLNode& node)
1885 XMLNodeList nlist = node.children();
1886 XMLNodeConstIterator niter;
1890 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1891 if ((*niter)->name() == "InputConnection") {
1892 add_bundle (new ARDOUR::InputBundle (**niter));
1893 } else if ((*niter)->name() == "OutputConnection") {
1894 add_bundle (new ARDOUR::OutputBundle (**niter));
1896 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1905 Session::load_edit_groups (const XMLNode& node)
1907 return load_route_groups (node, true);
1911 Session::load_mix_groups (const XMLNode& node)
1913 return load_route_groups (node, false);
1917 Session::load_route_groups (const XMLNode& node, bool edit)
1919 XMLNodeList nlist = node.children();
1920 XMLNodeConstIterator niter;
1925 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1926 if ((*niter)->name() == "RouteGroup") {
1928 rg = add_edit_group ("");
1929 rg->set_state (**niter);
1931 rg = add_mix_group ("");
1932 rg->set_state (**niter);
1941 state_file_filter (const string &str, void *arg)
1943 return (str.length() > strlen(statefile_suffix) &&
1944 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
1948 bool operator()(const string* a, const string* b) {
1954 remove_end(string* state)
1956 string statename(*state);
1958 string::size_type start,end;
1959 if ((start = statename.find_last_of ('/')) != string::npos) {
1960 statename = statename.substr (start+1);
1963 if ((end = statename.rfind(".ardour")) == string::npos) {
1964 end = statename.length();
1967 return new string(statename.substr (0, end));
1971 Session::possible_states (string path)
1973 PathScanner scanner;
1974 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
1976 transform(states->begin(), states->end(), states->begin(), remove_end);
1979 sort (states->begin(), states->end(), cmp);
1985 Session::possible_states () const
1987 return possible_states(_path);
1991 Session::auto_save()
1993 save_state (_current_snapshot_name);
1997 Session::add_edit_group (string name)
1999 RouteGroup* rg = new RouteGroup (*this, name);
2000 edit_groups.push_back (rg);
2001 edit_group_added (rg); /* EMIT SIGNAL */
2007 Session::add_mix_group (string name)
2009 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2010 mix_groups.push_back (rg);
2011 mix_group_added (rg); /* EMIT SIGNAL */
2017 Session::remove_edit_group (RouteGroup& rg)
2019 list<RouteGroup*>::iterator i;
2021 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2022 (*i)->apply (&Route::drop_edit_group, this);
2023 edit_groups.erase (i);
2024 edit_group_removed (); /* EMIT SIGNAL */
2031 Session::remove_mix_group (RouteGroup& rg)
2033 list<RouteGroup*>::iterator i;
2035 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2036 (*i)->apply (&Route::drop_mix_group, this);
2037 mix_groups.erase (i);
2038 mix_group_removed (); /* EMIT SIGNAL */
2045 Session::mix_group_by_name (string name)
2047 list<RouteGroup *>::iterator i;
2049 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2050 if ((*i)->name() == name) {
2058 Session::edit_group_by_name (string name)
2060 list<RouteGroup *>::iterator i;
2062 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2063 if ((*i)->name() == name) {
2071 Session::begin_reversible_command (const string& name)
2073 current_trans = new UndoTransaction;
2074 current_trans->set_name (name);
2078 Session::commit_reversible_command (Command *cmd)
2083 current_trans->add_command (cmd);
2086 gettimeofday (&now, 0);
2087 current_trans->set_timestamp (now);
2089 _history.add (current_trans);
2092 Session::GlobalRouteBooleanState
2093 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2095 GlobalRouteBooleanState s;
2096 boost::shared_ptr<RouteList> r = routes.reader ();
2098 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2099 if (!(*i)->is_hidden()) {
2100 RouteBooleanState v;
2103 Route* r = (*i).get();
2104 v.second = (r->*method)();
2113 Session::GlobalRouteMeterState
2114 Session::get_global_route_metering ()
2116 GlobalRouteMeterState s;
2117 boost::shared_ptr<RouteList> r = routes.reader ();
2119 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2120 if (!(*i)->is_hidden()) {
2124 v.second = (*i)->meter_point();
2134 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2136 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2138 boost::shared_ptr<Route> r = (i->first.lock());
2141 r->set_meter_point (i->second, arg);
2147 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2149 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2151 boost::shared_ptr<Route> r = (i->first.lock());
2154 Route* rp = r.get();
2155 (rp->*method) (i->second, arg);
2161 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2163 set_global_route_boolean (s, &Route::set_mute, src);
2167 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2169 set_global_route_boolean (s, &Route::set_solo, src);
2173 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2175 set_global_route_boolean (s, &Route::set_record_enable, src);
2180 Session::global_mute_memento (void* src)
2182 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2186 Session::global_metering_memento (void* src)
2188 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2192 Session::global_solo_memento (void* src)
2194 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2198 Session::global_record_enable_memento (void* src)
2200 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2205 accept_all_non_peak_files (const string& path, void *arg)
2207 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2211 accept_all_state_files (const string& path, void *arg)
2213 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2217 Session::find_all_sources (string path, set<string>& result)
2222 if (!tree.read (path)) {
2226 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2231 XMLNodeConstIterator niter;
2233 nlist = node->children();
2237 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2241 if ((prop = (*niter)->property (X_("name"))) == 0) {
2245 if (prop->value()[0] == '/') {
2246 /* external file, ignore */
2250 sys::path source_path = _session_dir->sound_path ();
2252 source_path /= prop->value ();
2254 result.insert (source_path.to_string ());
2261 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2263 PathScanner scanner;
2264 vector<string*>* state_files;
2266 string this_snapshot_path;
2272 if (ripped[ripped.length()-1] == '/') {
2273 ripped = ripped.substr (0, ripped.length() - 1);
2276 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2278 if (state_files == 0) {
2283 this_snapshot_path = _path;
2284 this_snapshot_path += _current_snapshot_name;
2285 this_snapshot_path += statefile_suffix;
2287 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2289 if (exclude_this_snapshot && **i == this_snapshot_path) {
2293 if (find_all_sources (**i, result) < 0) {
2301 struct RegionCounter {
2302 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2303 AudioSourceList::iterator iter;
2304 boost::shared_ptr<Region> region;
2307 RegionCounter() : count (0) {}
2311 Session::cleanup_sources (Session::cleanup_report& rep)
2313 // FIXME: needs adaptation to midi
2315 vector<boost::shared_ptr<Source> > dead_sources;
2316 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2317 PathScanner scanner;
2319 vector<space_and_path>::iterator i;
2320 vector<space_and_path>::iterator nexti;
2321 vector<string*>* soundfiles;
2322 vector<string> unused;
2323 set<string> all_sources;
2328 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2330 /* step 1: consider deleting all unused playlists */
2332 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2335 status = AskAboutPlaylistDeletion (*x);
2344 playlists_tbd.push_back (*x);
2348 /* leave it alone */
2353 /* now delete any that were marked for deletion */
2355 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2356 (*x)->drop_references ();
2359 playlists_tbd.clear ();
2361 /* step 2: find all un-used sources */
2366 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2368 SourceMap::iterator tmp;
2373 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2377 if (!i->second->used() && i->second->length() > 0) {
2378 dead_sources.push_back (i->second);
2379 i->second->GoingAway();
2385 /* build a list of all the possible sound directories for the session */
2387 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2392 SessionDirectory sdir ((*i).path);
2393 sound_path += sdir.sound_path().to_string();
2395 if (nexti != session_dirs.end()) {
2402 /* now do the same thing for the files that ended up in the sounds dir(s)
2403 but are not referenced as sources in any snapshot.
2406 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2408 if (soundfiles == 0) {
2412 /* find all sources, but don't use this snapshot because the
2413 state file on disk still references sources we may have already
2417 find_all_sources_across_snapshots (all_sources, true);
2419 /* add our current source list
2422 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2423 boost::shared_ptr<AudioFileSource> fs;
2425 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2426 all_sources.insert (fs->path());
2430 char tmppath1[PATH_MAX+1];
2431 char tmppath2[PATH_MAX+1];
2433 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2438 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2440 realpath(spath.c_str(), tmppath1);
2441 realpath((*i).c_str(), tmppath2);
2443 if (strcmp(tmppath1, tmppath2) == 0) {
2450 unused.push_back (spath);
2454 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2456 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2457 struct stat statbuf;
2459 rep.paths.push_back (*x);
2460 if (stat ((*x).c_str(), &statbuf) == 0) {
2461 rep.space += statbuf.st_size;
2466 /* don't move the file across filesystems, just
2467 stick it in the `dead_sound_dir_name' directory
2468 on whichever filesystem it was already on.
2471 if ((*x).find ("/sounds/") != string::npos) {
2473 /* old school, go up 1 level */
2475 newpath = Glib::path_get_dirname (*x); // "sounds"
2476 newpath = Glib::path_get_dirname (newpath); // "session-name"
2480 /* new school, go up 4 levels */
2482 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2483 newpath = Glib::path_get_dirname (newpath); // "session-name"
2484 newpath = Glib::path_get_dirname (newpath); // "interchange"
2485 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2489 newpath += dead_sound_dir_name;
2491 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2492 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2497 newpath += Glib::path_get_basename ((*x));
2499 if (access (newpath.c_str(), F_OK) == 0) {
2501 /* the new path already exists, try versioning */
2503 char buf[PATH_MAX+1];
2507 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2510 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2511 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2515 if (version == 999) {
2516 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2520 newpath = newpath_v;
2525 /* it doesn't exist, or we can't read it or something */
2529 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2530 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2531 (*x), newpath, strerror (errno))
2536 /* see if there an easy to find peakfile for this file, and remove it.
2539 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2540 peakpath += peakfile_suffix;
2542 if (access (peakpath.c_str(), W_OK) == 0) {
2543 if (::unlink (peakpath.c_str()) != 0) {
2544 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2545 peakpath, _path, strerror (errno))
2547 /* try to back out */
2548 rename (newpath.c_str(), _path.c_str());
2556 /* dump the history list */
2560 /* save state so we don't end up a session file
2561 referring to non-existent sources.
2567 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2572 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2574 // FIXME: needs adaptation for MIDI
2576 vector<space_and_path>::iterator i;
2577 string dead_sound_dir;
2578 struct dirent* dentry;
2579 struct stat statbuf;
2585 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2587 dead_sound_dir = (*i).path;
2588 dead_sound_dir += dead_sound_dir_name;
2590 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2594 while ((dentry = readdir (dead)) != 0) {
2596 /* avoid '.' and '..' */
2598 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2599 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2605 fullpath = dead_sound_dir;
2607 fullpath += dentry->d_name;
2609 if (stat (fullpath.c_str(), &statbuf)) {
2613 if (!S_ISREG (statbuf.st_mode)) {
2617 if (unlink (fullpath.c_str())) {
2618 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2619 fullpath, strerror (errno))
2623 rep.paths.push_back (dentry->d_name);
2624 rep.space += statbuf.st_size;
2635 Session::set_dirty ()
2637 bool was_dirty = dirty();
2639 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2642 DirtyChanged(); /* EMIT SIGNAL */
2648 Session::set_clean ()
2650 bool was_dirty = dirty();
2652 _state_of_the_state = Clean;
2655 DirtyChanged(); /* EMIT SIGNAL */
2660 Session::set_deletion_in_progress ()
2662 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2666 Session::add_controllable (boost::shared_ptr<Controllable> c)
2668 /* this adds a controllable to the list managed by the Session.
2669 this is a subset of those managed by the Controllable class
2670 itself, and represents the only ones whose state will be saved
2671 as part of the session.
2674 Glib::Mutex::Lock lm (controllables_lock);
2675 controllables.insert (c);
2678 struct null_deleter { void operator()(void const *) const {} };
2681 Session::remove_controllable (Controllable* c)
2683 if (_state_of_the_state | Deletion) {
2687 Glib::Mutex::Lock lm (controllables_lock);
2689 Controllables::iterator x = controllables.find(
2690 boost::shared_ptr<Controllable>(c, null_deleter()));
2692 if (x != controllables.end()) {
2693 controllables.erase (x);
2697 boost::shared_ptr<Controllable>
2698 Session::controllable_by_id (const PBD::ID& id)
2700 Glib::Mutex::Lock lm (controllables_lock);
2702 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2703 if ((*i)->id() == id) {
2708 return boost::shared_ptr<Controllable>();
2712 Session::add_instant_xml (XMLNode& node)
2714 Stateful::add_instant_xml (node, _path);
2715 Config->add_instant_xml (node);
2719 Session::instant_xml (const string& node_name)
2721 return Stateful::instant_xml (node_name, _path);
2725 Session::save_history (string snapshot_name)
2731 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2733 if (snapshot_name.empty()) {
2734 snapshot_name = _current_snapshot_name;
2737 xml_path = _path + snapshot_name + ".history";
2739 bak_path = xml_path + ".bak";
2741 if ((access (xml_path.c_str(), F_OK) == 0) &&
2742 (rename (xml_path.c_str(), bak_path.c_str())))
2744 error << _("could not backup old history file, current history not saved.") << endmsg;
2748 if (!tree.write (xml_path))
2750 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2752 /* don't leave a corrupt file lying around if it is
2756 if (unlink (xml_path.c_str())) {
2757 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2759 if (rename (bak_path.c_str(), xml_path.c_str()))
2761 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2772 Session::restore_history (string snapshot_name)
2777 if (snapshot_name.empty()) {
2778 snapshot_name = _current_snapshot_name;
2782 xmlpath = _path + snapshot_name + ".history";
2783 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2785 if (access (xmlpath.c_str(), F_OK)) {
2786 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2790 if (!tree.read (xmlpath)) {
2791 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2795 /* replace history */
2798 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2801 UndoTransaction* ut = new UndoTransaction ();
2804 ut->set_name(t->property("name")->value());
2805 stringstream ss(t->property("tv_sec")->value());
2807 ss.str(t->property("tv_usec")->value());
2809 ut->set_timestamp(tv);
2811 for (XMLNodeConstIterator child_it = t->children().begin();
2812 child_it != t->children().end();
2815 XMLNode *n = *child_it;
2818 if (n->name() == "MementoCommand" ||
2819 n->name() == "MementoUndoCommand" ||
2820 n->name() == "MementoRedoCommand") {
2822 if ((c = memento_command_factory(n))) {
2826 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2828 if ((c = global_state_command_factory (*n))) {
2829 ut->add_command (c);
2834 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2845 Session::config_changed (const char* parameter_name)
2847 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2849 if (PARAM_IS ("seamless-loop")) {
2851 } else if (PARAM_IS ("rf-speed")) {
2853 } else if (PARAM_IS ("auto-loop")) {
2855 } else if (PARAM_IS ("auto-input")) {
2857 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2858 /* auto-input only makes a difference if we're rolling */
2860 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2862 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2863 if ((*i)->record_enabled ()) {
2864 (*i)->monitor_input (!Config->get_auto_input());
2869 } else if (PARAM_IS ("punch-in")) {
2873 if ((location = _locations.auto_punch_location()) != 0) {
2875 if (Config->get_punch_in ()) {
2876 replace_event (Event::PunchIn, location->start());
2878 remove_event (location->start(), Event::PunchIn);
2882 } else if (PARAM_IS ("punch-out")) {
2886 if ((location = _locations.auto_punch_location()) != 0) {
2888 if (Config->get_punch_out()) {
2889 replace_event (Event::PunchOut, location->end());
2891 clear_events (Event::PunchOut);
2895 } else if (PARAM_IS ("edit-mode")) {
2897 Glib::Mutex::Lock lm (playlist_lock);
2899 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2900 (*i)->set_edit_mode (Config->get_edit_mode ());
2903 } else if (PARAM_IS ("use-video-sync")) {
2905 waiting_for_sync_offset = Config->get_use_video_sync();
2907 } else if (PARAM_IS ("mmc-control")) {
2909 //poke_midi_thread ();
2911 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
2914 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
2917 } else if (PARAM_IS ("mmc-send-id")) {
2920 mmc->set_send_device_id (Config->get_mmc_send_device_id());
2923 } else if (PARAM_IS ("midi-control")) {
2925 //poke_midi_thread ();
2927 } else if (PARAM_IS ("raid-path")) {
2929 setup_raid_path (Config->get_raid_path());
2931 } else if (PARAM_IS ("smpte-format")) {
2935 } else if (PARAM_IS ("video-pullup")) {
2939 } else if (PARAM_IS ("seamless-loop")) {
2941 if (play_loop && transport_rolling()) {
2942 // to reset diskstreams etc
2943 request_play_loop (true);
2946 } else if (PARAM_IS ("rf-speed")) {
2948 cumulative_rf_motion = 0;
2951 } else if (PARAM_IS ("click-sound")) {
2953 setup_click_sounds (1);
2955 } else if (PARAM_IS ("click-emphasis-sound")) {
2957 setup_click_sounds (-1);
2959 } else if (PARAM_IS ("clicking")) {
2961 if (Config->get_clicking()) {
2962 if (_click_io && click_data) { // don't require emphasis data
2969 } else if (PARAM_IS ("send-mtc")) {
2971 /* only set the internal flag if we have
2975 if (_mtc_port != 0) {
2976 session_send_mtc = Config->get_send_mtc();
2977 if (session_send_mtc) {
2978 /* mark us ready to send */
2979 next_quarter_frame_to_send = 0;
2982 session_send_mtc = false;
2985 } else if (PARAM_IS ("send-mmc")) {
2987 /* only set the internal flag if we have
2991 if (_mmc_port != 0) {
2992 session_send_mmc = Config->get_send_mmc();
2995 session_send_mmc = false;
2998 } else if (PARAM_IS ("midi-feedback")) {
3000 /* only set the internal flag if we have
3004 if (_mtc_port != 0) {
3005 session_midi_feedback = Config->get_midi_feedback();
3008 } else if (PARAM_IS ("jack-time-master")) {
3010 engine().reset_timebase ();
3012 } else if (PARAM_IS ("native-file-header-format")) {
3014 if (!first_file_header_format_reset) {
3015 reset_native_file_format ();
3018 first_file_header_format_reset = false;
3020 } else if (PARAM_IS ("native-file-data-format")) {
3022 if (!first_file_data_format_reset) {
3023 reset_native_file_format ();
3026 first_file_data_format_reset = false;
3028 } else if (PARAM_IS ("slave-source")) {
3029 set_slave_source (Config->get_slave_source());
3030 } else if (PARAM_IS ("remote-model")) {
3031 set_remote_control_ids ();
3032 } else if (PARAM_IS ("denormal-model")) {