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 ("Connections");
958 Glib::Mutex::Lock lm (bundle_lock);
959 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
960 if (!(*i)->dynamic()) {
961 child->add_child_nocopy ((*i)->get_state());
966 child = node->add_child ("Routes");
968 boost::shared_ptr<RouteList> r = routes.reader ();
970 RoutePublicOrderSorter cmp;
971 RouteList public_order (*r);
972 public_order.sort (cmp);
974 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
975 if (!(*i)->is_hidden()) {
977 child->add_child_nocopy ((*i)->get_state());
979 child->add_child_nocopy ((*i)->get_template());
986 child = node->add_child ("EditGroups");
987 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
988 child->add_child_nocopy ((*i)->get_state());
991 child = node->add_child ("MixGroups");
992 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
993 child->add_child_nocopy ((*i)->get_state());
996 child = node->add_child ("Playlists");
997 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
998 if (!(*i)->hidden()) {
999 if (!(*i)->empty()) {
1001 child->add_child_nocopy ((*i)->get_state());
1003 child->add_child_nocopy ((*i)->get_template());
1009 child = node->add_child ("UnusedPlaylists");
1010 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1011 if (!(*i)->hidden()) {
1012 if (!(*i)->empty()) {
1014 child->add_child_nocopy ((*i)->get_state());
1016 child->add_child_nocopy ((*i)->get_template());
1024 child = node->add_child ("Click");
1025 child->add_child_nocopy (_click_io->state (full_state));
1029 child = node->add_child ("NamedSelections");
1030 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1032 child->add_child_nocopy ((*i)->get_state());
1037 node->add_child_nocopy (_tempo_map->get_state());
1039 node->add_child_nocopy (get_control_protocol_state());
1042 node->add_child_copy (*_extra_xml);
1049 Session::get_control_protocol_state ()
1051 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1052 return cpm.get_state();
1056 Session::set_state (const XMLNode& node)
1060 const XMLProperty* prop;
1063 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1065 if (node.name() != X_("Session")){
1066 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1070 if ((prop = node.property ("name")) != 0) {
1071 _name = prop->value ();
1074 setup_raid_path(_session_dir->root_path().to_string());
1076 if ((prop = node.property (X_("id-counter"))) != 0) {
1078 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1079 ID::init_counter (x);
1081 /* old sessions used a timebased counter, so fake
1082 the startup ID counter based on a standard
1087 ID::init_counter (now);
1091 IO::disable_ports ();
1092 IO::disable_connecting ();
1094 /* Object loading order:
1112 if (use_config_midi_ports ()) {
1115 if ((child = find_named_node (node, "extra")) != 0) {
1116 _extra_xml = new XMLNode (*child);
1119 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1120 load_options (*child);
1121 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1122 load_options (*child);
1124 error << _("Session: XML state has no options section") << endmsg;
1127 if ((child = find_named_node (node, "Locations")) == 0) {
1128 error << _("Session: XML state has no locations section") << endmsg;
1130 } else if (_locations.set_state (*child)) {
1136 if ((location = _locations.auto_loop_location()) != 0) {
1137 set_auto_loop_location (location);
1140 if ((location = _locations.auto_punch_location()) != 0) {
1141 set_auto_punch_location (location);
1144 if ((location = _locations.end_location()) == 0) {
1145 _locations.add (end_location);
1147 delete end_location;
1148 end_location = location;
1151 if ((location = _locations.start_location()) == 0) {
1152 _locations.add (start_location);
1154 delete start_location;
1155 start_location = location;
1158 AudioFileSource::set_header_position_offset (start_location->start());
1160 if ((child = find_named_node (node, "Sources")) == 0) {
1161 error << _("Session: XML state has no sources section") << endmsg;
1163 } else if (load_sources (*child)) {
1167 if ((child = find_named_node (node, "Regions")) == 0) {
1168 error << _("Session: XML state has no Regions section") << endmsg;
1170 } else if (load_regions (*child)) {
1174 if ((child = find_named_node (node, "Playlists")) == 0) {
1175 error << _("Session: XML state has no playlists section") << endmsg;
1177 } else if (load_playlists (*child)) {
1181 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1183 } else if (load_unused_playlists (*child)) {
1187 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1188 if (load_named_selections (*child)) {
1193 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1194 error << _("Session: XML state has no diskstreams section") << endmsg;
1196 } else if (load_diskstreams (*child)) {
1200 if ((child = find_named_node (node, "Connections")) == 0) {
1201 error << _("Session: XML state has no connections section") << endmsg;
1203 } else if (load_bundles (*child)) {
1207 if ((child = find_named_node (node, "EditGroups")) == 0) {
1208 error << _("Session: XML state has no edit groups section") << endmsg;
1210 } else if (load_edit_groups (*child)) {
1214 if ((child = find_named_node (node, "MixGroups")) == 0) {
1215 error << _("Session: XML state has no mix groups section") << endmsg;
1217 } else if (load_mix_groups (*child)) {
1221 if ((child = find_named_node (node, "TempoMap")) == 0) {
1222 error << _("Session: XML state has no Tempo Map section") << endmsg;
1224 } else if (_tempo_map->set_state (*child)) {
1228 if ((child = find_named_node (node, "Routes")) == 0) {
1229 error << _("Session: XML state has no routes section") << endmsg;
1231 } else if (load_routes (*child)) {
1235 if ((child = find_named_node (node, "Click")) == 0) {
1236 warning << _("Session: XML state has no click section") << endmsg;
1237 } else if (_click_io) {
1238 _click_io->set_state (*child);
1241 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1242 ControlProtocolManager::instance().set_protocol_states (*child);
1245 /* here beginneth the second phase ... */
1247 StateReady (); /* EMIT SIGNAL */
1249 _state_of_the_state = Clean;
1251 if (state_was_pending) {
1252 save_state (_current_snapshot_name);
1253 remove_pending_capture_state ();
1254 state_was_pending = false;
1264 Session::load_routes (const XMLNode& node)
1267 XMLNodeConstIterator niter;
1268 RouteList new_routes;
1270 nlist = node.children();
1274 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1276 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1279 error << _("Session: cannot create Route from XML description.") << endmsg;
1283 new_routes.push_back (route);
1286 add_routes (new_routes);
1291 boost::shared_ptr<Route>
1292 Session::XMLRouteFactory (const XMLNode& node)
1294 if (node.name() != "Route") {
1295 return boost::shared_ptr<Route> ((Route*) 0);
1298 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1300 DataType type = DataType::AUDIO;
1301 const XMLProperty* prop = node.property("default-type");
1303 type = DataType(prop->value());
1305 assert(type != DataType::NIL);
1307 if (has_diskstream) {
1308 if (type == DataType::AUDIO) {
1309 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1312 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1316 boost::shared_ptr<Route> ret (new Route (*this, node));
1322 Session::load_regions (const XMLNode& node)
1325 XMLNodeConstIterator niter;
1326 boost::shared_ptr<Region> region;
1328 nlist = node.children();
1332 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1333 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1334 error << _("Session: cannot create Region from XML description.") << endmsg;
1341 boost::shared_ptr<Region>
1342 Session::XMLRegionFactory (const XMLNode& node, bool full)
1344 const XMLProperty* type = node.property("type");
1348 if ( !type || type->value() == "audio" ) {
1350 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1352 } else if (type->value() == "midi") {
1354 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1358 } catch (failed_constructor& err) {
1359 return boost::shared_ptr<Region> ();
1362 return boost::shared_ptr<Region> ();
1365 boost::shared_ptr<AudioRegion>
1366 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1368 const XMLProperty* prop;
1369 boost::shared_ptr<Source> source;
1370 boost::shared_ptr<AudioSource> as;
1372 uint32_t nchans = 1;
1375 if (node.name() != X_("Region")) {
1376 return boost::shared_ptr<AudioRegion>();
1379 if ((prop = node.property (X_("channels"))) != 0) {
1380 nchans = atoi (prop->value().c_str());
1383 if ((prop = node.property ("name")) == 0) {
1384 cerr << "no name for this region\n";
1388 if ((prop = node.property (X_("source-0"))) == 0) {
1389 if ((prop = node.property ("source")) == 0) {
1390 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1391 return boost::shared_ptr<AudioRegion>();
1395 PBD::ID s_id (prop->value());
1397 if ((source = source_by_id (s_id)) == 0) {
1398 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1399 return boost::shared_ptr<AudioRegion>();
1402 as = boost::dynamic_pointer_cast<AudioSource>(source);
1404 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1405 return boost::shared_ptr<AudioRegion>();
1408 sources.push_back (as);
1410 /* pickup other channels */
1412 for (uint32_t n=1; n < nchans; ++n) {
1413 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1414 if ((prop = node.property (buf)) != 0) {
1416 PBD::ID id2 (prop->value());
1418 if ((source = source_by_id (id2)) == 0) {
1419 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1420 return boost::shared_ptr<AudioRegion>();
1423 as = boost::dynamic_pointer_cast<AudioSource>(source);
1425 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1426 return boost::shared_ptr<AudioRegion>();
1428 sources.push_back (as);
1433 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1435 /* a final detail: this is the one and only place that we know how long missing files are */
1437 if (region->whole_file()) {
1438 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1439 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1441 sfp->set_length (region->length());
1450 catch (failed_constructor& err) {
1451 return boost::shared_ptr<AudioRegion>();
1455 boost::shared_ptr<MidiRegion>
1456 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1458 const XMLProperty* prop;
1459 boost::shared_ptr<Source> source;
1460 boost::shared_ptr<MidiSource> ms;
1462 uint32_t nchans = 1;
1464 if (node.name() != X_("Region")) {
1465 return boost::shared_ptr<MidiRegion>();
1468 if ((prop = node.property (X_("channels"))) != 0) {
1469 nchans = atoi (prop->value().c_str());
1472 if ((prop = node.property ("name")) == 0) {
1473 cerr << "no name for this region\n";
1477 // Multiple midi channels? that's just crazy talk
1478 assert(nchans == 1);
1480 if ((prop = node.property (X_("source-0"))) == 0) {
1481 if ((prop = node.property ("source")) == 0) {
1482 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1483 return boost::shared_ptr<MidiRegion>();
1487 PBD::ID s_id (prop->value());
1489 if ((source = source_by_id (s_id)) == 0) {
1490 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1491 return boost::shared_ptr<MidiRegion>();
1494 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1496 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1497 return boost::shared_ptr<MidiRegion>();
1500 sources.push_back (ms);
1503 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1504 /* a final detail: this is the one and only place that we know how long missing files are */
1506 if (region->whole_file()) {
1507 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1508 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1510 sfp->set_length (region->length());
1518 catch (failed_constructor& err) {
1519 return boost::shared_ptr<MidiRegion>();
1524 Session::get_sources_as_xml ()
1527 XMLNode* node = new XMLNode (X_("Sources"));
1528 Glib::Mutex::Lock lm (source_lock);
1530 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1531 node->add_child_nocopy (i->second->get_state());
1538 Session::path_from_region_name (DataType type, string name, string identifier)
1540 char buf[PATH_MAX+1];
1542 SessionDirectory sdir(get_best_session_directory_for_new_source());
1543 string sound_dir = ((type == DataType::AUDIO)
1544 ? sdir.sound_path().to_string()
1545 : sdir.midi_path().to_string());
1547 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1549 for (n = 0; n < 999999; ++n) {
1550 if (identifier.length()) {
1551 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1552 identifier.c_str(), n, ext.c_str());
1554 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1558 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1563 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1572 Session::load_sources (const XMLNode& node)
1575 XMLNodeConstIterator niter;
1576 boost::shared_ptr<Source> source;
1578 nlist = node.children();
1582 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1585 if ((source = XMLSourceFactory (**niter)) == 0) {
1586 error << _("Session: cannot create Source from XML description.") << endmsg;
1590 catch (non_existent_source& err) {
1591 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1592 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1599 boost::shared_ptr<Source>
1600 Session::XMLSourceFactory (const XMLNode& node)
1602 if (node.name() != "Source") {
1603 return boost::shared_ptr<Source>();
1607 return SourceFactory::create (*this, node);
1610 catch (failed_constructor& err) {
1611 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1612 return boost::shared_ptr<Source>();
1617 Session::save_template (string template_name)
1621 if (_state_of_the_state & CannotSave) {
1625 sys::path user_template_dir(user_template_directory());
1629 sys::create_directories (user_template_dir);
1631 catch(sys::filesystem_error& ex)
1633 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1634 user_template_dir.to_string(), ex.what()) << endmsg;
1638 tree.set_root (&get_template());
1640 sys::path template_file_path(user_template_dir);
1641 template_file_path /= template_name + template_suffix;
1643 if (sys::exists (template_file_path))
1645 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1646 template_file_path.to_string()) << endmsg;
1650 if (!tree.write (template_file_path.to_string())) {
1651 error << _("mix template not saved") << endmsg;
1659 Session::refresh_disk_space ()
1662 struct statfs statfsbuf;
1663 vector<space_and_path>::iterator i;
1664 Glib::Mutex::Lock lm (space_lock);
1667 /* get freespace on every FS that is part of the session path */
1669 _total_free_4k_blocks = 0;
1671 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1672 statfs ((*i).path.c_str(), &statfsbuf);
1674 scale = statfsbuf.f_bsize/4096.0;
1676 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1677 _total_free_4k_blocks += (*i).blocks;
1683 Session::get_best_session_directory_for_new_source ()
1685 vector<space_and_path>::iterator i;
1686 string result = _session_dir->root_path().to_string();
1688 /* handle common case without system calls */
1690 if (session_dirs.size() == 1) {
1694 /* OK, here's the algorithm we're following here:
1696 We want to select which directory to use for
1697 the next file source to be created. Ideally,
1698 we'd like to use a round-robin process so as to
1699 get maximum performance benefits from splitting
1700 the files across multiple disks.
1702 However, in situations without much diskspace, an
1703 RR approach may end up filling up a filesystem
1704 with new files while others still have space.
1705 Its therefore important to pay some attention to
1706 the freespace in the filesystem holding each
1707 directory as well. However, if we did that by
1708 itself, we'd keep creating new files in the file
1709 system with the most space until it was as full
1710 as all others, thus negating any performance
1711 benefits of this RAID-1 like approach.
1713 So, we use a user-configurable space threshold. If
1714 there are at least 2 filesystems with more than this
1715 much space available, we use RR selection between them.
1716 If not, then we pick the filesystem with the most space.
1718 This gets a good balance between the two
1722 refresh_disk_space ();
1724 int free_enough = 0;
1726 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1727 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1732 if (free_enough >= 2) {
1733 /* use RR selection process, ensuring that the one
1737 i = last_rr_session_dir;
1740 if (++i == session_dirs.end()) {
1741 i = session_dirs.begin();
1744 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1745 if (create_session_directory ((*i).path)) {
1747 last_rr_session_dir = i;
1752 } while (i != last_rr_session_dir);
1756 /* pick FS with the most freespace (and that
1757 seems to actually work ...)
1760 vector<space_and_path> sorted;
1761 space_and_path_ascending_cmp cmp;
1763 sorted = session_dirs;
1764 sort (sorted.begin(), sorted.end(), cmp);
1766 for (i = sorted.begin(); i != sorted.end(); ++i) {
1767 if (create_session_directory ((*i).path)) {
1769 last_rr_session_dir = i;
1779 Session::load_playlists (const XMLNode& node)
1782 XMLNodeConstIterator niter;
1783 boost::shared_ptr<Playlist> playlist;
1785 nlist = node.children();
1789 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1791 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1792 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1800 Session::load_unused_playlists (const XMLNode& node)
1803 XMLNodeConstIterator niter;
1804 boost::shared_ptr<Playlist> playlist;
1806 nlist = node.children();
1810 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1812 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1813 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1817 // now manually untrack it
1819 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1825 boost::shared_ptr<Playlist>
1826 Session::XMLPlaylistFactory (const XMLNode& node)
1829 return PlaylistFactory::create (*this, node);
1832 catch (failed_constructor& err) {
1833 return boost::shared_ptr<Playlist>();
1838 Session::load_named_selections (const XMLNode& node)
1841 XMLNodeConstIterator niter;
1844 nlist = node.children();
1848 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1850 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1851 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1859 Session::XMLNamedSelectionFactory (const XMLNode& node)
1862 return new NamedSelection (*this, node);
1865 catch (failed_constructor& err) {
1871 Session::automation_dir () const
1874 res += "automation/";
1879 Session::load_bundles (const XMLNode& node)
1881 XMLNodeList nlist = node.children();
1882 XMLNodeConstIterator niter;
1886 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1887 if ((*niter)->name() == "InputConnection") {
1888 add_bundle (boost::shared_ptr<Bundle> (new InputBundle (**niter)));
1889 } else if ((*niter)->name() == "OutputConnection") {
1890 add_bundle (boost::shared_ptr<Bundle> (new OutputBundle (**niter)));
1892 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1901 Session::load_edit_groups (const XMLNode& node)
1903 return load_route_groups (node, true);
1907 Session::load_mix_groups (const XMLNode& node)
1909 return load_route_groups (node, false);
1913 Session::load_route_groups (const XMLNode& node, bool edit)
1915 XMLNodeList nlist = node.children();
1916 XMLNodeConstIterator niter;
1921 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1922 if ((*niter)->name() == "RouteGroup") {
1924 rg = add_edit_group ("");
1925 rg->set_state (**niter);
1927 rg = add_mix_group ("");
1928 rg->set_state (**niter);
1937 Session::auto_save()
1939 save_state (_current_snapshot_name);
1943 Session::add_edit_group (string name)
1945 RouteGroup* rg = new RouteGroup (*this, name);
1946 edit_groups.push_back (rg);
1947 edit_group_added (rg); /* EMIT SIGNAL */
1953 Session::add_mix_group (string name)
1955 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
1956 mix_groups.push_back (rg);
1957 mix_group_added (rg); /* EMIT SIGNAL */
1963 Session::remove_edit_group (RouteGroup& rg)
1965 list<RouteGroup*>::iterator i;
1967 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
1968 (*i)->apply (&Route::drop_edit_group, this);
1969 edit_groups.erase (i);
1970 edit_group_removed (); /* EMIT SIGNAL */
1977 Session::remove_mix_group (RouteGroup& rg)
1979 list<RouteGroup*>::iterator i;
1981 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
1982 (*i)->apply (&Route::drop_mix_group, this);
1983 mix_groups.erase (i);
1984 mix_group_removed (); /* EMIT SIGNAL */
1991 Session::mix_group_by_name (string name)
1993 list<RouteGroup *>::iterator i;
1995 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1996 if ((*i)->name() == name) {
2004 Session::edit_group_by_name (string name)
2006 list<RouteGroup *>::iterator i;
2008 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2009 if ((*i)->name() == name) {
2017 Session::begin_reversible_command (const string& name)
2019 current_trans = new UndoTransaction;
2020 current_trans->set_name (name);
2024 Session::commit_reversible_command (Command *cmd)
2029 current_trans->add_command (cmd);
2032 gettimeofday (&now, 0);
2033 current_trans->set_timestamp (now);
2035 _history.add (current_trans);
2038 Session::GlobalRouteBooleanState
2039 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2041 GlobalRouteBooleanState s;
2042 boost::shared_ptr<RouteList> r = routes.reader ();
2044 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2045 if (!(*i)->is_hidden()) {
2046 RouteBooleanState v;
2049 Route* r = (*i).get();
2050 v.second = (r->*method)();
2059 Session::GlobalRouteMeterState
2060 Session::get_global_route_metering ()
2062 GlobalRouteMeterState s;
2063 boost::shared_ptr<RouteList> r = routes.reader ();
2065 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2066 if (!(*i)->is_hidden()) {
2070 v.second = (*i)->meter_point();
2080 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2082 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2084 boost::shared_ptr<Route> r = (i->first.lock());
2087 r->set_meter_point (i->second, arg);
2093 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2095 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2097 boost::shared_ptr<Route> r = (i->first.lock());
2100 Route* rp = r.get();
2101 (rp->*method) (i->second, arg);
2107 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2109 set_global_route_boolean (s, &Route::set_mute, src);
2113 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2115 set_global_route_boolean (s, &Route::set_solo, src);
2119 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2121 set_global_route_boolean (s, &Route::set_record_enable, src);
2126 Session::global_mute_memento (void* src)
2128 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2132 Session::global_metering_memento (void* src)
2134 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2138 Session::global_solo_memento (void* src)
2140 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2144 Session::global_record_enable_memento (void* src)
2146 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2151 accept_all_non_peak_files (const string& path, void *arg)
2153 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2157 accept_all_state_files (const string& path, void *arg)
2159 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2163 Session::find_all_sources (string path, set<string>& result)
2168 if (!tree.read (path)) {
2172 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2177 XMLNodeConstIterator niter;
2179 nlist = node->children();
2183 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2187 if ((prop = (*niter)->property (X_("name"))) == 0) {
2191 if (prop->value()[0] == '/') {
2192 /* external file, ignore */
2196 sys::path source_path = _session_dir->sound_path ();
2198 source_path /= prop->value ();
2200 result.insert (source_path.to_string ());
2207 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2209 PathScanner scanner;
2210 vector<string*>* state_files;
2212 string this_snapshot_path;
2218 if (ripped[ripped.length()-1] == '/') {
2219 ripped = ripped.substr (0, ripped.length() - 1);
2222 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2224 if (state_files == 0) {
2229 this_snapshot_path = _path;
2230 this_snapshot_path += _current_snapshot_name;
2231 this_snapshot_path += statefile_suffix;
2233 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2235 if (exclude_this_snapshot && **i == this_snapshot_path) {
2239 if (find_all_sources (**i, result) < 0) {
2247 struct RegionCounter {
2248 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2249 AudioSourceList::iterator iter;
2250 boost::shared_ptr<Region> region;
2253 RegionCounter() : count (0) {}
2257 Session::cleanup_sources (Session::cleanup_report& rep)
2259 // FIXME: needs adaptation to midi
2261 vector<boost::shared_ptr<Source> > dead_sources;
2262 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2263 PathScanner scanner;
2265 vector<space_and_path>::iterator i;
2266 vector<space_and_path>::iterator nexti;
2267 vector<string*>* soundfiles;
2268 vector<string> unused;
2269 set<string> all_sources;
2274 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2276 /* step 1: consider deleting all unused playlists */
2278 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2281 status = AskAboutPlaylistDeletion (*x);
2290 playlists_tbd.push_back (*x);
2294 /* leave it alone */
2299 /* now delete any that were marked for deletion */
2301 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2302 (*x)->drop_references ();
2305 playlists_tbd.clear ();
2307 /* step 2: find all un-used sources */
2312 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2314 SourceMap::iterator tmp;
2319 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2323 if (!i->second->used() && i->second->length() > 0) {
2324 dead_sources.push_back (i->second);
2325 i->second->GoingAway();
2331 /* build a list of all the possible sound directories for the session */
2333 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2338 SessionDirectory sdir ((*i).path);
2339 sound_path += sdir.sound_path().to_string();
2341 if (nexti != session_dirs.end()) {
2348 /* now do the same thing for the files that ended up in the sounds dir(s)
2349 but are not referenced as sources in any snapshot.
2352 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2354 if (soundfiles == 0) {
2358 /* find all sources, but don't use this snapshot because the
2359 state file on disk still references sources we may have already
2363 find_all_sources_across_snapshots (all_sources, true);
2365 /* add our current source list
2368 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2369 boost::shared_ptr<AudioFileSource> fs;
2371 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2372 all_sources.insert (fs->path());
2376 char tmppath1[PATH_MAX+1];
2377 char tmppath2[PATH_MAX+1];
2379 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2384 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2386 realpath(spath.c_str(), tmppath1);
2387 realpath((*i).c_str(), tmppath2);
2389 if (strcmp(tmppath1, tmppath2) == 0) {
2396 unused.push_back (spath);
2400 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2402 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2403 struct stat statbuf;
2405 rep.paths.push_back (*x);
2406 if (stat ((*x).c_str(), &statbuf) == 0) {
2407 rep.space += statbuf.st_size;
2412 /* don't move the file across filesystems, just
2413 stick it in the `dead_sound_dir_name' directory
2414 on whichever filesystem it was already on.
2417 if ((*x).find ("/sounds/") != string::npos) {
2419 /* old school, go up 1 level */
2421 newpath = Glib::path_get_dirname (*x); // "sounds"
2422 newpath = Glib::path_get_dirname (newpath); // "session-name"
2426 /* new school, go up 4 levels */
2428 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2429 newpath = Glib::path_get_dirname (newpath); // "session-name"
2430 newpath = Glib::path_get_dirname (newpath); // "interchange"
2431 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2435 newpath += dead_sound_dir_name;
2437 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2438 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2443 newpath += Glib::path_get_basename ((*x));
2445 if (access (newpath.c_str(), F_OK) == 0) {
2447 /* the new path already exists, try versioning */
2449 char buf[PATH_MAX+1];
2453 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2456 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2457 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2461 if (version == 999) {
2462 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2466 newpath = newpath_v;
2471 /* it doesn't exist, or we can't read it or something */
2475 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2476 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2477 (*x), newpath, strerror (errno))
2482 /* see if there an easy to find peakfile for this file, and remove it.
2485 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2486 peakpath += peakfile_suffix;
2488 if (access (peakpath.c_str(), W_OK) == 0) {
2489 if (::unlink (peakpath.c_str()) != 0) {
2490 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2491 peakpath, _path, strerror (errno))
2493 /* try to back out */
2494 rename (newpath.c_str(), _path.c_str());
2502 /* dump the history list */
2506 /* save state so we don't end up a session file
2507 referring to non-existent sources.
2513 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2518 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2520 // FIXME: needs adaptation for MIDI
2522 vector<space_and_path>::iterator i;
2523 string dead_sound_dir;
2524 struct dirent* dentry;
2525 struct stat statbuf;
2531 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2533 dead_sound_dir = (*i).path;
2534 dead_sound_dir += dead_sound_dir_name;
2536 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2540 while ((dentry = readdir (dead)) != 0) {
2542 /* avoid '.' and '..' */
2544 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2545 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2551 fullpath = dead_sound_dir;
2553 fullpath += dentry->d_name;
2555 if (stat (fullpath.c_str(), &statbuf)) {
2559 if (!S_ISREG (statbuf.st_mode)) {
2563 if (unlink (fullpath.c_str())) {
2564 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2565 fullpath, strerror (errno))
2569 rep.paths.push_back (dentry->d_name);
2570 rep.space += statbuf.st_size;
2581 Session::set_dirty ()
2583 bool was_dirty = dirty();
2585 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2588 DirtyChanged(); /* EMIT SIGNAL */
2594 Session::set_clean ()
2596 bool was_dirty = dirty();
2598 _state_of_the_state = Clean;
2601 DirtyChanged(); /* EMIT SIGNAL */
2606 Session::set_deletion_in_progress ()
2608 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2612 Session::add_controllable (boost::shared_ptr<Controllable> c)
2614 /* this adds a controllable to the list managed by the Session.
2615 this is a subset of those managed by the Controllable class
2616 itself, and represents the only ones whose state will be saved
2617 as part of the session.
2620 Glib::Mutex::Lock lm (controllables_lock);
2621 controllables.insert (c);
2624 struct null_deleter { void operator()(void const *) const {} };
2627 Session::remove_controllable (Controllable* c)
2629 if (_state_of_the_state | Deletion) {
2633 Glib::Mutex::Lock lm (controllables_lock);
2635 Controllables::iterator x = controllables.find(
2636 boost::shared_ptr<Controllable>(c, null_deleter()));
2638 if (x != controllables.end()) {
2639 controllables.erase (x);
2643 boost::shared_ptr<Controllable>
2644 Session::controllable_by_id (const PBD::ID& id)
2646 Glib::Mutex::Lock lm (controllables_lock);
2648 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2649 if ((*i)->id() == id) {
2654 return boost::shared_ptr<Controllable>();
2658 Session::add_instant_xml (XMLNode& node)
2660 Stateful::add_instant_xml (node, _path);
2661 Config->add_instant_xml (node);
2665 Session::instant_xml (const string& node_name)
2667 return Stateful::instant_xml (node_name, _path);
2671 Session::save_history (string snapshot_name)
2675 if (snapshot_name.empty()) {
2676 snapshot_name = _current_snapshot_name;
2679 const string history_filename = snapshot_name + history_suffix;
2680 const string backup_filename = history_filename + backup_suffix;
2681 const sys::path xml_path = _session_dir->root_path() / history_filename;
2682 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2684 if (sys::exists (xml_path)) {
2687 sys::rename (xml_path, backup_path);
2689 catch (const sys::filesystem_error& err)
2691 error << _("could not backup old history file, current history not saved") << endmsg;
2697 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2701 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2703 if (!tree.write (xml_path.to_string()))
2705 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2709 sys::remove (xml_path);
2710 sys::rename (backup_path, xml_path);
2712 catch (const sys::filesystem_error& err)
2714 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2715 backup_path.to_string(), err.what()) << endmsg;
2725 Session::restore_history (string snapshot_name)
2729 if (snapshot_name.empty()) {
2730 snapshot_name = _current_snapshot_name;
2733 const string xml_filename = snapshot_name + history_suffix;
2734 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2736 info << string_compose(_("Loading history from '%1'."), xml_path.to_string()) << endmsg;
2738 if (!sys::exists (xml_path)) {
2739 info << string_compose (_("%1: no history file \"%2\" for this session."),
2740 _name, xml_path.to_string()) << endmsg;
2744 if (!tree.read (xml_path.to_string())) {
2745 error << string_compose (_("Could not understand session history file \"%1\""),
2746 xml_path.to_string()) << endmsg;
2753 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2756 UndoTransaction* ut = new UndoTransaction ();
2759 ut->set_name(t->property("name")->value());
2760 stringstream ss(t->property("tv_sec")->value());
2762 ss.str(t->property("tv_usec")->value());
2764 ut->set_timestamp(tv);
2766 for (XMLNodeConstIterator child_it = t->children().begin();
2767 child_it != t->children().end();
2770 XMLNode *n = *child_it;
2773 if (n->name() == "MementoCommand" ||
2774 n->name() == "MementoUndoCommand" ||
2775 n->name() == "MementoRedoCommand") {
2777 if ((c = memento_command_factory(n))) {
2781 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2783 if ((c = global_state_command_factory (*n))) {
2784 ut->add_command (c);
2789 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2800 Session::config_changed (const char* parameter_name)
2802 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2804 if (PARAM_IS ("seamless-loop")) {
2806 } else if (PARAM_IS ("rf-speed")) {
2808 } else if (PARAM_IS ("auto-loop")) {
2810 } else if (PARAM_IS ("auto-input")) {
2812 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2813 /* auto-input only makes a difference if we're rolling */
2815 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2817 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2818 if ((*i)->record_enabled ()) {
2819 (*i)->monitor_input (!Config->get_auto_input());
2824 } else if (PARAM_IS ("punch-in")) {
2828 if ((location = _locations.auto_punch_location()) != 0) {
2830 if (Config->get_punch_in ()) {
2831 replace_event (Event::PunchIn, location->start());
2833 remove_event (location->start(), Event::PunchIn);
2837 } else if (PARAM_IS ("punch-out")) {
2841 if ((location = _locations.auto_punch_location()) != 0) {
2843 if (Config->get_punch_out()) {
2844 replace_event (Event::PunchOut, location->end());
2846 clear_events (Event::PunchOut);
2850 } else if (PARAM_IS ("edit-mode")) {
2852 Glib::Mutex::Lock lm (playlist_lock);
2854 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2855 (*i)->set_edit_mode (Config->get_edit_mode ());
2858 } else if (PARAM_IS ("use-video-sync")) {
2860 waiting_for_sync_offset = Config->get_use_video_sync();
2862 } else if (PARAM_IS ("mmc-control")) {
2864 //poke_midi_thread ();
2866 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
2869 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
2872 } else if (PARAM_IS ("mmc-send-id")) {
2875 mmc->set_send_device_id (Config->get_mmc_send_device_id());
2878 } else if (PARAM_IS ("midi-control")) {
2880 //poke_midi_thread ();
2882 } else if (PARAM_IS ("raid-path")) {
2884 setup_raid_path (Config->get_raid_path());
2886 } else if (PARAM_IS ("smpte-format")) {
2890 } else if (PARAM_IS ("video-pullup")) {
2894 } else if (PARAM_IS ("seamless-loop")) {
2896 if (play_loop && transport_rolling()) {
2897 // to reset diskstreams etc
2898 request_play_loop (true);
2901 } else if (PARAM_IS ("rf-speed")) {
2903 cumulative_rf_motion = 0;
2906 } else if (PARAM_IS ("click-sound")) {
2908 setup_click_sounds (1);
2910 } else if (PARAM_IS ("click-emphasis-sound")) {
2912 setup_click_sounds (-1);
2914 } else if (PARAM_IS ("clicking")) {
2916 if (Config->get_clicking()) {
2917 if (_click_io && click_data) { // don't require emphasis data
2924 } else if (PARAM_IS ("send-mtc")) {
2926 /* only set the internal flag if we have
2930 if (_mtc_port != 0) {
2931 session_send_mtc = Config->get_send_mtc();
2932 if (session_send_mtc) {
2933 /* mark us ready to send */
2934 next_quarter_frame_to_send = 0;
2937 session_send_mtc = false;
2940 } else if (PARAM_IS ("send-mmc")) {
2942 /* only set the internal flag if we have
2946 if (_mmc_port != 0) {
2947 session_send_mmc = Config->get_send_mmc();
2950 session_send_mmc = false;
2953 } else if (PARAM_IS ("midi-feedback")) {
2955 /* only set the internal flag if we have
2959 if (_mtc_port != 0) {
2960 session_midi_feedback = Config->get_midi_feedback();
2963 } else if (PARAM_IS ("jack-time-master")) {
2965 engine().reset_timebase ();
2967 } else if (PARAM_IS ("native-file-header-format")) {
2969 if (!first_file_header_format_reset) {
2970 reset_native_file_format ();
2973 first_file_header_format_reset = false;
2975 } else if (PARAM_IS ("native-file-data-format")) {
2977 if (!first_file_data_format_reset) {
2978 reset_native_file_format ();
2981 first_file_data_format_reset = false;
2983 } else if (PARAM_IS ("slave-source")) {
2984 set_slave_source (Config->get_slave_source());
2985 } else if (PARAM_IS ("remote-model")) {
2986 set_remote_control_ids ();
2987 } else if (PARAM_IS ("denormal-model")) {
2989 } else if (PARAM_IS ("history-depth")) {
2990 set_history_depth (Config->get_history_depth());
2991 } else if (PARAM_IS ("sync-all-route-ordering")) {
3002 Session::set_history_depth (uint32_t d)
3004 _history.set_depth (d);