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 string sound_dir = ((type == DataType::AUDIO)
1577 ? sdir.sound_path().to_string()
1578 : sdir.midi_path().to_string());
1580 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1582 for (n = 0; n < 999999; ++n) {
1583 if (identifier.length()) {
1584 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1585 identifier.c_str(), n, ext.c_str());
1587 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1591 if (!sys::exists (buf)) {
1596 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1605 Session::load_sources (const XMLNode& node)
1608 XMLNodeConstIterator niter;
1609 boost::shared_ptr<Source> source;
1611 nlist = node.children();
1615 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1618 if ((source = XMLSourceFactory (**niter)) == 0) {
1619 error << _("Session: cannot create Source from XML description.") << endmsg;
1623 catch (non_existent_source& err) {
1624 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1625 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1632 boost::shared_ptr<Source>
1633 Session::XMLSourceFactory (const XMLNode& node)
1635 if (node.name() != "Source") {
1636 return boost::shared_ptr<Source>();
1640 return SourceFactory::create (*this, node);
1643 catch (failed_constructor& err) {
1644 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1645 return boost::shared_ptr<Source>();
1650 Session::save_template (string template_name)
1654 if (_state_of_the_state & CannotSave) {
1658 sys::path user_template_dir(user_template_directory());
1662 sys::create_directories (user_template_dir);
1664 catch(sys::filesystem_error& ex)
1666 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1667 user_template_dir.to_string(), ex.what()) << endmsg;
1671 tree.set_root (&get_template());
1673 sys::path template_file_path(user_template_dir);
1674 template_file_path /= template_name + template_suffix;
1676 if (sys::exists (template_file_path))
1678 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1679 template_file_path.to_string()) << endmsg;
1683 if (!tree.write (template_file_path.to_string())) {
1684 error << _("mix template not saved") << endmsg;
1692 Session::refresh_disk_space ()
1695 struct statfs statfsbuf;
1696 vector<space_and_path>::iterator i;
1697 Glib::Mutex::Lock lm (space_lock);
1700 /* get freespace on every FS that is part of the session path */
1702 _total_free_4k_blocks = 0;
1704 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1705 statfs ((*i).path.c_str(), &statfsbuf);
1707 scale = statfsbuf.f_bsize/4096.0;
1709 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1710 _total_free_4k_blocks += (*i).blocks;
1716 Session::get_best_session_directory_for_new_source ()
1718 vector<space_and_path>::iterator i;
1719 string result = _session_dir->root_path().to_string();
1721 /* handle common case without system calls */
1723 if (session_dirs.size() == 1) {
1727 /* OK, here's the algorithm we're following here:
1729 We want to select which directory to use for
1730 the next file source to be created. Ideally,
1731 we'd like to use a round-robin process so as to
1732 get maximum performance benefits from splitting
1733 the files across multiple disks.
1735 However, in situations without much diskspace, an
1736 RR approach may end up filling up a filesystem
1737 with new files while others still have space.
1738 Its therefore important to pay some attention to
1739 the freespace in the filesystem holding each
1740 directory as well. However, if we did that by
1741 itself, we'd keep creating new files in the file
1742 system with the most space until it was as full
1743 as all others, thus negating any performance
1744 benefits of this RAID-1 like approach.
1746 So, we use a user-configurable space threshold. If
1747 there are at least 2 filesystems with more than this
1748 much space available, we use RR selection between them.
1749 If not, then we pick the filesystem with the most space.
1751 This gets a good balance between the two
1755 refresh_disk_space ();
1757 int free_enough = 0;
1759 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1760 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1765 if (free_enough >= 2) {
1766 /* use RR selection process, ensuring that the one
1770 i = last_rr_session_dir;
1773 if (++i == session_dirs.end()) {
1774 i = session_dirs.begin();
1777 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1778 if (create_session_directory ((*i).path)) {
1780 last_rr_session_dir = i;
1785 } while (i != last_rr_session_dir);
1789 /* pick FS with the most freespace (and that
1790 seems to actually work ...)
1793 vector<space_and_path> sorted;
1794 space_and_path_ascending_cmp cmp;
1796 sorted = session_dirs;
1797 sort (sorted.begin(), sorted.end(), cmp);
1799 for (i = sorted.begin(); i != sorted.end(); ++i) {
1800 if (create_session_directory ((*i).path)) {
1802 last_rr_session_dir = i;
1812 Session::load_playlists (const XMLNode& node)
1815 XMLNodeConstIterator niter;
1816 boost::shared_ptr<Playlist> playlist;
1818 nlist = node.children();
1822 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1824 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1825 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1833 Session::load_unused_playlists (const XMLNode& node)
1836 XMLNodeConstIterator niter;
1837 boost::shared_ptr<Playlist> playlist;
1839 nlist = node.children();
1843 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1845 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1846 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1850 // now manually untrack it
1852 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1858 boost::shared_ptr<Playlist>
1859 Session::XMLPlaylistFactory (const XMLNode& node)
1862 return PlaylistFactory::create (*this, node);
1865 catch (failed_constructor& err) {
1866 return boost::shared_ptr<Playlist>();
1871 Session::load_named_selections (const XMLNode& node)
1874 XMLNodeConstIterator niter;
1877 nlist = node.children();
1881 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1883 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1884 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1892 Session::XMLNamedSelectionFactory (const XMLNode& node)
1895 return new NamedSelection (*this, node);
1898 catch (failed_constructor& err) {
1904 Session::automation_dir () const
1907 res += "automation/";
1912 Session::load_bundles (XMLNode const & node)
1914 XMLNodeList nlist = node.children();
1915 XMLNodeConstIterator niter;
1919 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1920 if ((*niter)->name() == "InputBundle") {
1921 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
1922 } else if ((*niter)->name() == "OutputBundle") {
1923 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
1925 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
1934 Session::load_edit_groups (const XMLNode& node)
1936 return load_route_groups (node, true);
1940 Session::load_mix_groups (const XMLNode& node)
1942 return load_route_groups (node, false);
1946 Session::load_route_groups (const XMLNode& node, bool edit)
1948 XMLNodeList nlist = node.children();
1949 XMLNodeConstIterator niter;
1954 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1955 if ((*niter)->name() == "RouteGroup") {
1957 rg = add_edit_group ("");
1958 rg->set_state (**niter);
1960 rg = add_mix_group ("");
1961 rg->set_state (**niter);
1970 Session::auto_save()
1972 save_state (_current_snapshot_name);
1976 Session::add_edit_group (string name)
1978 RouteGroup* rg = new RouteGroup (*this, name);
1979 edit_groups.push_back (rg);
1980 edit_group_added (rg); /* EMIT SIGNAL */
1986 Session::add_mix_group (string name)
1988 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
1989 mix_groups.push_back (rg);
1990 mix_group_added (rg); /* EMIT SIGNAL */
1996 Session::remove_edit_group (RouteGroup& rg)
1998 list<RouteGroup*>::iterator i;
2000 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2001 (*i)->apply (&Route::drop_edit_group, this);
2002 edit_groups.erase (i);
2003 edit_group_removed (); /* EMIT SIGNAL */
2010 Session::remove_mix_group (RouteGroup& rg)
2012 list<RouteGroup*>::iterator i;
2014 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2015 (*i)->apply (&Route::drop_mix_group, this);
2016 mix_groups.erase (i);
2017 mix_group_removed (); /* EMIT SIGNAL */
2024 Session::mix_group_by_name (string name)
2026 list<RouteGroup *>::iterator i;
2028 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2029 if ((*i)->name() == name) {
2037 Session::edit_group_by_name (string name)
2039 list<RouteGroup *>::iterator i;
2041 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2042 if ((*i)->name() == name) {
2050 Session::begin_reversible_command (const string& name)
2052 current_trans = new UndoTransaction;
2053 current_trans->set_name (name);
2057 Session::commit_reversible_command (Command *cmd)
2062 current_trans->add_command (cmd);
2065 gettimeofday (&now, 0);
2066 current_trans->set_timestamp (now);
2068 _history.add (current_trans);
2071 Session::GlobalRouteBooleanState
2072 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2074 GlobalRouteBooleanState s;
2075 boost::shared_ptr<RouteList> r = routes.reader ();
2077 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2078 if (!(*i)->is_hidden()) {
2079 RouteBooleanState v;
2082 Route* r = (*i).get();
2083 v.second = (r->*method)();
2092 Session::GlobalRouteMeterState
2093 Session::get_global_route_metering ()
2095 GlobalRouteMeterState s;
2096 boost::shared_ptr<RouteList> r = routes.reader ();
2098 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2099 if (!(*i)->is_hidden()) {
2103 v.second = (*i)->meter_point();
2113 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2115 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2117 boost::shared_ptr<Route> r = (i->first.lock());
2120 r->set_meter_point (i->second, arg);
2126 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2128 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2130 boost::shared_ptr<Route> r = (i->first.lock());
2133 Route* rp = r.get();
2134 (rp->*method) (i->second, arg);
2140 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2142 set_global_route_boolean (s, &Route::set_mute, src);
2146 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2148 set_global_route_boolean (s, &Route::set_solo, src);
2152 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2154 set_global_route_boolean (s, &Route::set_record_enable, src);
2159 Session::global_mute_memento (void* src)
2161 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2165 Session::global_metering_memento (void* src)
2167 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2171 Session::global_solo_memento (void* src)
2173 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2177 Session::global_record_enable_memento (void* src)
2179 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2184 accept_all_non_peak_files (const string& path, void *arg)
2186 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2190 accept_all_state_files (const string& path, void *arg)
2192 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2196 Session::find_all_sources (string path, set<string>& result)
2201 if (!tree.read (path)) {
2205 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2210 XMLNodeConstIterator niter;
2212 nlist = node->children();
2216 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2220 if ((prop = (*niter)->property (X_("name"))) == 0) {
2224 if (prop->value()[0] == '/') {
2225 /* external file, ignore */
2229 sys::path source_path = _session_dir->sound_path ();
2231 source_path /= prop->value ();
2233 result.insert (source_path.to_string ());
2240 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2242 PathScanner scanner;
2243 vector<string*>* state_files;
2245 string this_snapshot_path;
2251 if (ripped[ripped.length()-1] == '/') {
2252 ripped = ripped.substr (0, ripped.length() - 1);
2255 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2257 if (state_files == 0) {
2262 this_snapshot_path = _path;
2263 this_snapshot_path += _current_snapshot_name;
2264 this_snapshot_path += statefile_suffix;
2266 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2268 if (exclude_this_snapshot && **i == this_snapshot_path) {
2272 if (find_all_sources (**i, result) < 0) {
2280 struct RegionCounter {
2281 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2282 AudioSourceList::iterator iter;
2283 boost::shared_ptr<Region> region;
2286 RegionCounter() : count (0) {}
2290 Session::cleanup_sources (Session::cleanup_report& rep)
2292 // FIXME: needs adaptation to midi
2294 vector<boost::shared_ptr<Source> > dead_sources;
2295 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2296 PathScanner scanner;
2298 vector<space_and_path>::iterator i;
2299 vector<space_and_path>::iterator nexti;
2300 vector<string*>* soundfiles;
2301 vector<string> unused;
2302 set<string> all_sources;
2307 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2309 /* step 1: consider deleting all unused playlists */
2311 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2314 status = AskAboutPlaylistDeletion (*x);
2323 playlists_tbd.push_back (*x);
2327 /* leave it alone */
2332 /* now delete any that were marked for deletion */
2334 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2335 (*x)->drop_references ();
2338 playlists_tbd.clear ();
2340 /* step 2: find all un-used sources */
2345 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2347 SourceMap::iterator tmp;
2352 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2356 if (!i->second->used() && i->second->length() > 0) {
2357 dead_sources.push_back (i->second);
2358 i->second->GoingAway();
2364 /* build a list of all the possible sound directories for the session */
2366 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2371 SessionDirectory sdir ((*i).path);
2372 sound_path += sdir.sound_path().to_string();
2374 if (nexti != session_dirs.end()) {
2381 /* now do the same thing for the files that ended up in the sounds dir(s)
2382 but are not referenced as sources in any snapshot.
2385 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2387 if (soundfiles == 0) {
2391 /* find all sources, but don't use this snapshot because the
2392 state file on disk still references sources we may have already
2396 find_all_sources_across_snapshots (all_sources, true);
2398 /* add our current source list
2401 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2402 boost::shared_ptr<AudioFileSource> fs;
2404 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2405 all_sources.insert (fs->path());
2409 char tmppath1[PATH_MAX+1];
2410 char tmppath2[PATH_MAX+1];
2412 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2417 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2419 realpath(spath.c_str(), tmppath1);
2420 realpath((*i).c_str(), tmppath2);
2422 if (strcmp(tmppath1, tmppath2) == 0) {
2429 unused.push_back (spath);
2433 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2435 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2436 struct stat statbuf;
2438 rep.paths.push_back (*x);
2439 if (stat ((*x).c_str(), &statbuf) == 0) {
2440 rep.space += statbuf.st_size;
2445 /* don't move the file across filesystems, just
2446 stick it in the `dead_sound_dir_name' directory
2447 on whichever filesystem it was already on.
2450 if ((*x).find ("/sounds/") != string::npos) {
2452 /* old school, go up 1 level */
2454 newpath = Glib::path_get_dirname (*x); // "sounds"
2455 newpath = Glib::path_get_dirname (newpath); // "session-name"
2459 /* new school, go up 4 levels */
2461 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2462 newpath = Glib::path_get_dirname (newpath); // "session-name"
2463 newpath = Glib::path_get_dirname (newpath); // "interchange"
2464 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2468 newpath += dead_sound_dir_name;
2470 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2471 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2476 newpath += Glib::path_get_basename ((*x));
2478 if (access (newpath.c_str(), F_OK) == 0) {
2480 /* the new path already exists, try versioning */
2482 char buf[PATH_MAX+1];
2486 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2489 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2490 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2494 if (version == 999) {
2495 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2499 newpath = newpath_v;
2504 /* it doesn't exist, or we can't read it or something */
2508 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2509 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2510 (*x), newpath, strerror (errno))
2515 /* see if there an easy to find peakfile for this file, and remove it.
2518 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2519 peakpath += peakfile_suffix;
2521 if (access (peakpath.c_str(), W_OK) == 0) {
2522 if (::unlink (peakpath.c_str()) != 0) {
2523 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2524 peakpath, _path, strerror (errno))
2526 /* try to back out */
2527 rename (newpath.c_str(), _path.c_str());
2535 /* dump the history list */
2539 /* save state so we don't end up a session file
2540 referring to non-existent sources.
2546 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2551 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2553 // FIXME: needs adaptation for MIDI
2555 vector<space_and_path>::iterator i;
2556 string dead_sound_dir;
2557 struct dirent* dentry;
2558 struct stat statbuf;
2564 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2566 dead_sound_dir = (*i).path;
2567 dead_sound_dir += dead_sound_dir_name;
2569 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2573 while ((dentry = readdir (dead)) != 0) {
2575 /* avoid '.' and '..' */
2577 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2578 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2584 fullpath = dead_sound_dir;
2586 fullpath += dentry->d_name;
2588 if (stat (fullpath.c_str(), &statbuf)) {
2592 if (!S_ISREG (statbuf.st_mode)) {
2596 if (unlink (fullpath.c_str())) {
2597 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2598 fullpath, strerror (errno))
2602 rep.paths.push_back (dentry->d_name);
2603 rep.space += statbuf.st_size;
2614 Session::set_dirty ()
2616 bool was_dirty = dirty();
2618 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2621 DirtyChanged(); /* EMIT SIGNAL */
2627 Session::set_clean ()
2629 bool was_dirty = dirty();
2631 _state_of_the_state = Clean;
2634 DirtyChanged(); /* EMIT SIGNAL */
2639 Session::set_deletion_in_progress ()
2641 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2645 Session::add_controllable (boost::shared_ptr<Controllable> c)
2647 /* this adds a controllable to the list managed by the Session.
2648 this is a subset of those managed by the Controllable class
2649 itself, and represents the only ones whose state will be saved
2650 as part of the session.
2653 Glib::Mutex::Lock lm (controllables_lock);
2654 controllables.insert (c);
2657 struct null_deleter { void operator()(void const *) const {} };
2660 Session::remove_controllable (Controllable* c)
2662 if (_state_of_the_state | Deletion) {
2666 Glib::Mutex::Lock lm (controllables_lock);
2668 Controllables::iterator x = controllables.find(
2669 boost::shared_ptr<Controllable>(c, null_deleter()));
2671 if (x != controllables.end()) {
2672 controllables.erase (x);
2676 boost::shared_ptr<Controllable>
2677 Session::controllable_by_id (const PBD::ID& id)
2679 Glib::Mutex::Lock lm (controllables_lock);
2681 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2682 if ((*i)->id() == id) {
2687 return boost::shared_ptr<Controllable>();
2691 Session::add_instant_xml (XMLNode& node)
2693 Stateful::add_instant_xml (node, _path);
2694 Config->add_instant_xml (node);
2698 Session::instant_xml (const string& node_name)
2700 return Stateful::instant_xml (node_name, _path);
2704 Session::save_history (string snapshot_name)
2708 if (snapshot_name.empty()) {
2709 snapshot_name = _current_snapshot_name;
2712 const string history_filename = snapshot_name + history_suffix;
2713 const string backup_filename = history_filename + backup_suffix;
2714 const sys::path xml_path = _session_dir->root_path() / history_filename;
2715 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2717 if (sys::exists (xml_path)) {
2720 sys::rename (xml_path, backup_path);
2722 catch (const sys::filesystem_error& err)
2724 error << _("could not backup old history file, current history not saved") << endmsg;
2730 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2734 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2736 if (!tree.write (xml_path.to_string()))
2738 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2742 sys::remove (xml_path);
2743 sys::rename (backup_path, xml_path);
2745 catch (const sys::filesystem_error& err)
2747 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2748 backup_path.to_string(), err.what()) << endmsg;
2758 Session::restore_history (string snapshot_name)
2762 if (snapshot_name.empty()) {
2763 snapshot_name = _current_snapshot_name;
2766 const string xml_filename = snapshot_name + history_suffix;
2767 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2769 info << string_compose(_("Loading history from '%1'."), xml_path.to_string()) << endmsg;
2771 if (!sys::exists (xml_path)) {
2772 info << string_compose (_("%1: no history file \"%2\" for this session."),
2773 _name, xml_path.to_string()) << endmsg;
2777 if (!tree.read (xml_path.to_string())) {
2778 error << string_compose (_("Could not understand session history file \"%1\""),
2779 xml_path.to_string()) << endmsg;
2786 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2789 UndoTransaction* ut = new UndoTransaction ();
2792 ut->set_name(t->property("name")->value());
2793 stringstream ss(t->property("tv_sec")->value());
2795 ss.str(t->property("tv_usec")->value());
2797 ut->set_timestamp(tv);
2799 for (XMLNodeConstIterator child_it = t->children().begin();
2800 child_it != t->children().end();
2803 XMLNode *n = *child_it;
2806 if (n->name() == "MementoCommand" ||
2807 n->name() == "MementoUndoCommand" ||
2808 n->name() == "MementoRedoCommand") {
2810 if ((c = memento_command_factory(n))) {
2814 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2816 if ((c = global_state_command_factory (*n))) {
2817 ut->add_command (c);
2822 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2833 Session::config_changed (const char* parameter_name)
2835 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2837 if (PARAM_IS ("seamless-loop")) {
2839 } else if (PARAM_IS ("rf-speed")) {
2841 } else if (PARAM_IS ("auto-loop")) {
2843 } else if (PARAM_IS ("auto-input")) {
2845 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2846 /* auto-input only makes a difference if we're rolling */
2848 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2850 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2851 if ((*i)->record_enabled ()) {
2852 (*i)->monitor_input (!Config->get_auto_input());
2857 } else if (PARAM_IS ("punch-in")) {
2861 if ((location = _locations.auto_punch_location()) != 0) {
2863 if (Config->get_punch_in ()) {
2864 replace_event (Event::PunchIn, location->start());
2866 remove_event (location->start(), Event::PunchIn);
2870 } else if (PARAM_IS ("punch-out")) {
2874 if ((location = _locations.auto_punch_location()) != 0) {
2876 if (Config->get_punch_out()) {
2877 replace_event (Event::PunchOut, location->end());
2879 clear_events (Event::PunchOut);
2883 } else if (PARAM_IS ("edit-mode")) {
2885 Glib::Mutex::Lock lm (playlist_lock);
2887 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2888 (*i)->set_edit_mode (Config->get_edit_mode ());
2891 } else if (PARAM_IS ("use-video-sync")) {
2893 waiting_for_sync_offset = Config->get_use_video_sync();
2895 } else if (PARAM_IS ("mmc-control")) {
2897 //poke_midi_thread ();
2899 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
2902 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
2905 } else if (PARAM_IS ("mmc-send-id")) {
2908 mmc->set_send_device_id (Config->get_mmc_send_device_id());
2911 } else if (PARAM_IS ("midi-control")) {
2913 //poke_midi_thread ();
2915 } else if (PARAM_IS ("raid-path")) {
2917 setup_raid_path (Config->get_raid_path());
2919 } else if (PARAM_IS ("smpte-format")) {
2923 } else if (PARAM_IS ("video-pullup")) {
2927 } else if (PARAM_IS ("seamless-loop")) {
2929 if (play_loop && transport_rolling()) {
2930 // to reset diskstreams etc
2931 request_play_loop (true);
2934 } else if (PARAM_IS ("rf-speed")) {
2936 cumulative_rf_motion = 0;
2939 } else if (PARAM_IS ("click-sound")) {
2941 setup_click_sounds (1);
2943 } else if (PARAM_IS ("click-emphasis-sound")) {
2945 setup_click_sounds (-1);
2947 } else if (PARAM_IS ("clicking")) {
2949 if (Config->get_clicking()) {
2950 if (_click_io && click_data) { // don't require emphasis data
2957 } else if (PARAM_IS ("send-mtc")) {
2959 /* only set the internal flag if we have
2963 if (_mtc_port != 0) {
2964 session_send_mtc = Config->get_send_mtc();
2965 if (session_send_mtc) {
2966 /* mark us ready to send */
2967 next_quarter_frame_to_send = 0;
2970 session_send_mtc = false;
2973 } else if (PARAM_IS ("send-mmc")) {
2975 /* only set the internal flag if we have
2979 if (_mmc_port != 0) {
2980 session_send_mmc = Config->get_send_mmc();
2983 session_send_mmc = false;
2986 } else if (PARAM_IS ("midi-feedback")) {
2988 /* only set the internal flag if we have
2992 if (_mtc_port != 0) {
2993 session_midi_feedback = Config->get_midi_feedback();
2996 } else if (PARAM_IS ("jack-time-master")) {
2998 engine().reset_timebase ();
3000 } else if (PARAM_IS ("native-file-header-format")) {
3002 if (!first_file_header_format_reset) {
3003 reset_native_file_format ();
3006 first_file_header_format_reset = false;
3008 } else if (PARAM_IS ("native-file-data-format")) {
3010 if (!first_file_data_format_reset) {
3011 reset_native_file_format ();
3014 first_file_data_format_reset = false;
3016 } else if (PARAM_IS ("slave-source")) {
3017 set_slave_source (Config->get_slave_source());
3018 } else if (PARAM_IS ("remote-model")) {
3019 set_remote_control_ids ();
3020 } else if (PARAM_IS ("denormal-model")) {
3022 } else if (PARAM_IS ("history-depth")) {
3023 set_history_depth (Config->get_history_depth());
3024 } else if (PARAM_IS ("sync-all-route-ordering")) {
3035 Session::set_history_depth (uint32_t d)
3037 _history.set_depth (d);