2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #define __STDC_FORMAT_MACROS 1
28 #include <sigc++/bind.h>
30 #include <cstdio> /* snprintf(3) ... grrr */
45 #include <sys/param.h>
46 #include <sys/mount.h>
51 #include <midi++/mmc.h>
52 #include <midi++/port.h>
53 #include <pbd/error.h>
55 #include <glibmm/thread.h>
56 #include <pbd/pathscanner.h>
57 #include <pbd/pthread_utils.h>
58 #include <pbd/search_path.h>
59 #include <pbd/stacktrace.h>
61 #include <ardour/audioengine.h>
62 #include <ardour/configuration.h>
63 #include <ardour/session.h>
64 #include <ardour/session_directory.h>
65 #include <ardour/session_utils.h>
66 #include <ardour/session_state_utils.h>
67 #include <ardour/buffer.h>
68 #include <ardour/audio_diskstream.h>
69 #include <ardour/midi_diskstream.h>
70 #include <ardour/utils.h>
71 #include <ardour/audioplaylist.h>
72 #include <ardour/midi_playlist.h>
73 #include <ardour/smf_source.h>
74 #include <ardour/audiofilesource.h>
75 #include <ardour/silentfilesource.h>
76 #include <ardour/sndfilesource.h>
77 #include <ardour/midi_source.h>
78 #include <ardour/sndfile_helpers.h>
79 #include <ardour/auditioner.h>
80 #include <ardour/export.h>
81 #include <ardour/io_processor.h>
82 #include <ardour/send.h>
83 #include <ardour/processor.h>
84 #include <ardour/bundle.h>
85 #include <ardour/slave.h>
86 #include <ardour/tempo.h>
87 #include <ardour/audio_track.h>
88 #include <ardour/midi_track.h>
89 #include <ardour/cycle_timer.h>
90 #include <ardour/utils.h>
91 #include <ardour/named_selection.h>
92 #include <ardour/version.h>
93 #include <ardour/location.h>
94 #include <ardour/audioregion.h>
95 #include <ardour/midi_region.h>
96 #include <ardour/crossfade.h>
97 #include <ardour/control_protocol_manager.h>
98 #include <ardour/region_factory.h>
99 #include <ardour/source_factory.h>
100 #include <ardour/playlist_factory.h>
101 #include <ardour/filename_extensions.h>
102 #include <ardour/directory_names.h>
103 #include <ardour/template_utils.h>
105 #include <control_protocol/control_protocol.h>
111 using namespace ARDOUR;
115 Session::first_stage_init (string fullpath, string snapshot_name)
117 if (fullpath.length() == 0) {
119 throw failed_constructor();
122 char buf[PATH_MAX+1];
123 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
124 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
126 throw failed_constructor();
131 if (_path[_path.length()-1] != '/') {
135 /* these two are just provisional settings. set_state()
136 will likely override them.
139 _name = _current_snapshot_name = snapshot_name;
141 set_history_depth (Config->get_history_depth());
143 _current_frame_rate = _engine.frame_rate ();
144 _tempo_map = new TempoMap (_current_frame_rate);
145 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
149 g_atomic_int_set (&processing_prohibited, 0);
151 _transport_speed = 0;
152 _last_transport_speed = 0;
153 auto_play_legal = false;
154 transport_sub_state = 0;
155 _transport_frame = 0;
157 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
158 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
159 _end_location_is_free = true;
160 g_atomic_int_set (&_record_status, Disabled);
161 loop_changing = false;
163 _last_roll_location = 0;
164 _last_record_location = 0;
165 pending_locate_frame = 0;
166 pending_locate_roll = false;
167 pending_locate_flush = false;
168 dstream_buffer_size = 0;
170 state_was_pending = false;
172 outbound_mtc_smpte_frame = 0;
173 next_quarter_frame_to_send = -1;
174 current_block_size = 0;
175 solo_update_disabled = false;
176 currently_soloing = false;
177 _have_captured = false;
178 _worst_output_latency = 0;
179 _worst_input_latency = 0;
180 _worst_track_latency = 0;
181 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
183 butler_mixdown_buffer = 0;
184 butler_gain_buffer = 0;
186 session_send_mmc = false;
187 session_send_mtc = false;
188 post_transport_work = PostTransportWork (0);
189 g_atomic_int_set (&butler_should_do_transport_work, 0);
190 g_atomic_int_set (&butler_active, 0);
191 g_atomic_int_set (&_playback_load, 100);
192 g_atomic_int_set (&_capture_load, 100);
193 g_atomic_int_set (&_playback_load_min, 100);
194 g_atomic_int_set (&_capture_load_min, 100);
196 waiting_to_start = false;
198 _gain_automation_buffer = 0;
199 _pan_automation_buffer = 0;
201 pending_abort = false;
202 destructive_index = 0;
204 first_file_data_format_reset = true;
205 first_file_header_format_reset = true;
206 butler_thread = (pthread_t) 0;
207 //midi_thread = (pthread_t) 0;
209 AudioDiskstream::allocate_working_buffers();
211 /* default short fade = 15ms */
213 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
214 SndFileSource::setup_standard_crossfades (frame_rate());
216 last_mmc_step.tv_sec = 0;
217 last_mmc_step.tv_usec = 0;
220 /* click sounds are unset by default, which causes us to internal
221 waveforms for clicks.
225 click_emphasis_data = 0;
227 click_emphasis_length = 0;
230 process_function = &Session::process_with_events;
232 if (Config->get_use_video_sync()) {
233 waiting_for_sync_offset = true;
235 waiting_for_sync_offset = false;
238 _current_frame_rate = 48000;
239 _base_frame_rate = 48000;
243 _smpte_offset_negative = true;
244 last_smpte_valid = false;
248 last_rr_session_dir = session_dirs.begin();
249 refresh_disk_space ();
251 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
255 average_slave_delta = 1800;
256 have_first_delta_accumulator = false;
257 delta_accumulator_cnt = 0;
258 slave_state = Stopped;
260 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
262 /* These are all static "per-class" signals */
264 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
265 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
266 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
267 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
268 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
269 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
271 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
273 IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
275 /* stop IO objects from doing stuff until we're ready for them */
277 IO::disable_panners ();
278 IO::disable_ports ();
279 IO::disable_connecting ();
283 Session::second_stage_init (bool new_session)
285 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
288 if (load_state (_current_snapshot_name)) {
291 remove_empty_sounds ();
294 if (start_butler_thread()) {
298 /*if (start_midi_thread ()) {
302 // set_state() will call setup_raid_path(), but if it's a new session we need
303 // to call setup_raid_path() here.
305 if (set_state (*state_tree->root())) {
309 setup_raid_path(_path);
312 /* we can't save till after ::when_engine_running() is called,
313 because otherwise we save state with no connections made.
314 therefore, we reset _state_of_the_state because ::set_state()
315 will have cleared it.
317 we also have to include Loading so that any events that get
318 generated between here and the end of ::when_engine_running()
319 will be processed directly rather than queued.
322 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
324 // set_auto_input (true);
325 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
326 _locations.added.connect (mem_fun (this, &Session::locations_added));
327 setup_click_sounds (0);
328 setup_midi_control ();
330 /* Pay attention ... */
332 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
333 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
336 when_engine_running();
339 /* handle this one in a different way than all others, so that its clear what happened */
341 catch (AudioEngine::PortRegistrationFailure& err) {
342 error << _("Unable to create all required ports")
351 //send_full_time_code ();
352 _engine.transport_locate (0);
353 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
354 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
356 ControlProtocolManager::instance().set_session (*this);
359 _end_location_is_free = true;
361 _end_location_is_free = false;
368 Session::raid_path () const
370 SearchPath raid_search_path;
372 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
373 raid_search_path += sys::path((*i).path);
376 return raid_search_path.to_string ();
380 Session::setup_raid_path (string path)
389 session_dirs.clear ();
391 SearchPath search_path(path);
392 SearchPath sound_search_path;
393 SearchPath midi_search_path;
396 SearchPath::const_iterator i = search_path.begin();
397 i != search_path.end();
401 sp.path = (*i).to_string ();
402 sp.blocks = 0; // not needed
403 session_dirs.push_back (sp);
405 SessionDirectory sdir(sp.path);
407 sound_search_path += sdir.sound_path ();
408 midi_search_path += sdir.midi_path ();
411 // set the AudioFileSource and SMFSource search path
413 AudioFileSource::set_search_path (sound_search_path.to_string ());
414 SMFSource::set_search_path (midi_search_path.to_string ());
416 // reset the round-robin soundfile path thingie
418 last_rr_session_dir = session_dirs.begin();
422 Session::initialize_start_and_end_locations (nframes_t start, nframes_t end)
424 start_location->set_end (start);
425 _locations.add (start_location);
427 end_location->set_end (end);
428 _locations.add (end_location);
432 Session::create_session_file ()
434 _state_of_the_state = Clean;
436 if (save_state (_current_snapshot_name)) {
437 error << "Could not create new session file" << endmsg;
444 Session::create_session_file_from_template (const string& template_path)
446 sys::path session_file_path(_session_dir->root_path());
448 session_file_path /= _name + statefile_suffix;
452 sys::copy_file (template_path, session_file_path);
454 catch(sys::filesystem_error& ex)
456 error << string_compose (_("Could not use session template %1 to create new session (%2)."),
457 template_path, ex.what())
465 Session::load_diskstreams (const XMLNode& node)
468 XMLNodeConstIterator citer;
470 clist = node.children();
472 for (citer = clist.begin(); citer != clist.end(); ++citer) {
475 /* diskstreams added automatically by DiskstreamCreated handler */
476 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
477 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
478 add_diskstream (dstream);
479 } else if ((*citer)->name() == "MidiDiskstream") {
480 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
481 add_diskstream (dstream);
483 error << _("Session: unknown diskstream type in XML") << endmsg;
487 catch (failed_constructor& err) {
488 error << _("Session: could not load diskstream via XML state") << endmsg;
497 Session::maybe_write_autosave()
499 if (dirty() && record_status() != Recording) {
500 save_state("", true);
505 Session::remove_pending_capture_state ()
507 sys::path pending_state_file_path(_session_dir->root_path());
509 pending_state_file_path /= _current_snapshot_name + pending_suffix;
513 sys::remove (pending_state_file_path);
515 catch(sys::filesystem_error& ex)
517 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
518 pending_state_file_path.to_string(), ex.what()) << endmsg;
522 /** Rename a state file.
523 * @param snapshot_name Snapshot name.
526 Session::rename_state (string old_name, string new_name)
528 if (old_name == _current_snapshot_name || old_name == _name) {
529 /* refuse to rename the current snapshot or the "main" one */
533 const string old_xml_filename = old_name + statefile_suffix;
534 const string new_xml_filename = new_name + statefile_suffix;
536 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
537 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
541 sys::rename (old_xml_path, new_xml_path);
543 catch (const sys::filesystem_error& err)
545 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
546 old_name, new_name, err.what()) << endmsg;
550 /** Remove a state file.
551 * @param snapshot_name Snapshot name.
554 Session::remove_state (string snapshot_name)
556 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
557 // refuse to remove the current snapshot or the "main" one
561 sys::path xml_path(_session_dir->root_path());
563 xml_path /= snapshot_name + statefile_suffix;
565 if (!create_backup_file (xml_path)) {
566 // don't remove it if a backup can't be made
567 // create_backup_file will log the error.
572 sys::remove (xml_path);
576 Session::save_state (string snapshot_name, bool pending)
579 sys::path xml_path(_session_dir->root_path());
581 if (_state_of_the_state & CannotSave) {
585 if (!_engine.connected ()) {
586 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
591 /* tell sources we're saving first, in case they write out to a new file
592 * which should be saved with the state rather than the old one */
593 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
594 i->second->session_saved();
596 tree.set_root (&get_state());
598 if (snapshot_name.empty()) {
599 snapshot_name = _current_snapshot_name;
604 /* proper save: use statefile_suffix (.ardour in English) */
606 xml_path /= snapshot_name + statefile_suffix;
608 /* make a backup copy of the old file */
610 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
611 // create_backup_file will log the error
617 /* pending save: use pending_suffix (.pending in English) */
618 xml_path /= snapshot_name + pending_suffix;
621 sys::path tmp_path(_session_dir->root_path());
623 tmp_path /= snapshot_name + temp_suffix;
625 // cerr << "actually writing state to " << xml_path.to_string() << endl;
627 if (!tree.write (tmp_path.to_string())) {
628 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
629 sys::remove (tmp_path);
634 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
635 error << string_compose (_("could not rename temporary session file %1 to %2"),
636 tmp_path.to_string(), xml_path.to_string()) << endmsg;
637 sys::remove (tmp_path);
644 save_history (snapshot_name);
646 bool was_dirty = dirty();
648 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
651 DirtyChanged (); /* EMIT SIGNAL */
654 StateSaved (snapshot_name); /* EMIT SIGNAL */
661 Session::restore_state (string snapshot_name)
663 if (load_state (snapshot_name) == 0) {
664 set_state (*state_tree->root());
671 Session::load_state (string snapshot_name)
678 state_was_pending = false;
680 /* check for leftover pending state from a crashed capture attempt */
682 sys::path xmlpath(_session_dir->root_path());
683 xmlpath /= snapshot_name + pending_suffix;
685 if (sys::exists (xmlpath)) {
687 /* there is pending state from a crashed capture attempt */
689 if (AskAboutPendingState()) {
690 state_was_pending = true;
694 if (!state_was_pending) {
695 xmlpath = _session_dir->root_path();
696 xmlpath /= snapshot_name + statefile_suffix;
699 if (!sys::exists (xmlpath)) {
700 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
704 state_tree = new XMLTree;
708 if (!state_tree->read (xmlpath.to_string())) {
709 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
715 XMLNode& root (*state_tree->root());
717 if (root.name() != X_("Session")) {
718 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
724 const XMLProperty* prop;
727 if ((prop = root.property ("version")) == 0) {
728 /* no version implies very old version of Ardour */
732 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
733 if (major_version < 2) {
740 sys::path backup_path(_session_dir->root_path());
742 backup_path /= snapshot_name + "-1" + statefile_suffix;
744 // only create a backup once
745 if (sys::exists (backup_path)) {
749 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
750 xmlpath.to_string(), backup_path.to_string())
755 sys::copy_file (xmlpath, backup_path);
757 catch(sys::filesystem_error& ex)
759 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
760 xmlpath.to_string(), ex.what())
770 Session::load_options (const XMLNode& node)
774 LocaleGuard lg (X_("POSIX"));
776 Config->set_variables (node, ConfigVariableBase::Session);
778 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
779 if ((prop = child->property ("val")) != 0) {
780 _end_location_is_free = (prop->value() == "yes");
788 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
790 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
791 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
793 return owner & modified_by_session_or_user;
797 Session::get_options () const
800 LocaleGuard lg (X_("POSIX"));
802 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
804 child = option_root.add_child ("end-marker-is-free");
805 child->add_property ("val", _end_location_is_free ? "yes" : "no");
817 Session::get_template()
819 /* if we don't disable rec-enable, diskstreams
820 will believe they need to store their capture
821 sources in their state node.
824 disable_record (false);
830 Session::state(bool full_state)
832 XMLNode* node = new XMLNode("Session");
835 // store libardour version, just in case
837 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
838 libardour_major_version, libardour_minor_version, libardour_micro_version);
839 node->add_property("version", string(buf));
841 /* store configuration settings */
846 node->add_property ("name", _name);
848 if (session_dirs.size() > 1) {
852 vector<space_and_path>::iterator i = session_dirs.begin();
853 vector<space_and_path>::iterator next;
855 ++i; /* skip the first one */
859 while (i != session_dirs.end()) {
863 if (next != session_dirs.end()) {
873 child = node->add_child ("Path");
874 child->add_content (p);
878 /* save the ID counter */
880 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
881 node->add_property ("id-counter", buf);
883 /* various options */
885 node->add_child_nocopy (get_options());
887 child = node->add_child ("Sources");
890 Glib::Mutex::Lock sl (source_lock);
892 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
894 /* Don't save information about AudioFileSources that are empty */
896 boost::shared_ptr<AudioFileSource> fs;
898 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
900 /* Don't save sources that are empty, unless they're destructive (which are OK
901 if they are empty, because we will re-use them every time.)
904 if (!fs->destructive()) {
905 if (fs->length() == 0) {
911 child->add_child_nocopy (siter->second->get_state());
915 child = node->add_child ("Regions");
918 Glib::Mutex::Lock rl (region_lock);
920 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
922 /* only store regions not attached to playlists */
924 if (i->second->playlist() == 0) {
925 child->add_child_nocopy (i->second->state (true));
930 child = node->add_child ("DiskStreams");
933 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
934 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
935 if (!(*i)->hidden()) {
936 child->add_child_nocopy ((*i)->get_state());
942 node->add_child_nocopy (_locations.get_state());
944 // for a template, just create a new Locations, populate it
945 // with the default start and end, and get the state for that.
947 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
948 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
951 end->set_end(compute_initial_length());
953 node->add_child_nocopy (loc.get_state());
956 child = node->add_child ("Bundles");
958 Glib::Mutex::Lock lm (bundle_lock);
959 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
960 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
962 child->add_child_nocopy (b->get_state());
967 child = node->add_child ("Routes");
969 boost::shared_ptr<RouteList> r = routes.reader ();
971 RoutePublicOrderSorter cmp;
972 RouteList public_order (*r);
973 public_order.sort (cmp);
975 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
976 if (!(*i)->is_hidden()) {
978 child->add_child_nocopy ((*i)->get_state());
980 child->add_child_nocopy ((*i)->get_template());
987 child = node->add_child ("EditGroups");
988 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
989 child->add_child_nocopy ((*i)->get_state());
992 child = node->add_child ("MixGroups");
993 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
994 child->add_child_nocopy ((*i)->get_state());
997 child = node->add_child ("Playlists");
998 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
999 if (!(*i)->hidden()) {
1000 if (!(*i)->empty()) {
1002 child->add_child_nocopy ((*i)->get_state());
1004 child->add_child_nocopy ((*i)->get_template());
1010 child = node->add_child ("UnusedPlaylists");
1011 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1012 if (!(*i)->hidden()) {
1013 if (!(*i)->empty()) {
1015 child->add_child_nocopy ((*i)->get_state());
1017 child->add_child_nocopy ((*i)->get_template());
1025 child = node->add_child ("Click");
1026 child->add_child_nocopy (_click_io->state (full_state));
1030 child = node->add_child ("NamedSelections");
1031 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1033 child->add_child_nocopy ((*i)->get_state());
1038 node->add_child_nocopy (_tempo_map->get_state());
1040 node->add_child_nocopy (get_control_protocol_state());
1043 node->add_child_copy (*_extra_xml);
1050 Session::get_control_protocol_state ()
1052 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1053 return cpm.get_state();
1057 Session::set_state (const XMLNode& node)
1061 const XMLProperty* prop;
1064 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1066 if (node.name() != X_("Session")){
1067 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1071 if ((prop = node.property ("name")) != 0) {
1072 _name = prop->value ();
1075 setup_raid_path(_session_dir->root_path().to_string());
1077 if ((prop = node.property (X_("id-counter"))) != 0) {
1079 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1080 ID::init_counter (x);
1082 /* old sessions used a timebased counter, so fake
1083 the startup ID counter based on a standard
1088 ID::init_counter (now);
1092 IO::disable_ports ();
1093 IO::disable_connecting ();
1095 /* Object loading order:
1113 if (use_config_midi_ports ()) {
1116 if ((child = find_named_node (node, "extra")) != 0) {
1117 _extra_xml = new XMLNode (*child);
1120 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1121 load_options (*child);
1122 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1123 load_options (*child);
1125 error << _("Session: XML state has no options section") << endmsg;
1128 if ((child = find_named_node (node, "Locations")) == 0) {
1129 error << _("Session: XML state has no locations section") << endmsg;
1131 } else if (_locations.set_state (*child)) {
1137 if ((location = _locations.auto_loop_location()) != 0) {
1138 set_auto_loop_location (location);
1141 if ((location = _locations.auto_punch_location()) != 0) {
1142 set_auto_punch_location (location);
1145 if ((location = _locations.end_location()) == 0) {
1146 _locations.add (end_location);
1148 delete end_location;
1149 end_location = location;
1152 if ((location = _locations.start_location()) == 0) {
1153 _locations.add (start_location);
1155 delete start_location;
1156 start_location = location;
1159 AudioFileSource::set_header_position_offset (start_location->start());
1161 if ((child = find_named_node (node, "Sources")) == 0) {
1162 error << _("Session: XML state has no sources section") << endmsg;
1164 } else if (load_sources (*child)) {
1168 if ((child = find_named_node (node, "Regions")) == 0) {
1169 error << _("Session: XML state has no Regions section") << endmsg;
1171 } else if (load_regions (*child)) {
1175 if ((child = find_named_node (node, "Playlists")) == 0) {
1176 error << _("Session: XML state has no playlists section") << endmsg;
1178 } else if (load_playlists (*child)) {
1182 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1184 } else if (load_unused_playlists (*child)) {
1188 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1189 if (load_named_selections (*child)) {
1194 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1195 error << _("Session: XML state has no diskstreams section") << endmsg;
1197 } else if (load_diskstreams (*child)) {
1201 if ((child = find_named_node (node, "Bundles")) == 0) {
1202 error << _("Session: XML state has no bundles section") << endmsg;
1205 /* We can't load Bundles yet as they need to be able
1206 to convert from port names to Port objects, which can't happen until
1208 _bundle_xml_node = new XMLNode (*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 SourceList master_sources;
1377 uint32_t nchans = 1;
1380 if (node.name() != X_("Region")) {
1381 return boost::shared_ptr<AudioRegion>();
1384 if ((prop = node.property (X_("channels"))) != 0) {
1385 nchans = atoi (prop->value().c_str());
1388 if ((prop = node.property ("name")) == 0) {
1389 cerr << "no name for this region\n";
1393 if ((prop = node.property (X_("source-0"))) == 0) {
1394 if ((prop = node.property ("source")) == 0) {
1395 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1396 return boost::shared_ptr<AudioRegion>();
1400 PBD::ID s_id (prop->value());
1402 if ((source = source_by_id (s_id)) == 0) {
1403 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1404 return boost::shared_ptr<AudioRegion>();
1407 as = boost::dynamic_pointer_cast<AudioSource>(source);
1409 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1410 return boost::shared_ptr<AudioRegion>();
1413 sources.push_back (as);
1415 /* pickup other channels */
1417 for (uint32_t n=1; n < nchans; ++n) {
1418 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1419 if ((prop = node.property (buf)) != 0) {
1421 PBD::ID id2 (prop->value());
1423 if ((source = source_by_id (id2)) == 0) {
1424 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1425 return boost::shared_ptr<AudioRegion>();
1428 as = boost::dynamic_pointer_cast<AudioSource>(source);
1430 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1431 return boost::shared_ptr<AudioRegion>();
1433 sources.push_back (as);
1437 for (uint32_t n=1; n < nchans; ++n) {
1438 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1439 if ((prop = node.property (buf)) != 0) {
1441 PBD::ID id2 (prop->value());
1443 if ((source = source_by_id (id2)) == 0) {
1444 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1445 return boost::shared_ptr<AudioRegion>();
1448 as = boost::dynamic_pointer_cast<AudioSource>(source);
1450 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1451 return boost::shared_ptr<AudioRegion>();
1453 master_sources.push_back (as);
1458 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1460 /* a final detail: this is the one and only place that we know how long missing files are */
1462 if (region->whole_file()) {
1463 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1464 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1466 sfp->set_length (region->length());
1471 if (!master_sources.empty()) {
1472 if (master_sources.size() == nchans) {
1473 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1475 region->set_master_sources (master_sources);
1483 catch (failed_constructor& err) {
1484 return boost::shared_ptr<AudioRegion>();
1488 boost::shared_ptr<MidiRegion>
1489 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1491 const XMLProperty* prop;
1492 boost::shared_ptr<Source> source;
1493 boost::shared_ptr<MidiSource> ms;
1495 uint32_t nchans = 1;
1497 if (node.name() != X_("Region")) {
1498 return boost::shared_ptr<MidiRegion>();
1501 if ((prop = node.property (X_("channels"))) != 0) {
1502 nchans = atoi (prop->value().c_str());
1505 if ((prop = node.property ("name")) == 0) {
1506 cerr << "no name for this region\n";
1510 // Multiple midi channels? that's just crazy talk
1511 assert(nchans == 1);
1513 if ((prop = node.property (X_("source-0"))) == 0) {
1514 if ((prop = node.property ("source")) == 0) {
1515 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1516 return boost::shared_ptr<MidiRegion>();
1520 PBD::ID s_id (prop->value());
1522 if ((source = source_by_id (s_id)) == 0) {
1523 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1524 return boost::shared_ptr<MidiRegion>();
1527 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1529 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1530 return boost::shared_ptr<MidiRegion>();
1533 sources.push_back (ms);
1536 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1537 /* a final detail: this is the one and only place that we know how long missing files are */
1539 if (region->whole_file()) {
1540 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1541 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1543 sfp->set_length (region->length());
1551 catch (failed_constructor& err) {
1552 return boost::shared_ptr<MidiRegion>();
1557 Session::get_sources_as_xml ()
1560 XMLNode* node = new XMLNode (X_("Sources"));
1561 Glib::Mutex::Lock lm (source_lock);
1563 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1564 node->add_child_nocopy (i->second->get_state());
1571 Session::path_from_region_name (DataType type, string name, string identifier)
1573 char buf[PATH_MAX+1];
1575 SessionDirectory sdir(get_best_session_directory_for_new_source());
1576 sys::path source_dir = ((type == DataType::AUDIO)
1577 ? sdir.sound_path() : sdir.midi_path());
1579 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1581 for (n = 0; n < 999999; ++n) {
1582 if (identifier.length()) {
1583 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1584 identifier.c_str(), n, ext.c_str());
1586 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1590 sys::path source_path = source_dir / buf;
1592 if (!sys::exists (source_path)) {
1593 return source_path.to_string();
1597 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1606 Session::load_sources (const XMLNode& node)
1609 XMLNodeConstIterator niter;
1610 boost::shared_ptr<Source> source;
1612 nlist = node.children();
1616 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1619 if ((source = XMLSourceFactory (**niter)) == 0) {
1620 error << _("Session: cannot create Source from XML description.") << endmsg;
1624 catch (non_existent_source& err) {
1625 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1626 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1633 boost::shared_ptr<Source>
1634 Session::XMLSourceFactory (const XMLNode& node)
1636 if (node.name() != "Source") {
1637 return boost::shared_ptr<Source>();
1641 return SourceFactory::create (*this, node);
1644 catch (failed_constructor& err) {
1645 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1646 return boost::shared_ptr<Source>();
1651 Session::save_template (string template_name)
1655 if (_state_of_the_state & CannotSave) {
1659 sys::path user_template_dir(user_template_directory());
1663 sys::create_directories (user_template_dir);
1665 catch(sys::filesystem_error& ex)
1667 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1668 user_template_dir.to_string(), ex.what()) << endmsg;
1672 tree.set_root (&get_template());
1674 sys::path template_file_path(user_template_dir);
1675 template_file_path /= template_name + template_suffix;
1677 if (sys::exists (template_file_path))
1679 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1680 template_file_path.to_string()) << endmsg;
1684 if (!tree.write (template_file_path.to_string())) {
1685 error << _("mix template not saved") << endmsg;
1693 Session::refresh_disk_space ()
1696 struct statfs statfsbuf;
1697 vector<space_and_path>::iterator i;
1698 Glib::Mutex::Lock lm (space_lock);
1701 /* get freespace on every FS that is part of the session path */
1703 _total_free_4k_blocks = 0;
1705 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1706 statfs ((*i).path.c_str(), &statfsbuf);
1708 scale = statfsbuf.f_bsize/4096.0;
1710 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1711 _total_free_4k_blocks += (*i).blocks;
1717 Session::get_best_session_directory_for_new_source ()
1719 vector<space_and_path>::iterator i;
1720 string result = _session_dir->root_path().to_string();
1722 /* handle common case without system calls */
1724 if (session_dirs.size() == 1) {
1728 /* OK, here's the algorithm we're following here:
1730 We want to select which directory to use for
1731 the next file source to be created. Ideally,
1732 we'd like to use a round-robin process so as to
1733 get maximum performance benefits from splitting
1734 the files across multiple disks.
1736 However, in situations without much diskspace, an
1737 RR approach may end up filling up a filesystem
1738 with new files while others still have space.
1739 Its therefore important to pay some attention to
1740 the freespace in the filesystem holding each
1741 directory as well. However, if we did that by
1742 itself, we'd keep creating new files in the file
1743 system with the most space until it was as full
1744 as all others, thus negating any performance
1745 benefits of this RAID-1 like approach.
1747 So, we use a user-configurable space threshold. If
1748 there are at least 2 filesystems with more than this
1749 much space available, we use RR selection between them.
1750 If not, then we pick the filesystem with the most space.
1752 This gets a good balance between the two
1756 refresh_disk_space ();
1758 int free_enough = 0;
1760 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1761 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1766 if (free_enough >= 2) {
1767 /* use RR selection process, ensuring that the one
1771 i = last_rr_session_dir;
1774 if (++i == session_dirs.end()) {
1775 i = session_dirs.begin();
1778 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1779 if (create_session_directory ((*i).path)) {
1781 last_rr_session_dir = i;
1786 } while (i != last_rr_session_dir);
1790 /* pick FS with the most freespace (and that
1791 seems to actually work ...)
1794 vector<space_and_path> sorted;
1795 space_and_path_ascending_cmp cmp;
1797 sorted = session_dirs;
1798 sort (sorted.begin(), sorted.end(), cmp);
1800 for (i = sorted.begin(); i != sorted.end(); ++i) {
1801 if (create_session_directory ((*i).path)) {
1803 last_rr_session_dir = i;
1813 Session::load_playlists (const XMLNode& node)
1816 XMLNodeConstIterator niter;
1817 boost::shared_ptr<Playlist> playlist;
1819 nlist = node.children();
1823 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1825 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1826 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1834 Session::load_unused_playlists (const XMLNode& node)
1837 XMLNodeConstIterator niter;
1838 boost::shared_ptr<Playlist> playlist;
1840 nlist = node.children();
1844 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1846 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1847 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1851 // now manually untrack it
1853 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1859 boost::shared_ptr<Playlist>
1860 Session::XMLPlaylistFactory (const XMLNode& node)
1863 return PlaylistFactory::create (*this, node);
1866 catch (failed_constructor& err) {
1867 return boost::shared_ptr<Playlist>();
1872 Session::load_named_selections (const XMLNode& node)
1875 XMLNodeConstIterator niter;
1878 nlist = node.children();
1882 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1884 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1885 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1893 Session::XMLNamedSelectionFactory (const XMLNode& node)
1896 return new NamedSelection (*this, node);
1899 catch (failed_constructor& err) {
1905 Session::automation_dir () const
1908 res += "automation/";
1913 Session::load_bundles (XMLNode const & node)
1915 XMLNodeList nlist = node.children();
1916 XMLNodeConstIterator niter;
1920 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1921 if ((*niter)->name() == "InputBundle") {
1922 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
1923 } else if ((*niter)->name() == "OutputBundle") {
1924 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
1926 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
1935 Session::load_edit_groups (const XMLNode& node)
1937 return load_route_groups (node, true);
1941 Session::load_mix_groups (const XMLNode& node)
1943 return load_route_groups (node, false);
1947 Session::load_route_groups (const XMLNode& node, bool edit)
1949 XMLNodeList nlist = node.children();
1950 XMLNodeConstIterator niter;
1955 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1956 if ((*niter)->name() == "RouteGroup") {
1958 rg = add_edit_group ("");
1959 rg->set_state (**niter);
1961 rg = add_mix_group ("");
1962 rg->set_state (**niter);
1971 Session::auto_save()
1973 save_state (_current_snapshot_name);
1977 Session::add_edit_group (string name)
1979 RouteGroup* rg = new RouteGroup (*this, name);
1980 edit_groups.push_back (rg);
1981 edit_group_added (rg); /* EMIT SIGNAL */
1987 Session::add_mix_group (string name)
1989 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
1990 mix_groups.push_back (rg);
1991 mix_group_added (rg); /* EMIT SIGNAL */
1997 Session::remove_edit_group (RouteGroup& rg)
1999 list<RouteGroup*>::iterator i;
2001 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2002 (*i)->apply (&Route::drop_edit_group, this);
2003 edit_groups.erase (i);
2004 edit_group_removed (); /* EMIT SIGNAL */
2011 Session::remove_mix_group (RouteGroup& rg)
2013 list<RouteGroup*>::iterator i;
2015 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2016 (*i)->apply (&Route::drop_mix_group, this);
2017 mix_groups.erase (i);
2018 mix_group_removed (); /* EMIT SIGNAL */
2025 Session::mix_group_by_name (string name)
2027 list<RouteGroup *>::iterator i;
2029 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2030 if ((*i)->name() == name) {
2038 Session::edit_group_by_name (string name)
2040 list<RouteGroup *>::iterator i;
2042 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2043 if ((*i)->name() == name) {
2051 Session::begin_reversible_command (const string& name)
2053 current_trans = new UndoTransaction;
2054 current_trans->set_name (name);
2058 Session::commit_reversible_command (Command *cmd)
2063 current_trans->add_command (cmd);
2066 gettimeofday (&now, 0);
2067 current_trans->set_timestamp (now);
2069 _history.add (current_trans);
2072 Session::GlobalRouteBooleanState
2073 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2075 GlobalRouteBooleanState s;
2076 boost::shared_ptr<RouteList> r = routes.reader ();
2078 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2079 if (!(*i)->is_hidden()) {
2080 RouteBooleanState v;
2083 Route* r = (*i).get();
2084 v.second = (r->*method)();
2093 Session::GlobalRouteMeterState
2094 Session::get_global_route_metering ()
2096 GlobalRouteMeterState 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()) {
2104 v.second = (*i)->meter_point();
2114 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2116 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2118 boost::shared_ptr<Route> r = (i->first.lock());
2121 r->set_meter_point (i->second, arg);
2127 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2129 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2131 boost::shared_ptr<Route> r = (i->first.lock());
2134 Route* rp = r.get();
2135 (rp->*method) (i->second, arg);
2141 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2143 set_global_route_boolean (s, &Route::set_mute, src);
2147 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2149 set_global_route_boolean (s, &Route::set_solo, src);
2153 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2155 set_global_route_boolean (s, &Route::set_record_enable, src);
2160 Session::global_mute_memento (void* src)
2162 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2166 Session::global_metering_memento (void* src)
2168 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2172 Session::global_solo_memento (void* src)
2174 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2178 Session::global_record_enable_memento (void* src)
2180 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2185 accept_all_non_peak_files (const string& path, void *arg)
2187 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2191 accept_all_state_files (const string& path, void *arg)
2193 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2197 Session::find_all_sources (string path, set<string>& result)
2202 if (!tree.read (path)) {
2206 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2211 XMLNodeConstIterator niter;
2213 nlist = node->children();
2217 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2221 if ((prop = (*niter)->property (X_("name"))) == 0) {
2225 if (prop->value()[0] == '/') {
2226 /* external file, ignore */
2230 sys::path source_path = _session_dir->sound_path ();
2232 source_path /= prop->value ();
2234 result.insert (source_path.to_string ());
2241 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2243 PathScanner scanner;
2244 vector<string*>* state_files;
2246 string this_snapshot_path;
2252 if (ripped[ripped.length()-1] == '/') {
2253 ripped = ripped.substr (0, ripped.length() - 1);
2256 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2258 if (state_files == 0) {
2263 this_snapshot_path = _path;
2264 this_snapshot_path += _current_snapshot_name;
2265 this_snapshot_path += statefile_suffix;
2267 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2269 if (exclude_this_snapshot && **i == this_snapshot_path) {
2273 if (find_all_sources (**i, result) < 0) {
2281 struct RegionCounter {
2282 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2283 AudioSourceList::iterator iter;
2284 boost::shared_ptr<Region> region;
2287 RegionCounter() : count (0) {}
2291 Session::cleanup_sources (Session::cleanup_report& rep)
2293 // FIXME: needs adaptation to midi
2295 vector<boost::shared_ptr<Source> > dead_sources;
2296 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2297 PathScanner scanner;
2299 vector<space_and_path>::iterator i;
2300 vector<space_and_path>::iterator nexti;
2301 vector<string*>* soundfiles;
2302 vector<string> unused;
2303 set<string> all_sources;
2308 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2310 /* step 1: consider deleting all unused playlists */
2312 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2315 status = AskAboutPlaylistDeletion (*x);
2324 playlists_tbd.push_back (*x);
2328 /* leave it alone */
2333 /* now delete any that were marked for deletion */
2335 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2336 (*x)->drop_references ();
2339 playlists_tbd.clear ();
2341 /* step 2: find all un-used sources */
2346 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2348 SourceMap::iterator tmp;
2353 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2357 if (!i->second->used() && i->second->length() > 0) {
2358 dead_sources.push_back (i->second);
2359 i->second->GoingAway();
2365 /* build a list of all the possible sound directories for the session */
2367 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2372 SessionDirectory sdir ((*i).path);
2373 sound_path += sdir.sound_path().to_string();
2375 if (nexti != session_dirs.end()) {
2382 /* now do the same thing for the files that ended up in the sounds dir(s)
2383 but are not referenced as sources in any snapshot.
2386 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2388 if (soundfiles == 0) {
2392 /* find all sources, but don't use this snapshot because the
2393 state file on disk still references sources we may have already
2397 find_all_sources_across_snapshots (all_sources, true);
2399 /* add our current source list
2402 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2403 boost::shared_ptr<AudioFileSource> fs;
2405 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2406 all_sources.insert (fs->path());
2410 char tmppath1[PATH_MAX+1];
2411 char tmppath2[PATH_MAX+1];
2413 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2418 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2420 realpath(spath.c_str(), tmppath1);
2421 realpath((*i).c_str(), tmppath2);
2423 if (strcmp(tmppath1, tmppath2) == 0) {
2430 unused.push_back (spath);
2434 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2436 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2437 struct stat statbuf;
2439 rep.paths.push_back (*x);
2440 if (stat ((*x).c_str(), &statbuf) == 0) {
2441 rep.space += statbuf.st_size;
2446 /* don't move the file across filesystems, just
2447 stick it in the `dead_sound_dir_name' directory
2448 on whichever filesystem it was already on.
2451 if ((*x).find ("/sounds/") != string::npos) {
2453 /* old school, go up 1 level */
2455 newpath = Glib::path_get_dirname (*x); // "sounds"
2456 newpath = Glib::path_get_dirname (newpath); // "session-name"
2460 /* new school, go up 4 levels */
2462 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2463 newpath = Glib::path_get_dirname (newpath); // "session-name"
2464 newpath = Glib::path_get_dirname (newpath); // "interchange"
2465 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2469 newpath += dead_sound_dir_name;
2471 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2472 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2477 newpath += Glib::path_get_basename ((*x));
2479 if (access (newpath.c_str(), F_OK) == 0) {
2481 /* the new path already exists, try versioning */
2483 char buf[PATH_MAX+1];
2487 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2490 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2491 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2495 if (version == 999) {
2496 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2500 newpath = newpath_v;
2505 /* it doesn't exist, or we can't read it or something */
2509 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2510 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2511 (*x), newpath, strerror (errno))
2516 /* see if there an easy to find peakfile for this file, and remove it.
2519 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2520 peakpath += peakfile_suffix;
2522 if (access (peakpath.c_str(), W_OK) == 0) {
2523 if (::unlink (peakpath.c_str()) != 0) {
2524 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2525 peakpath, _path, strerror (errno))
2527 /* try to back out */
2528 rename (newpath.c_str(), _path.c_str());
2536 /* dump the history list */
2540 /* save state so we don't end up a session file
2541 referring to non-existent sources.
2547 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2552 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2554 // FIXME: needs adaptation for MIDI
2556 vector<space_and_path>::iterator i;
2557 string dead_sound_dir;
2558 struct dirent* dentry;
2559 struct stat statbuf;
2565 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2567 dead_sound_dir = (*i).path;
2568 dead_sound_dir += dead_sound_dir_name;
2570 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2574 while ((dentry = readdir (dead)) != 0) {
2576 /* avoid '.' and '..' */
2578 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2579 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2585 fullpath = dead_sound_dir;
2587 fullpath += dentry->d_name;
2589 if (stat (fullpath.c_str(), &statbuf)) {
2593 if (!S_ISREG (statbuf.st_mode)) {
2597 if (unlink (fullpath.c_str())) {
2598 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2599 fullpath, strerror (errno))
2603 rep.paths.push_back (dentry->d_name);
2604 rep.space += statbuf.st_size;
2615 Session::set_dirty ()
2617 bool was_dirty = dirty();
2619 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2622 DirtyChanged(); /* EMIT SIGNAL */
2628 Session::set_clean ()
2630 bool was_dirty = dirty();
2632 _state_of_the_state = Clean;
2635 DirtyChanged(); /* EMIT SIGNAL */
2640 Session::set_deletion_in_progress ()
2642 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2646 Session::add_controllable (boost::shared_ptr<Controllable> c)
2648 /* this adds a controllable to the list managed by the Session.
2649 this is a subset of those managed by the Controllable class
2650 itself, and represents the only ones whose state will be saved
2651 as part of the session.
2654 Glib::Mutex::Lock lm (controllables_lock);
2655 controllables.insert (c);
2658 struct null_deleter { void operator()(void const *) const {} };
2661 Session::remove_controllable (Controllable* c)
2663 if (_state_of_the_state | Deletion) {
2667 Glib::Mutex::Lock lm (controllables_lock);
2669 Controllables::iterator x = controllables.find(
2670 boost::shared_ptr<Controllable>(c, null_deleter()));
2672 if (x != controllables.end()) {
2673 controllables.erase (x);
2677 boost::shared_ptr<Controllable>
2678 Session::controllable_by_id (const PBD::ID& id)
2680 Glib::Mutex::Lock lm (controllables_lock);
2682 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2683 if ((*i)->id() == id) {
2688 return boost::shared_ptr<Controllable>();
2692 Session::add_instant_xml (XMLNode& node)
2694 Stateful::add_instant_xml (node, _path);
2695 Config->add_instant_xml (node);
2699 Session::instant_xml (const string& node_name)
2701 return Stateful::instant_xml (node_name, _path);
2705 Session::save_history (string snapshot_name)
2709 if (snapshot_name.empty()) {
2710 snapshot_name = _current_snapshot_name;
2713 const string history_filename = snapshot_name + history_suffix;
2714 const string backup_filename = history_filename + backup_suffix;
2715 const sys::path xml_path = _session_dir->root_path() / history_filename;
2716 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2718 if (sys::exists (xml_path)) {
2721 sys::rename (xml_path, backup_path);
2723 catch (const sys::filesystem_error& err)
2725 error << _("could not backup old history file, current history not saved") << endmsg;
2731 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2735 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2737 if (!tree.write (xml_path.to_string()))
2739 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2743 sys::remove (xml_path);
2744 sys::rename (backup_path, xml_path);
2746 catch (const sys::filesystem_error& err)
2748 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2749 backup_path.to_string(), err.what()) << endmsg;
2759 Session::restore_history (string snapshot_name)
2763 if (snapshot_name.empty()) {
2764 snapshot_name = _current_snapshot_name;
2767 const string xml_filename = snapshot_name + history_suffix;
2768 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2770 info << string_compose(_("Loading history from '%1'."), xml_path.to_string()) << endmsg;
2772 if (!sys::exists (xml_path)) {
2773 info << string_compose (_("%1: no history file \"%2\" for this session."),
2774 _name, xml_path.to_string()) << endmsg;
2778 if (!tree.read (xml_path.to_string())) {
2779 error << string_compose (_("Could not understand session history file \"%1\""),
2780 xml_path.to_string()) << endmsg;
2787 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2790 UndoTransaction* ut = new UndoTransaction ();
2793 ut->set_name(t->property("name")->value());
2794 stringstream ss(t->property("tv_sec")->value());
2796 ss.str(t->property("tv_usec")->value());
2798 ut->set_timestamp(tv);
2800 for (XMLNodeConstIterator child_it = t->children().begin();
2801 child_it != t->children().end();
2804 XMLNode *n = *child_it;
2807 if (n->name() == "MementoCommand" ||
2808 n->name() == "MementoUndoCommand" ||
2809 n->name() == "MementoRedoCommand") {
2811 if ((c = memento_command_factory(n))) {
2815 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2817 if ((c = global_state_command_factory (*n))) {
2818 ut->add_command (c);
2823 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2834 Session::config_changed (const char* parameter_name)
2836 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2838 if (PARAM_IS ("seamless-loop")) {
2840 } else if (PARAM_IS ("rf-speed")) {
2842 } else if (PARAM_IS ("auto-loop")) {
2844 } else if (PARAM_IS ("auto-input")) {
2846 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2847 /* auto-input only makes a difference if we're rolling */
2849 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2851 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2852 if ((*i)->record_enabled ()) {
2853 (*i)->monitor_input (!Config->get_auto_input());
2858 } else if (PARAM_IS ("punch-in")) {
2862 if ((location = _locations.auto_punch_location()) != 0) {
2864 if (Config->get_punch_in ()) {
2865 replace_event (Event::PunchIn, location->start());
2867 remove_event (location->start(), Event::PunchIn);
2871 } else if (PARAM_IS ("punch-out")) {
2875 if ((location = _locations.auto_punch_location()) != 0) {
2877 if (Config->get_punch_out()) {
2878 replace_event (Event::PunchOut, location->end());
2880 clear_events (Event::PunchOut);
2884 } else if (PARAM_IS ("edit-mode")) {
2886 Glib::Mutex::Lock lm (playlist_lock);
2888 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2889 (*i)->set_edit_mode (Config->get_edit_mode ());
2892 } else if (PARAM_IS ("use-video-sync")) {
2894 waiting_for_sync_offset = Config->get_use_video_sync();
2896 } else if (PARAM_IS ("mmc-control")) {
2898 //poke_midi_thread ();
2900 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
2903 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
2906 } else if (PARAM_IS ("mmc-send-id")) {
2909 mmc->set_send_device_id (Config->get_mmc_send_device_id());
2912 } else if (PARAM_IS ("midi-control")) {
2914 //poke_midi_thread ();
2916 } else if (PARAM_IS ("raid-path")) {
2918 setup_raid_path (Config->get_raid_path());
2920 } else if (PARAM_IS ("smpte-format")) {
2924 } else if (PARAM_IS ("video-pullup")) {
2928 } else if (PARAM_IS ("seamless-loop")) {
2930 if (play_loop && transport_rolling()) {
2931 // to reset diskstreams etc
2932 request_play_loop (true);
2935 } else if (PARAM_IS ("rf-speed")) {
2937 cumulative_rf_motion = 0;
2940 } else if (PARAM_IS ("click-sound")) {
2942 setup_click_sounds (1);
2944 } else if (PARAM_IS ("click-emphasis-sound")) {
2946 setup_click_sounds (-1);
2948 } else if (PARAM_IS ("clicking")) {
2950 if (Config->get_clicking()) {
2951 if (_click_io && click_data) { // don't require emphasis data
2958 } else if (PARAM_IS ("send-mtc")) {
2960 /* only set the internal flag if we have
2964 if (_mtc_port != 0) {
2965 session_send_mtc = Config->get_send_mtc();
2966 if (session_send_mtc) {
2967 /* mark us ready to send */
2968 next_quarter_frame_to_send = 0;
2971 session_send_mtc = false;
2974 } else if (PARAM_IS ("send-mmc")) {
2976 /* only set the internal flag if we have
2980 if (_mmc_port != 0) {
2981 session_send_mmc = Config->get_send_mmc();
2984 session_send_mmc = false;
2987 } else if (PARAM_IS ("midi-feedback")) {
2989 /* only set the internal flag if we have
2993 if (_mtc_port != 0) {
2994 session_midi_feedback = Config->get_midi_feedback();
2997 } else if (PARAM_IS ("jack-time-master")) {
2999 engine().reset_timebase ();
3001 } else if (PARAM_IS ("native-file-header-format")) {
3003 if (!first_file_header_format_reset) {
3004 reset_native_file_format ();
3007 first_file_header_format_reset = false;
3009 } else if (PARAM_IS ("native-file-data-format")) {
3011 if (!first_file_data_format_reset) {
3012 reset_native_file_format ();
3015 first_file_data_format_reset = false;
3017 } else if (PARAM_IS ("slave-source")) {
3018 set_slave_source (Config->get_slave_source());
3019 } else if (PARAM_IS ("remote-model")) {
3020 set_remote_control_ids ();
3021 } else if (PARAM_IS ("denormal-model")) {
3023 } else if (PARAM_IS ("history-depth")) {
3024 set_history_depth (Config->get_history_depth());
3025 } else if (PARAM_IS ("sync-all-route-ordering")) {
3036 Session::set_history_depth (uint32_t d)
3038 _history.set_depth (d);