2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #define __STDC_FORMAT_MACROS 1
28 #include <sigc++/bind.h>
30 #include <cstdio> /* snprintf(3) ... grrr */
45 #include <sys/param.h>
46 #include <sys/mount.h>
51 #include <midi++/mmc.h>
52 #include <midi++/port.h>
53 #include <pbd/error.h>
55 #include <glibmm/thread.h>
56 #include <pbd/pathscanner.h>
57 #include <pbd/pthread_utils.h>
58 #include <pbd/search_path.h>
59 #include <pbd/stacktrace.h>
60 #include <pbd/copyfile.h>
62 #include <ardour/audioengine.h>
63 #include <ardour/configuration.h>
64 #include <ardour/session.h>
65 #include <ardour/session_directory.h>
66 #include <ardour/session_utils.h>
67 #include <ardour/buffer.h>
68 #include <ardour/audio_diskstream.h>
69 #include <ardour/midi_diskstream.h>
70 #include <ardour/utils.h>
71 #include <ardour/audioplaylist.h>
72 #include <ardour/midi_playlist.h>
73 #include <ardour/smf_source.h>
74 #include <ardour/audiofilesource.h>
75 #include <ardour/silentfilesource.h>
76 #include <ardour/sndfilesource.h>
77 #include <ardour/midi_source.h>
78 #include <ardour/sndfile_helpers.h>
79 #include <ardour/auditioner.h>
80 #include <ardour/export.h>
81 #include <ardour/io_processor.h>
82 #include <ardour/send.h>
83 #include <ardour/processor.h>
84 #include <ardour/bundle.h>
85 #include <ardour/slave.h>
86 #include <ardour/tempo.h>
87 #include <ardour/audio_track.h>
88 #include <ardour/midi_track.h>
89 #include <ardour/cycle_timer.h>
90 #include <ardour/utils.h>
91 #include <ardour/named_selection.h>
92 #include <ardour/version.h>
93 #include <ardour/location.h>
94 #include <ardour/audioregion.h>
95 #include <ardour/midi_region.h>
96 #include <ardour/crossfade.h>
97 #include <ardour/control_protocol_manager.h>
98 #include <ardour/region_factory.h>
99 #include <ardour/source_factory.h>
100 #include <ardour/playlist_factory.h>
101 #include <ardour/filename_extensions.h>
102 #include <ardour/directory_names.h>
103 #include <ardour/template_utils.h>
105 #include <control_protocol/control_protocol.h>
111 using namespace ARDOUR;
115 Session::first_stage_init (string fullpath, string snapshot_name)
117 if (fullpath.length() == 0) {
119 throw failed_constructor();
122 char buf[PATH_MAX+1];
123 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
124 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
126 throw failed_constructor();
131 if (_path[_path.length()-1] != '/') {
135 /* these two are just provisional settings. set_state()
136 will likely override them.
139 _name = _current_snapshot_name = snapshot_name;
141 _current_frame_rate = _engine.frame_rate ();
142 _tempo_map = new TempoMap (_current_frame_rate);
143 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
145 g_atomic_int_set (&processing_prohibited, 0);
147 _transport_speed = 0;
148 _last_transport_speed = 0;
149 auto_play_legal = false;
150 transport_sub_state = 0;
151 _transport_frame = 0;
153 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
154 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
155 _end_location_is_free = true;
156 g_atomic_int_set (&_record_status, Disabled);
157 loop_changing = false;
159 _last_roll_location = 0;
160 _last_record_location = 0;
161 pending_locate_frame = 0;
162 pending_locate_roll = false;
163 pending_locate_flush = false;
164 dstream_buffer_size = 0;
166 state_was_pending = false;
168 outbound_mtc_smpte_frame = 0;
169 next_quarter_frame_to_send = -1;
170 current_block_size = 0;
171 solo_update_disabled = false;
172 currently_soloing = false;
173 _have_captured = false;
174 _worst_output_latency = 0;
175 _worst_input_latency = 0;
176 _worst_track_latency = 0;
177 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
179 butler_mixdown_buffer = 0;
180 butler_gain_buffer = 0;
182 session_send_mmc = false;
183 session_send_mtc = false;
184 post_transport_work = PostTransportWork (0);
185 g_atomic_int_set (&butler_should_do_transport_work, 0);
186 g_atomic_int_set (&butler_active, 0);
187 g_atomic_int_set (&_playback_load, 100);
188 g_atomic_int_set (&_capture_load, 100);
189 g_atomic_int_set (&_playback_load_min, 100);
190 g_atomic_int_set (&_capture_load_min, 100);
192 waiting_to_start = false;
194 _gain_automation_buffer = 0;
195 _pan_automation_buffer = 0;
197 pending_abort = false;
198 destructive_index = 0;
200 first_file_data_format_reset = true;
201 first_file_header_format_reset = true;
202 butler_thread = (pthread_t) 0;
203 //midi_thread = (pthread_t) 0;
205 AudioDiskstream::allocate_working_buffers();
207 /* default short fade = 15ms */
209 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
210 SndFileSource::setup_standard_crossfades (frame_rate());
212 last_mmc_step.tv_sec = 0;
213 last_mmc_step.tv_usec = 0;
216 /* click sounds are unset by default, which causes us to internal
217 waveforms for clicks.
221 click_emphasis_data = 0;
223 click_emphasis_length = 0;
226 process_function = &Session::process_with_events;
228 if (Config->get_use_video_sync()) {
229 waiting_for_sync_offset = true;
231 waiting_for_sync_offset = false;
234 _current_frame_rate = 48000;
235 _base_frame_rate = 48000;
239 _smpte_offset_negative = true;
240 last_smpte_valid = false;
244 last_rr_session_dir = session_dirs.begin();
245 refresh_disk_space ();
247 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
251 average_slave_delta = 1800;
252 have_first_delta_accumulator = false;
253 delta_accumulator_cnt = 0;
254 slave_state = Stopped;
256 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
258 /* These are all static "per-class" signals */
260 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
261 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
262 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
263 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
264 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
265 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
267 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
269 IO::MoreChannels.connect (mem_fun (*this, &Session::ensure_buffers));
271 /* stop IO objects from doing stuff until we're ready for them */
273 IO::disable_panners ();
274 IO::disable_ports ();
275 IO::disable_connecting ();
279 Session::second_stage_init (bool new_session)
281 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
284 if (load_state (_current_snapshot_name)) {
287 remove_empty_sounds ();
290 if (start_butler_thread()) {
294 /*if (start_midi_thread ()) {
298 // set_state() will call setup_raid_path(), but if it's a new session we need
299 // to call setup_raid_path() here.
301 if (set_state (*state_tree->root())) {
305 setup_raid_path(_path);
308 /* we can't save till after ::when_engine_running() is called,
309 because otherwise we save state with no connections made.
310 therefore, we reset _state_of_the_state because ::set_state()
311 will have cleared it.
313 we also have to include Loading so that any events that get
314 generated between here and the end of ::when_engine_running()
315 will be processed directly rather than queued.
318 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
320 // set_auto_input (true);
321 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
322 _locations.added.connect (mem_fun (this, &Session::locations_added));
323 setup_click_sounds (0);
324 setup_midi_control ();
326 /* Pay attention ... */
328 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
329 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
332 when_engine_running();
335 /* handle this one in a different way than all others, so that its clear what happened */
337 catch (AudioEngine::PortRegistrationFailure& err) {
338 error << _("Unable to create all required ports")
347 //send_full_time_code ();
348 _engine.transport_locate (0);
349 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
350 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
352 ControlProtocolManager::instance().set_session (*this);
355 _end_location_is_free = true;
357 _end_location_is_free = false;
364 Session::raid_path () const
366 SearchPath raid_search_path;
368 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
369 raid_search_path += sys::path((*i).path);
372 return raid_search_path.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 sys::path backup_path(xml_path.to_string() + backup_suffix);
554 // make a backup copy of the state file
555 if (sys::exists (xml_path)) {
558 sys::copy_file (xml_path, backup_path);
560 catch(sys::filesystem_error& ex)
562 error << string_compose (_("Not removing state file %1 because a backup could not be made (%2)"),
563 xml_path.to_string(), ex.what())
570 sys::remove (xml_path);
574 Session::save_state (string snapshot_name, bool pending)
577 sys::path xml_path(_session_dir->root_path());
578 sys::path bak_path(xml_path);
580 if (_state_of_the_state & CannotSave) {
584 if (!_engine.connected ()) {
585 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
590 /* tell sources we're saving first, in case they write out to a new file
591 * which should be saved with the state rather than the old one */
592 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
593 i->second->session_saved();
595 tree.set_root (&get_state());
597 if (snapshot_name.empty()) {
598 snapshot_name = _current_snapshot_name;
603 /* proper save: use statefile_suffix (.ardour in English) */
605 xml_path /= snapshot_name + statefile_suffix;
607 /* make a backup copy of the old file */
608 bak_path /= snapshot_name + statefile_suffix + backup_suffix;
610 if (sys::exists (xml_path)) {
613 sys::copy_file (xml_path, bak_path);
615 catch(sys::filesystem_error& ex)
617 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
618 xml_path.to_string(), ex.what())
626 /* pending save: use pending_suffix (.pending in English) */
627 xml_path /= snapshot_name + pending_suffix;
630 sys::path tmp_path(_session_dir->root_path());
632 tmp_path /= snapshot_name + temp_suffix;
634 // cerr << "actually writing state to " << xml_path.to_string() << endl;
636 if (!tree.write (tmp_path.to_string())) {
637 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
638 sys::remove (tmp_path);
643 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
644 error << string_compose (_("could not rename temporary session file %1 to %2"),
645 tmp_path.to_string(), xml_path.to_string()) << endmsg;
646 sys::remove (tmp_path);
653 save_history (snapshot_name);
655 bool was_dirty = dirty();
657 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
660 DirtyChanged (); /* EMIT SIGNAL */
663 StateSaved (snapshot_name); /* EMIT SIGNAL */
670 Session::restore_state (string snapshot_name)
672 if (load_state (snapshot_name) == 0) {
673 set_state (*state_tree->root());
680 Session::load_state (string snapshot_name)
687 state_was_pending = false;
689 /* check for leftover pending state from a crashed capture attempt */
691 sys::path xmlpath(_session_dir->root_path());
692 xmlpath /= snapshot_name + pending_suffix;
694 if (sys::exists (xmlpath)) {
696 /* there is pending state from a crashed capture attempt */
698 if (AskAboutPendingState()) {
699 state_was_pending = true;
703 if (!state_was_pending) {
704 xmlpath = _session_dir->root_path();
705 xmlpath /= snapshot_name + statefile_suffix;
708 if (!sys::exists (xmlpath)) {
709 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
713 state_tree = new XMLTree;
717 if (!state_tree->read (xmlpath.to_string())) {
718 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
724 XMLNode& root (*state_tree->root());
726 if (root.name() != X_("Session")) {
727 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
733 const XMLProperty* prop;
736 if ((prop = root.property ("version")) == 0) {
737 /* no version implies very old version of Ardour */
741 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
742 if (major_version < 2) {
749 sys::path backup_path(_session_dir->root_path());
751 backup_path /= snapshot_name + "-1" + statefile_suffix;
753 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
754 xmlpath.to_string(), backup_path.to_string())
759 sys::copy_file (xmlpath, backup_path);
761 catch(sys::filesystem_error& ex)
763 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
764 xmlpath.to_string(), ex.what())
774 Session::load_options (const XMLNode& node)
778 LocaleGuard lg (X_("POSIX"));
780 Config->set_variables (node, ConfigVariableBase::Session);
782 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
783 if ((prop = child->property ("val")) != 0) {
784 _end_location_is_free = (prop->value() == "yes");
792 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
794 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
795 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
797 return owner & modified_by_session_or_user;
801 Session::get_options () const
804 LocaleGuard lg (X_("POSIX"));
806 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
808 child = option_root.add_child ("end-marker-is-free");
809 child->add_property ("val", _end_location_is_free ? "yes" : "no");
821 Session::get_template()
823 /* if we don't disable rec-enable, diskstreams
824 will believe they need to store their capture
825 sources in their state node.
828 disable_record (false);
834 Session::state(bool full_state)
836 XMLNode* node = new XMLNode("Session");
839 // store libardour version, just in case
841 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
842 libardour_major_version, libardour_minor_version, libardour_micro_version);
843 node->add_property("version", string(buf));
845 /* store configuration settings */
850 node->add_property ("name", _name);
852 if (session_dirs.size() > 1) {
856 vector<space_and_path>::iterator i = session_dirs.begin();
857 vector<space_and_path>::iterator next;
859 ++i; /* skip the first one */
863 while (i != session_dirs.end()) {
867 if (next != session_dirs.end()) {
877 child = node->add_child ("Path");
878 child->add_content (p);
882 /* save the ID counter */
884 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
885 node->add_property ("id-counter", buf);
887 /* various options */
889 node->add_child_nocopy (get_options());
891 child = node->add_child ("Sources");
894 Glib::Mutex::Lock sl (source_lock);
896 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
898 /* Don't save information about AudioFileSources that are empty */
900 boost::shared_ptr<AudioFileSource> fs;
902 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
904 /* Don't save sources that are empty, unless they're destructive (which are OK
905 if they are empty, because we will re-use them every time.)
908 if (!fs->destructive()) {
909 if (fs->length() == 0) {
915 child->add_child_nocopy (siter->second->get_state());
919 child = node->add_child ("Regions");
922 Glib::Mutex::Lock rl (region_lock);
924 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
926 /* only store regions not attached to playlists */
928 if (i->second->playlist() == 0) {
929 child->add_child_nocopy (i->second->state (true));
934 child = node->add_child ("DiskStreams");
937 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
938 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
939 if (!(*i)->hidden()) {
940 child->add_child_nocopy ((*i)->get_state());
946 node->add_child_nocopy (_locations.get_state());
948 // for a template, just create a new Locations, populate it
949 // with the default start and end, and get the state for that.
951 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
952 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
955 end->set_end(compute_initial_length());
957 node->add_child_nocopy (loc.get_state());
960 child = node->add_child ("Connections");
962 Glib::Mutex::Lock lm (bundle_lock);
963 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
964 if (!(*i)->dynamic()) {
965 child->add_child_nocopy ((*i)->get_state());
970 child = node->add_child ("Routes");
972 boost::shared_ptr<RouteList> r = routes.reader ();
974 RoutePublicOrderSorter cmp;
975 RouteList public_order (*r);
976 public_order.sort (cmp);
978 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
979 if (!(*i)->is_hidden()) {
981 child->add_child_nocopy ((*i)->get_state());
983 child->add_child_nocopy ((*i)->get_template());
990 child = node->add_child ("EditGroups");
991 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
992 child->add_child_nocopy ((*i)->get_state());
995 child = node->add_child ("MixGroups");
996 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
997 child->add_child_nocopy ((*i)->get_state());
1000 child = node->add_child ("Playlists");
1001 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1002 if (!(*i)->hidden()) {
1003 if (!(*i)->empty()) {
1005 child->add_child_nocopy ((*i)->get_state());
1007 child->add_child_nocopy ((*i)->get_template());
1013 child = node->add_child ("UnusedPlaylists");
1014 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1015 if (!(*i)->hidden()) {
1016 if (!(*i)->empty()) {
1018 child->add_child_nocopy ((*i)->get_state());
1020 child->add_child_nocopy ((*i)->get_template());
1028 child = node->add_child ("Click");
1029 child->add_child_nocopy (_click_io->state (full_state));
1033 child = node->add_child ("NamedSelections");
1034 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1036 child->add_child_nocopy ((*i)->get_state());
1041 node->add_child_nocopy (_tempo_map->get_state());
1043 node->add_child_nocopy (get_control_protocol_state());
1046 node->add_child_copy (*_extra_xml);
1053 Session::get_control_protocol_state ()
1055 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1056 return cpm.get_state();
1060 Session::set_state (const XMLNode& node)
1064 const XMLProperty* prop;
1067 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1069 if (node.name() != X_("Session")){
1070 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1074 if ((prop = node.property ("name")) != 0) {
1075 _name = prop->value ();
1078 setup_raid_path(_path);
1080 if ((prop = node.property (X_("id-counter"))) != 0) {
1082 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1083 ID::init_counter (x);
1085 /* old sessions used a timebased counter, so fake
1086 the startup ID counter based on a standard
1091 ID::init_counter (now);
1095 IO::disable_ports ();
1096 IO::disable_connecting ();
1098 /* Object loading order:
1116 if (use_config_midi_ports ()) {
1119 if ((child = find_named_node (node, "extra")) != 0) {
1120 _extra_xml = new XMLNode (*child);
1123 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1124 load_options (*child);
1125 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1126 load_options (*child);
1128 error << _("Session: XML state has no options section") << endmsg;
1131 if ((child = find_named_node (node, "Locations")) == 0) {
1132 error << _("Session: XML state has no locations section") << endmsg;
1134 } else if (_locations.set_state (*child)) {
1140 if ((location = _locations.auto_loop_location()) != 0) {
1141 set_auto_loop_location (location);
1144 if ((location = _locations.auto_punch_location()) != 0) {
1145 set_auto_punch_location (location);
1148 if ((location = _locations.end_location()) == 0) {
1149 _locations.add (end_location);
1151 delete end_location;
1152 end_location = location;
1155 if ((location = _locations.start_location()) == 0) {
1156 _locations.add (start_location);
1158 delete start_location;
1159 start_location = location;
1162 AudioFileSource::set_header_position_offset (start_location->start());
1164 if ((child = find_named_node (node, "Sources")) == 0) {
1165 error << _("Session: XML state has no sources section") << endmsg;
1167 } else if (load_sources (*child)) {
1171 if ((child = find_named_node (node, "Regions")) == 0) {
1172 error << _("Session: XML state has no Regions section") << endmsg;
1174 } else if (load_regions (*child)) {
1178 if ((child = find_named_node (node, "Playlists")) == 0) {
1179 error << _("Session: XML state has no playlists section") << endmsg;
1181 } else if (load_playlists (*child)) {
1185 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1187 } else if (load_unused_playlists (*child)) {
1191 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1192 if (load_named_selections (*child)) {
1197 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1198 error << _("Session: XML state has no diskstreams section") << endmsg;
1200 } else if (load_diskstreams (*child)) {
1204 if ((child = find_named_node (node, "Connections")) == 0) {
1205 error << _("Session: XML state has no connections section") << endmsg;
1207 } else if (load_bundles (*child)) {
1211 if ((child = find_named_node (node, "EditGroups")) == 0) {
1212 error << _("Session: XML state has no edit groups section") << endmsg;
1214 } else if (load_edit_groups (*child)) {
1218 if ((child = find_named_node (node, "MixGroups")) == 0) {
1219 error << _("Session: XML state has no mix groups section") << endmsg;
1221 } else if (load_mix_groups (*child)) {
1225 if ((child = find_named_node (node, "TempoMap")) == 0) {
1226 error << _("Session: XML state has no Tempo Map section") << endmsg;
1228 } else if (_tempo_map->set_state (*child)) {
1232 if ((child = find_named_node (node, "Routes")) == 0) {
1233 error << _("Session: XML state has no routes section") << endmsg;
1235 } else if (load_routes (*child)) {
1239 if ((child = find_named_node (node, "Click")) == 0) {
1240 warning << _("Session: XML state has no click section") << endmsg;
1241 } else if (_click_io) {
1242 _click_io->set_state (*child);
1245 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1246 ControlProtocolManager::instance().set_protocol_states (*child);
1249 /* here beginneth the second phase ... */
1251 StateReady (); /* EMIT SIGNAL */
1253 _state_of_the_state = Clean;
1255 if (state_was_pending) {
1256 save_state (_current_snapshot_name);
1257 remove_pending_capture_state ();
1258 state_was_pending = false;
1268 Session::load_routes (const XMLNode& node)
1271 XMLNodeConstIterator niter;
1272 RouteList new_routes;
1274 nlist = node.children();
1278 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1280 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1283 error << _("Session: cannot create Route from XML description.") << endmsg;
1287 new_routes.push_back (route);
1290 add_routes (new_routes);
1295 boost::shared_ptr<Route>
1296 Session::XMLRouteFactory (const XMLNode& node)
1298 if (node.name() != "Route") {
1299 return boost::shared_ptr<Route> ((Route*) 0);
1302 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1304 DataType type = DataType::AUDIO;
1305 const XMLProperty* prop = node.property("default-type");
1307 type = DataType(prop->value());
1309 assert(type != DataType::NIL);
1311 if (has_diskstream) {
1312 if (type == DataType::AUDIO) {
1313 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1316 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1320 boost::shared_ptr<Route> ret (new Route (*this, node));
1326 Session::load_regions (const XMLNode& node)
1329 XMLNodeConstIterator niter;
1330 boost::shared_ptr<Region> region;
1332 nlist = node.children();
1336 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1337 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1338 error << _("Session: cannot create Region from XML description.") << endmsg;
1345 boost::shared_ptr<Region>
1346 Session::XMLRegionFactory (const XMLNode& node, bool full)
1348 const XMLProperty* type = node.property("type");
1352 if ( !type || type->value() == "audio" ) {
1354 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1356 } else if (type->value() == "midi") {
1358 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1362 } catch (failed_constructor& err) {
1363 return boost::shared_ptr<Region> ();
1366 return boost::shared_ptr<Region> ();
1369 boost::shared_ptr<AudioRegion>
1370 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1372 const XMLProperty* prop;
1373 boost::shared_ptr<Source> source;
1374 boost::shared_ptr<AudioSource> as;
1376 uint32_t nchans = 1;
1379 if (node.name() != X_("Region")) {
1380 return boost::shared_ptr<AudioRegion>();
1383 if ((prop = node.property (X_("channels"))) != 0) {
1384 nchans = atoi (prop->value().c_str());
1387 if ((prop = node.property ("name")) == 0) {
1388 cerr << "no name for this region\n";
1392 if ((prop = node.property (X_("source-0"))) == 0) {
1393 if ((prop = node.property ("source")) == 0) {
1394 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1395 return boost::shared_ptr<AudioRegion>();
1399 PBD::ID s_id (prop->value());
1401 if ((source = source_by_id (s_id)) == 0) {
1402 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1403 return boost::shared_ptr<AudioRegion>();
1406 as = boost::dynamic_pointer_cast<AudioSource>(source);
1408 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1409 return boost::shared_ptr<AudioRegion>();
1412 sources.push_back (as);
1414 /* pickup other channels */
1416 for (uint32_t n=1; n < nchans; ++n) {
1417 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1418 if ((prop = node.property (buf)) != 0) {
1420 PBD::ID id2 (prop->value());
1422 if ((source = source_by_id (id2)) == 0) {
1423 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1424 return boost::shared_ptr<AudioRegion>();
1427 as = boost::dynamic_pointer_cast<AudioSource>(source);
1429 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1430 return boost::shared_ptr<AudioRegion>();
1432 sources.push_back (as);
1437 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1439 /* a final detail: this is the one and only place that we know how long missing files are */
1441 if (region->whole_file()) {
1442 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1443 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1445 sfp->set_length (region->length());
1454 catch (failed_constructor& err) {
1455 return boost::shared_ptr<AudioRegion>();
1459 boost::shared_ptr<MidiRegion>
1460 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1462 const XMLProperty* prop;
1463 boost::shared_ptr<Source> source;
1464 boost::shared_ptr<MidiSource> ms;
1466 uint32_t nchans = 1;
1468 if (node.name() != X_("Region")) {
1469 return boost::shared_ptr<MidiRegion>();
1472 if ((prop = node.property (X_("channels"))) != 0) {
1473 nchans = atoi (prop->value().c_str());
1476 if ((prop = node.property ("name")) == 0) {
1477 cerr << "no name for this region\n";
1481 // Multiple midi channels? that's just crazy talk
1482 assert(nchans == 1);
1484 if ((prop = node.property (X_("source-0"))) == 0) {
1485 if ((prop = node.property ("source")) == 0) {
1486 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1487 return boost::shared_ptr<MidiRegion>();
1491 PBD::ID s_id (prop->value());
1493 if ((source = source_by_id (s_id)) == 0) {
1494 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1495 return boost::shared_ptr<MidiRegion>();
1498 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1500 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1501 return boost::shared_ptr<MidiRegion>();
1504 sources.push_back (ms);
1507 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1508 /* a final detail: this is the one and only place that we know how long missing files are */
1510 if (region->whole_file()) {
1511 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1512 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1514 sfp->set_length (region->length());
1522 catch (failed_constructor& err) {
1523 return boost::shared_ptr<MidiRegion>();
1528 Session::get_sources_as_xml ()
1531 XMLNode* node = new XMLNode (X_("Sources"));
1532 Glib::Mutex::Lock lm (source_lock);
1534 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1535 node->add_child_nocopy (i->second->get_state());
1542 Session::path_from_region_name (DataType type, string name, string identifier)
1544 char buf[PATH_MAX+1];
1546 SessionDirectory sdir(get_best_session_directory_for_new_source());
1547 string sound_dir = ((type == DataType::AUDIO)
1548 ? sdir.sound_path().to_string()
1549 : sdir.midi_path().to_string());
1551 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1553 for (n = 0; n < 999999; ++n) {
1554 if (identifier.length()) {
1555 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1556 identifier.c_str(), n, ext.c_str());
1558 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1562 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1567 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1576 Session::load_sources (const XMLNode& node)
1579 XMLNodeConstIterator niter;
1580 boost::shared_ptr<Source> source;
1582 nlist = node.children();
1586 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1589 if ((source = XMLSourceFactory (**niter)) == 0) {
1590 error << _("Session: cannot create Source from XML description.") << endmsg;
1594 catch (non_existent_source& err) {
1595 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1596 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1603 boost::shared_ptr<Source>
1604 Session::XMLSourceFactory (const XMLNode& node)
1606 if (node.name() != "Source") {
1607 return boost::shared_ptr<Source>();
1611 return SourceFactory::create (*this, node);
1614 catch (failed_constructor& err) {
1615 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1616 return boost::shared_ptr<Source>();
1621 Session::save_template (string template_name)
1624 string xml_path, bak_path, template_path;
1626 if (_state_of_the_state & CannotSave) {
1630 sys::path user_template_dir(user_template_directory());
1634 sys::create_directories (user_template_dir);
1636 catch(sys::filesystem_error& ex)
1638 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1639 user_template_dir.to_string(), ex.what()) << endmsg;
1643 tree.set_root (&get_template());
1645 sys::path template_file_path(user_template_dir);
1646 template_file_path /= template_name + template_suffix;
1648 if (sys::exists (template_file_path))
1650 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1651 template_file_path.to_string()) << endmsg;
1655 if (!tree.write (template_file_path.to_string())) {
1656 error << _("mix template not saved") << endmsg;
1664 Session::refresh_disk_space ()
1667 struct statfs statfsbuf;
1668 vector<space_and_path>::iterator i;
1669 Glib::Mutex::Lock lm (space_lock);
1672 /* get freespace on every FS that is part of the session path */
1674 _total_free_4k_blocks = 0;
1676 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1677 statfs ((*i).path.c_str(), &statfsbuf);
1679 scale = statfsbuf.f_bsize/4096.0;
1681 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1682 _total_free_4k_blocks += (*i).blocks;
1688 Session::get_best_session_directory_for_new_source ()
1690 vector<space_and_path>::iterator i;
1691 string result = _session_dir->root_path().to_string();
1693 /* handle common case without system calls */
1695 if (session_dirs.size() == 1) {
1699 /* OK, here's the algorithm we're following here:
1701 We want to select which directory to use for
1702 the next file source to be created. Ideally,
1703 we'd like to use a round-robin process so as to
1704 get maximum performance benefits from splitting
1705 the files across multiple disks.
1707 However, in situations without much diskspace, an
1708 RR approach may end up filling up a filesystem
1709 with new files while others still have space.
1710 Its therefore important to pay some attention to
1711 the freespace in the filesystem holding each
1712 directory as well. However, if we did that by
1713 itself, we'd keep creating new files in the file
1714 system with the most space until it was as full
1715 as all others, thus negating any performance
1716 benefits of this RAID-1 like approach.
1718 So, we use a user-configurable space threshold. If
1719 there are at least 2 filesystems with more than this
1720 much space available, we use RR selection between them.
1721 If not, then we pick the filesystem with the most space.
1723 This gets a good balance between the two
1727 refresh_disk_space ();
1729 int free_enough = 0;
1731 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1732 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1737 if (free_enough >= 2) {
1738 /* use RR selection process, ensuring that the one
1742 i = last_rr_session_dir;
1745 if (++i == session_dirs.end()) {
1746 i = session_dirs.begin();
1749 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1750 if (create_session_directory ((*i).path)) {
1752 last_rr_session_dir = i;
1757 } while (i != last_rr_session_dir);
1761 /* pick FS with the most freespace (and that
1762 seems to actually work ...)
1765 vector<space_and_path> sorted;
1766 space_and_path_ascending_cmp cmp;
1768 sorted = session_dirs;
1769 sort (sorted.begin(), sorted.end(), cmp);
1771 for (i = sorted.begin(); i != sorted.end(); ++i) {
1772 if (create_session_directory ((*i).path)) {
1774 last_rr_session_dir = i;
1784 Session::load_playlists (const XMLNode& node)
1787 XMLNodeConstIterator niter;
1788 boost::shared_ptr<Playlist> playlist;
1790 nlist = node.children();
1794 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1796 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1797 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1805 Session::load_unused_playlists (const XMLNode& node)
1808 XMLNodeConstIterator niter;
1809 boost::shared_ptr<Playlist> playlist;
1811 nlist = node.children();
1815 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1817 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1818 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1822 // now manually untrack it
1824 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1830 boost::shared_ptr<Playlist>
1831 Session::XMLPlaylistFactory (const XMLNode& node)
1834 return PlaylistFactory::create (*this, node);
1837 catch (failed_constructor& err) {
1838 return boost::shared_ptr<Playlist>();
1843 Session::load_named_selections (const XMLNode& node)
1846 XMLNodeConstIterator niter;
1849 nlist = node.children();
1853 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1855 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1856 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1864 Session::XMLNamedSelectionFactory (const XMLNode& node)
1867 return new NamedSelection (*this, node);
1870 catch (failed_constructor& err) {
1876 Session::automation_dir () const
1879 res += "automation/";
1884 Session::load_bundles (const XMLNode& node)
1886 XMLNodeList nlist = node.children();
1887 XMLNodeConstIterator niter;
1891 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1892 if ((*niter)->name() == "InputConnection") {
1893 add_bundle (new ARDOUR::InputBundle (**niter));
1894 } else if ((*niter)->name() == "OutputConnection") {
1895 add_bundle (new ARDOUR::OutputBundle (**niter));
1897 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1906 Session::load_edit_groups (const XMLNode& node)
1908 return load_route_groups (node, true);
1912 Session::load_mix_groups (const XMLNode& node)
1914 return load_route_groups (node, false);
1918 Session::load_route_groups (const XMLNode& node, bool edit)
1920 XMLNodeList nlist = node.children();
1921 XMLNodeConstIterator niter;
1926 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1927 if ((*niter)->name() == "RouteGroup") {
1929 rg = add_edit_group ("");
1930 rg->set_state (**niter);
1932 rg = add_mix_group ("");
1933 rg->set_state (**niter);
1942 state_file_filter (const string &str, void *arg)
1944 return (str.length() > strlen(statefile_suffix) &&
1945 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
1949 bool operator()(const string* a, const string* b) {
1955 remove_end(string* state)
1957 string statename(*state);
1959 string::size_type start,end;
1960 if ((start = statename.find_last_of ('/')) != string::npos) {
1961 statename = statename.substr (start+1);
1964 if ((end = statename.rfind(".ardour")) == string::npos) {
1965 end = statename.length();
1968 return new string(statename.substr (0, end));
1972 Session::possible_states (string path)
1974 PathScanner scanner;
1975 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
1977 transform(states->begin(), states->end(), states->begin(), remove_end);
1980 sort (states->begin(), states->end(), cmp);
1986 Session::possible_states () const
1988 return possible_states(_path);
1992 Session::auto_save()
1994 save_state (_current_snapshot_name);
1998 Session::add_edit_group (string name)
2000 RouteGroup* rg = new RouteGroup (*this, name);
2001 edit_groups.push_back (rg);
2002 edit_group_added (rg); /* EMIT SIGNAL */
2008 Session::add_mix_group (string name)
2010 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2011 mix_groups.push_back (rg);
2012 mix_group_added (rg); /* EMIT SIGNAL */
2018 Session::remove_edit_group (RouteGroup& rg)
2020 list<RouteGroup*>::iterator i;
2022 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2023 (*i)->apply (&Route::drop_edit_group, this);
2024 edit_groups.erase (i);
2025 edit_group_removed (); /* EMIT SIGNAL */
2032 Session::remove_mix_group (RouteGroup& rg)
2034 list<RouteGroup*>::iterator i;
2036 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2037 (*i)->apply (&Route::drop_mix_group, this);
2038 mix_groups.erase (i);
2039 mix_group_removed (); /* EMIT SIGNAL */
2046 Session::mix_group_by_name (string name)
2048 list<RouteGroup *>::iterator i;
2050 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2051 if ((*i)->name() == name) {
2059 Session::edit_group_by_name (string name)
2061 list<RouteGroup *>::iterator i;
2063 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2064 if ((*i)->name() == name) {
2072 Session::begin_reversible_command (const string& name)
2074 current_trans = new UndoTransaction;
2075 current_trans->set_name (name);
2079 Session::commit_reversible_command (Command *cmd)
2084 current_trans->add_command (cmd);
2087 gettimeofday (&now, 0);
2088 current_trans->set_timestamp (now);
2090 _history.add (current_trans);
2093 Session::GlobalRouteBooleanState
2094 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2096 GlobalRouteBooleanState s;
2097 boost::shared_ptr<RouteList> r = routes.reader ();
2099 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2100 if (!(*i)->is_hidden()) {
2101 RouteBooleanState v;
2104 Route* r = (*i).get();
2105 v.second = (r->*method)();
2114 Session::GlobalRouteMeterState
2115 Session::get_global_route_metering ()
2117 GlobalRouteMeterState s;
2118 boost::shared_ptr<RouteList> r = routes.reader ();
2120 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2121 if (!(*i)->is_hidden()) {
2125 v.second = (*i)->meter_point();
2135 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2137 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2139 boost::shared_ptr<Route> r = (i->first.lock());
2142 r->set_meter_point (i->second, arg);
2148 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2150 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2152 boost::shared_ptr<Route> r = (i->first.lock());
2155 Route* rp = r.get();
2156 (rp->*method) (i->second, arg);
2162 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2164 set_global_route_boolean (s, &Route::set_mute, src);
2168 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2170 set_global_route_boolean (s, &Route::set_solo, src);
2174 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2176 set_global_route_boolean (s, &Route::set_record_enable, src);
2181 Session::global_mute_memento (void* src)
2183 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2187 Session::global_metering_memento (void* src)
2189 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2193 Session::global_solo_memento (void* src)
2195 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2199 Session::global_record_enable_memento (void* src)
2201 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2206 accept_all_non_peak_files (const string& path, void *arg)
2208 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2212 accept_all_state_files (const string& path, void *arg)
2214 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2218 Session::find_all_sources (string path, set<string>& result)
2223 if (!tree.read (path)) {
2227 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2232 XMLNodeConstIterator niter;
2234 nlist = node->children();
2238 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2242 if ((prop = (*niter)->property (X_("name"))) == 0) {
2246 if (prop->value()[0] == '/') {
2247 /* external file, ignore */
2251 sys::path source_path = _session_dir->sound_path ();
2253 source_path /= prop->value ();
2255 result.insert (source_path.to_string ());
2262 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2264 PathScanner scanner;
2265 vector<string*>* state_files;
2267 string this_snapshot_path;
2273 if (ripped[ripped.length()-1] == '/') {
2274 ripped = ripped.substr (0, ripped.length() - 1);
2277 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2279 if (state_files == 0) {
2284 this_snapshot_path = _path;
2285 this_snapshot_path += _current_snapshot_name;
2286 this_snapshot_path += statefile_suffix;
2288 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2290 if (exclude_this_snapshot && **i == this_snapshot_path) {
2294 if (find_all_sources (**i, result) < 0) {
2302 struct RegionCounter {
2303 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2304 AudioSourceList::iterator iter;
2305 boost::shared_ptr<Region> region;
2308 RegionCounter() : count (0) {}
2312 Session::cleanup_sources (Session::cleanup_report& rep)
2314 // FIXME: needs adaptation to midi
2316 vector<boost::shared_ptr<Source> > dead_sources;
2317 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2318 PathScanner scanner;
2320 vector<space_and_path>::iterator i;
2321 vector<space_and_path>::iterator nexti;
2322 vector<string*>* soundfiles;
2323 vector<string> unused;
2324 set<string> all_sources;
2329 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2331 /* step 1: consider deleting all unused playlists */
2333 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2336 status = AskAboutPlaylistDeletion (*x);
2345 playlists_tbd.push_back (*x);
2349 /* leave it alone */
2354 /* now delete any that were marked for deletion */
2356 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2357 (*x)->drop_references ();
2360 playlists_tbd.clear ();
2362 /* step 2: find all un-used sources */
2367 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2369 SourceMap::iterator tmp;
2374 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2378 if (!i->second->used() && i->second->length() > 0) {
2379 dead_sources.push_back (i->second);
2380 i->second->GoingAway();
2386 /* build a list of all the possible sound directories for the session */
2388 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2393 SessionDirectory sdir ((*i).path);
2394 sound_path += sdir.sound_path().to_string();
2396 if (nexti != session_dirs.end()) {
2403 /* now do the same thing for the files that ended up in the sounds dir(s)
2404 but are not referenced as sources in any snapshot.
2407 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2409 if (soundfiles == 0) {
2413 /* find all sources, but don't use this snapshot because the
2414 state file on disk still references sources we may have already
2418 find_all_sources_across_snapshots (all_sources, true);
2420 /* add our current source list
2423 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2424 boost::shared_ptr<AudioFileSource> fs;
2426 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2427 all_sources.insert (fs->path());
2431 char tmppath1[PATH_MAX+1];
2432 char tmppath2[PATH_MAX+1];
2434 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2439 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2441 realpath(spath.c_str(), tmppath1);
2442 realpath((*i).c_str(), tmppath2);
2444 if (strcmp(tmppath1, tmppath2) == 0) {
2451 unused.push_back (spath);
2455 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2457 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2458 struct stat statbuf;
2460 rep.paths.push_back (*x);
2461 if (stat ((*x).c_str(), &statbuf) == 0) {
2462 rep.space += statbuf.st_size;
2467 /* don't move the file across filesystems, just
2468 stick it in the `dead_sound_dir_name' directory
2469 on whichever filesystem it was already on.
2472 if ((*x).find ("/sounds/") != string::npos) {
2474 /* old school, go up 1 level */
2476 newpath = Glib::path_get_dirname (*x); // "sounds"
2477 newpath = Glib::path_get_dirname (newpath); // "session-name"
2481 /* new school, go up 4 levels */
2483 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2484 newpath = Glib::path_get_dirname (newpath); // "session-name"
2485 newpath = Glib::path_get_dirname (newpath); // "interchange"
2486 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2490 newpath += dead_sound_dir_name;
2492 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2493 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2498 newpath += Glib::path_get_basename ((*x));
2500 if (access (newpath.c_str(), F_OK) == 0) {
2502 /* the new path already exists, try versioning */
2504 char buf[PATH_MAX+1];
2508 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2511 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2512 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2516 if (version == 999) {
2517 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2521 newpath = newpath_v;
2526 /* it doesn't exist, or we can't read it or something */
2530 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2531 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2532 (*x), newpath, strerror (errno))
2537 /* see if there an easy to find peakfile for this file, and remove it.
2540 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2541 peakpath += peakfile_suffix;
2543 if (access (peakpath.c_str(), W_OK) == 0) {
2544 if (::unlink (peakpath.c_str()) != 0) {
2545 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2546 peakpath, _path, strerror (errno))
2548 /* try to back out */
2549 rename (newpath.c_str(), _path.c_str());
2557 /* dump the history list */
2561 /* save state so we don't end up a session file
2562 referring to non-existent sources.
2568 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2573 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2575 // FIXME: needs adaptation for MIDI
2577 vector<space_and_path>::iterator i;
2578 string dead_sound_dir;
2579 struct dirent* dentry;
2580 struct stat statbuf;
2586 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2588 dead_sound_dir = (*i).path;
2589 dead_sound_dir += dead_sound_dir_name;
2591 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2595 while ((dentry = readdir (dead)) != 0) {
2597 /* avoid '.' and '..' */
2599 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2600 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2606 fullpath = dead_sound_dir;
2608 fullpath += dentry->d_name;
2610 if (stat (fullpath.c_str(), &statbuf)) {
2614 if (!S_ISREG (statbuf.st_mode)) {
2618 if (unlink (fullpath.c_str())) {
2619 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2620 fullpath, strerror (errno))
2624 rep.paths.push_back (dentry->d_name);
2625 rep.space += statbuf.st_size;
2636 Session::set_dirty ()
2638 bool was_dirty = dirty();
2640 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2643 DirtyChanged(); /* EMIT SIGNAL */
2649 Session::set_clean ()
2651 bool was_dirty = dirty();
2653 _state_of_the_state = Clean;
2656 DirtyChanged(); /* EMIT SIGNAL */
2661 Session::set_deletion_in_progress ()
2663 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2667 Session::add_controllable (boost::shared_ptr<Controllable> c)
2669 /* this adds a controllable to the list managed by the Session.
2670 this is a subset of those managed by the Controllable class
2671 itself, and represents the only ones whose state will be saved
2672 as part of the session.
2675 Glib::Mutex::Lock lm (controllables_lock);
2676 controllables.insert (c);
2679 struct null_deleter { void operator()(void const *) const {} };
2682 Session::remove_controllable (Controllable* c)
2684 if (_state_of_the_state | Deletion) {
2688 Glib::Mutex::Lock lm (controllables_lock);
2690 Controllables::iterator x = controllables.find(
2691 boost::shared_ptr<Controllable>(c, null_deleter()));
2693 if (x != controllables.end()) {
2694 controllables.erase (x);
2698 boost::shared_ptr<Controllable>
2699 Session::controllable_by_id (const PBD::ID& id)
2701 Glib::Mutex::Lock lm (controllables_lock);
2703 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2704 if ((*i)->id() == id) {
2709 return boost::shared_ptr<Controllable>();
2713 Session::add_instant_xml (XMLNode& node)
2715 Stateful::add_instant_xml (node, _path);
2716 Config->add_instant_xml (node);
2720 Session::instant_xml (const string& node_name)
2722 return Stateful::instant_xml (node_name, _path);
2726 Session::save_history (string snapshot_name)
2732 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2734 if (snapshot_name.empty()) {
2735 snapshot_name = _current_snapshot_name;
2738 xml_path = _path + snapshot_name + ".history";
2740 bak_path = xml_path + ".bak";
2742 if ((access (xml_path.c_str(), F_OK) == 0) &&
2743 (rename (xml_path.c_str(), bak_path.c_str())))
2745 error << _("could not backup old history file, current history not saved.") << endmsg;
2749 if (!tree.write (xml_path))
2751 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2753 /* don't leave a corrupt file lying around if it is
2757 if (unlink (xml_path.c_str())) {
2758 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2760 if (rename (bak_path.c_str(), xml_path.c_str()))
2762 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2773 Session::restore_history (string snapshot_name)
2778 if (snapshot_name.empty()) {
2779 snapshot_name = _current_snapshot_name;
2783 xmlpath = _path + snapshot_name + ".history";
2784 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2786 if (access (xmlpath.c_str(), F_OK)) {
2787 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2791 if (!tree.read (xmlpath)) {
2792 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2796 /* replace history */
2799 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2802 UndoTransaction* ut = new UndoTransaction ();
2805 ut->set_name(t->property("name")->value());
2806 stringstream ss(t->property("tv_sec")->value());
2808 ss.str(t->property("tv_usec")->value());
2810 ut->set_timestamp(tv);
2812 for (XMLNodeConstIterator child_it = t->children().begin();
2813 child_it != t->children().end();
2816 XMLNode *n = *child_it;
2819 if (n->name() == "MementoCommand" ||
2820 n->name() == "MementoUndoCommand" ||
2821 n->name() == "MementoRedoCommand") {
2823 if ((c = memento_command_factory(n))) {
2827 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2829 if ((c = global_state_command_factory (*n))) {
2830 ut->add_command (c);
2835 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2846 Session::config_changed (const char* parameter_name)
2848 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2850 if (PARAM_IS ("seamless-loop")) {
2852 } else if (PARAM_IS ("rf-speed")) {
2854 } else if (PARAM_IS ("auto-loop")) {
2856 } else if (PARAM_IS ("auto-input")) {
2858 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2859 /* auto-input only makes a difference if we're rolling */
2861 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2863 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2864 if ((*i)->record_enabled ()) {
2865 (*i)->monitor_input (!Config->get_auto_input());
2870 } else if (PARAM_IS ("punch-in")) {
2874 if ((location = _locations.auto_punch_location()) != 0) {
2876 if (Config->get_punch_in ()) {
2877 replace_event (Event::PunchIn, location->start());
2879 remove_event (location->start(), Event::PunchIn);
2883 } else if (PARAM_IS ("punch-out")) {
2887 if ((location = _locations.auto_punch_location()) != 0) {
2889 if (Config->get_punch_out()) {
2890 replace_event (Event::PunchOut, location->end());
2892 clear_events (Event::PunchOut);
2896 } else if (PARAM_IS ("edit-mode")) {
2898 Glib::Mutex::Lock lm (playlist_lock);
2900 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2901 (*i)->set_edit_mode (Config->get_edit_mode ());
2904 } else if (PARAM_IS ("use-video-sync")) {
2906 waiting_for_sync_offset = Config->get_use_video_sync();
2908 } else if (PARAM_IS ("mmc-control")) {
2910 //poke_midi_thread ();
2912 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
2915 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
2918 } else if (PARAM_IS ("mmc-send-id")) {
2921 mmc->set_send_device_id (Config->get_mmc_send_device_id());
2924 } else if (PARAM_IS ("midi-control")) {
2926 //poke_midi_thread ();
2928 } else if (PARAM_IS ("raid-path")) {
2930 setup_raid_path (Config->get_raid_path());
2932 } else if (PARAM_IS ("smpte-format")) {
2936 } else if (PARAM_IS ("video-pullup")) {
2940 } else if (PARAM_IS ("seamless-loop")) {
2942 if (play_loop && transport_rolling()) {
2943 // to reset diskstreams etc
2944 request_play_loop (true);
2947 } else if (PARAM_IS ("rf-speed")) {
2949 cumulative_rf_motion = 0;
2952 } else if (PARAM_IS ("click-sound")) {
2954 setup_click_sounds (1);
2956 } else if (PARAM_IS ("click-emphasis-sound")) {
2958 setup_click_sounds (-1);
2960 } else if (PARAM_IS ("clicking")) {
2962 if (Config->get_clicking()) {
2963 if (_click_io && click_data) { // don't require emphasis data
2970 } else if (PARAM_IS ("send-mtc")) {
2972 /* only set the internal flag if we have
2976 if (_mtc_port != 0) {
2977 session_send_mtc = Config->get_send_mtc();
2978 if (session_send_mtc) {
2979 /* mark us ready to send */
2980 next_quarter_frame_to_send = 0;
2983 session_send_mtc = false;
2986 } else if (PARAM_IS ("send-mmc")) {
2988 /* only set the internal flag if we have
2992 if (_mmc_port != 0) {
2993 session_send_mmc = Config->get_send_mmc();
2996 session_send_mmc = false;
2999 } else if (PARAM_IS ("midi-feedback")) {
3001 /* only set the internal flag if we have
3005 if (_mtc_port != 0) {
3006 session_midi_feedback = Config->get_midi_feedback();
3009 } else if (PARAM_IS ("jack-time-master")) {
3011 engine().reset_timebase ();
3013 } else if (PARAM_IS ("native-file-header-format")) {
3015 if (!first_file_header_format_reset) {
3016 reset_native_file_format ();
3019 first_file_header_format_reset = false;
3021 } else if (PARAM_IS ("native-file-data-format")) {
3023 if (!first_file_data_format_reset) {
3024 reset_native_file_format ();
3027 first_file_data_format_reset = false;
3029 } else if (PARAM_IS ("slave-source")) {
3030 set_slave_source (Config->get_slave_source());
3031 } else if (PARAM_IS ("remote-model")) {
3032 set_remote_control_ids ();
3033 } else if (PARAM_IS ("denormal-model")) {