2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #define __STDC_FORMAT_MACROS 1
28 #include <sigc++/bind.h>
30 #include <cstdio> /* snprintf(3) ... grrr */
45 #include <sys/param.h>
46 #include <sys/mount.h>
51 #include <midi++/mmc.h>
52 #include <midi++/port.h>
53 #include <pbd/error.h>
55 #include <glibmm/thread.h>
56 #include <pbd/pathscanner.h>
57 #include <pbd/pthread_utils.h>
58 #include <pbd/search_path.h>
59 #include <pbd/stacktrace.h>
60 #include <pbd/copyfile.h>
62 #include <ardour/audioengine.h>
63 #include <ardour/configuration.h>
64 #include <ardour/session.h>
65 #include <ardour/session_directory.h>
66 #include <ardour/session_utils.h>
67 #include <ardour/buffer.h>
68 #include <ardour/audio_diskstream.h>
69 #include <ardour/midi_diskstream.h>
70 #include <ardour/utils.h>
71 #include <ardour/audioplaylist.h>
72 #include <ardour/midi_playlist.h>
73 #include <ardour/smf_source.h>
74 #include <ardour/audiofilesource.h>
75 #include <ardour/silentfilesource.h>
76 #include <ardour/sndfilesource.h>
77 #include <ardour/midi_source.h>
78 #include <ardour/sndfile_helpers.h>
79 #include <ardour/auditioner.h>
80 #include <ardour/export.h>
81 #include <ardour/io_processor.h>
82 #include <ardour/send.h>
83 #include <ardour/processor.h>
84 #include <ardour/bundle.h>
85 #include <ardour/slave.h>
86 #include <ardour/tempo.h>
87 #include <ardour/audio_track.h>
88 #include <ardour/midi_track.h>
89 #include <ardour/cycle_timer.h>
90 #include <ardour/utils.h>
91 #include <ardour/named_selection.h>
92 #include <ardour/version.h>
93 #include <ardour/location.h>
94 #include <ardour/audioregion.h>
95 #include <ardour/midi_region.h>
96 #include <ardour/crossfade.h>
97 #include <ardour/control_protocol_manager.h>
98 #include <ardour/region_factory.h>
99 #include <ardour/source_factory.h>
100 #include <ardour/playlist_factory.h>
101 #include <ardour/filename_extensions.h>
102 #include <ardour/directory_names.h>
103 #include <ardour/template_utils.h>
105 #include <control_protocol/control_protocol.h>
111 using namespace ARDOUR;
115 Session::first_stage_init (string fullpath, string snapshot_name)
117 if (fullpath.length() == 0) {
119 throw failed_constructor();
122 char buf[PATH_MAX+1];
123 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
124 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
126 throw failed_constructor();
131 if (_path[_path.length()-1] != '/') {
135 /* these two are just provisional settings. set_state()
136 will likely override them.
139 _name = _current_snapshot_name = snapshot_name;
141 _current_frame_rate = _engine.frame_rate ();
142 _tempo_map = new TempoMap (_current_frame_rate);
143 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
145 g_atomic_int_set (&processing_prohibited, 0);
147 _transport_speed = 0;
148 _last_transport_speed = 0;
149 auto_play_legal = false;
150 transport_sub_state = 0;
151 _transport_frame = 0;
153 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
154 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
155 _end_location_is_free = true;
156 g_atomic_int_set (&_record_status, Disabled);
157 loop_changing = false;
159 _last_roll_location = 0;
160 _last_record_location = 0;
161 pending_locate_frame = 0;
162 pending_locate_roll = false;
163 pending_locate_flush = false;
164 dstream_buffer_size = 0;
166 state_was_pending = false;
168 outbound_mtc_smpte_frame = 0;
169 next_quarter_frame_to_send = -1;
170 current_block_size = 0;
171 solo_update_disabled = false;
172 currently_soloing = false;
173 _have_captured = false;
174 _worst_output_latency = 0;
175 _worst_input_latency = 0;
176 _worst_track_latency = 0;
177 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
179 butler_mixdown_buffer = 0;
180 butler_gain_buffer = 0;
182 session_send_mmc = false;
183 session_send_mtc = false;
184 post_transport_work = PostTransportWork (0);
185 g_atomic_int_set (&butler_should_do_transport_work, 0);
186 g_atomic_int_set (&butler_active, 0);
187 g_atomic_int_set (&_playback_load, 100);
188 g_atomic_int_set (&_capture_load, 100);
189 g_atomic_int_set (&_playback_load_min, 100);
190 g_atomic_int_set (&_capture_load_min, 100);
192 waiting_to_start = false;
194 _gain_automation_buffer = 0;
195 _pan_automation_buffer = 0;
197 pending_abort = false;
198 destructive_index = 0;
200 first_file_data_format_reset = true;
201 first_file_header_format_reset = true;
202 butler_thread = (pthread_t) 0;
203 //midi_thread = (pthread_t) 0;
205 AudioDiskstream::allocate_working_buffers();
207 /* default short fade = 15ms */
209 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
210 SndFileSource::setup_standard_crossfades (frame_rate());
212 last_mmc_step.tv_sec = 0;
213 last_mmc_step.tv_usec = 0;
216 /* click sounds are unset by default, which causes us to internal
217 waveforms for clicks.
221 click_emphasis_data = 0;
223 click_emphasis_length = 0;
226 process_function = &Session::process_with_events;
228 if (Config->get_use_video_sync()) {
229 waiting_for_sync_offset = true;
231 waiting_for_sync_offset = false;
234 _current_frame_rate = 48000;
235 _base_frame_rate = 48000;
239 _smpte_offset_negative = true;
240 last_smpte_valid = false;
244 last_rr_session_dir = session_dirs.begin();
245 refresh_disk_space ();
247 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
251 average_slave_delta = 1800;
252 have_first_delta_accumulator = false;
253 delta_accumulator_cnt = 0;
254 slave_state = Stopped;
256 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
258 /* These are all static "per-class" signals */
260 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
261 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
262 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
263 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
264 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
265 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
267 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
269 IO::MoreChannels.connect (mem_fun (*this, &Session::ensure_buffers));
271 /* stop IO objects from doing stuff until we're ready for them */
273 IO::disable_panners ();
274 IO::disable_ports ();
275 IO::disable_connecting ();
279 Session::second_stage_init (bool new_session)
281 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
284 if (load_state (_current_snapshot_name)) {
287 remove_empty_sounds ();
290 if (start_butler_thread()) {
294 /*if (start_midi_thread ()) {
298 // set_state() will call setup_raid_path(), but if it's a new session we need
299 // to call setup_raid_path() here.
301 if (set_state (*state_tree->root())) {
305 setup_raid_path(_path);
308 /* we can't save till after ::when_engine_running() is called,
309 because otherwise we save state with no connections made.
310 therefore, we reset _state_of_the_state because ::set_state()
311 will have cleared it.
313 we also have to include Loading so that any events that get
314 generated between here and the end of ::when_engine_running()
315 will be processed directly rather than queued.
318 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
320 // set_auto_input (true);
321 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
322 _locations.added.connect (mem_fun (this, &Session::locations_added));
323 setup_click_sounds (0);
324 setup_midi_control ();
326 /* Pay attention ... */
328 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
329 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
332 when_engine_running();
335 /* handle this one in a different way than all others, so that its clear what happened */
337 catch (AudioEngine::PortRegistrationFailure& err) {
338 error << _("Unable to create all required ports")
347 //send_full_time_code ();
348 _engine.transport_locate (0);
349 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
350 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
352 ControlProtocolManager::instance().set_session (*this);
355 _end_location_is_free = true;
357 _end_location_is_free = false;
364 Session::raid_path () const
366 SearchPath raid_search_path;
368 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
369 raid_search_path += sys::path((*i).path);
372 return raid_search_path.get_string ();
376 Session::setup_raid_path (string path)
385 session_dirs.clear ();
387 SearchPath search_path(path);
388 SearchPath sound_search_path;
389 SearchPath midi_search_path;
392 SearchPath::const_iterator i = search_path.begin();
393 i != search_path.end();
397 sp.path = (*i).to_string ();
398 sp.blocks = 0; // not needed
399 session_dirs.push_back (sp);
401 SessionDirectory sdir(sp.path);
403 sound_search_path += sdir.sound_path ();
404 midi_search_path += sdir.midi_path ();
407 // set the AudioFileSource and SMFSource search path
409 AudioFileSource::set_search_path (sound_search_path.get_string ());
410 SMFSource::set_search_path (midi_search_path.get_string ());
412 // reset the round-robin soundfile path thingie
414 last_rr_session_dir = session_dirs.begin();
418 Session::initialize_start_and_end_locations (nframes_t start, nframes_t end)
420 start_location->set_end (start);
421 _locations.add (start_location);
423 end_location->set_end (end);
424 _locations.add (end_location);
428 Session::create_session_file ()
430 _state_of_the_state = Clean;
432 if (save_state (_current_snapshot_name)) {
433 error << "Could not create new session file" << endmsg;
440 Session::create_session_file_from_template (const string& template_path)
442 string out_path = _path + _name + statefile_suffix;
444 if(!copy_file (template_path, out_path)) {
445 error << string_compose (_("Could not use session template %1 to create new session."), template_path)
453 Session::load_diskstreams (const XMLNode& node)
456 XMLNodeConstIterator citer;
458 clist = node.children();
460 for (citer = clist.begin(); citer != clist.end(); ++citer) {
463 /* diskstreams added automatically by DiskstreamCreated handler */
464 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
465 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
466 add_diskstream (dstream);
467 } else if ((*citer)->name() == "MidiDiskstream") {
468 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
469 add_diskstream (dstream);
471 error << _("Session: unknown diskstream type in XML") << endmsg;
475 catch (failed_constructor& err) {
476 error << _("Session: could not load diskstream via XML state") << endmsg;
485 Session::maybe_write_autosave()
487 if (dirty() && record_status() != Recording) {
488 save_state("", true);
493 Session::remove_pending_capture_state ()
498 xml_path += _current_snapshot_name;
499 xml_path += pending_suffix;
501 unlink (xml_path.c_str());
504 /** Rename a state file.
505 * @param snapshot_name Snapshot name.
508 Session::rename_state (string old_name, string new_name)
510 if (old_name == _current_snapshot_name || old_name == _name) {
511 /* refuse to rename the current snapshot or the "main" one */
515 const string old_xml_path = _path + old_name + statefile_suffix;
516 const string new_xml_path = _path + new_name + statefile_suffix;
518 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
519 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
523 /** Remove a state file.
524 * @param snapshot_name Snapshot name.
527 Session::remove_state (string snapshot_name)
529 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
530 /* refuse to remove the current snapshot or the "main" one */
534 const string xml_path = _path + snapshot_name + statefile_suffix;
536 /* make a backup copy of the state file */
537 const string bak_path = xml_path + ".bak";
538 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
539 copy_file (xml_path, bak_path);
543 unlink (xml_path.c_str());
547 Session::save_state (string snapshot_name, bool pending)
553 if (_state_of_the_state & CannotSave) {
557 if (!_engine.connected ()) {
558 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
563 /* tell sources we're saving first, in case they write out to a new file
564 * which should be saved with the state rather than the old one */
565 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
566 i->second->session_saved();
568 tree.set_root (&get_state());
570 if (snapshot_name.empty()) {
571 snapshot_name = _current_snapshot_name;
576 /* proper save: use statefile_suffix (.ardour in English) */
578 xml_path += snapshot_name;
579 xml_path += statefile_suffix;
581 /* make a backup copy of the old file */
585 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
586 copy_file (xml_path, bak_path);
591 /* pending save: use pending_suffix (.pending in English) */
593 xml_path += snapshot_name;
594 xml_path += pending_suffix;
601 tmp_path += snapshot_name;
604 // cerr << "actually writing state to " << xml_path << endl;
606 if (!tree.write (tmp_path)) {
607 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
608 unlink (tmp_path.c_str());
613 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
614 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
615 unlink (tmp_path.c_str());
622 save_history (snapshot_name);
624 bool was_dirty = dirty();
626 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
629 DirtyChanged (); /* EMIT SIGNAL */
632 StateSaved (snapshot_name); /* EMIT SIGNAL */
639 Session::restore_state (string snapshot_name)
641 if (load_state (snapshot_name) == 0) {
642 set_state (*state_tree->root());
649 Session::load_state (string snapshot_name)
658 state_was_pending = false;
660 /* check for leftover pending state from a crashed capture attempt */
663 xmlpath += snapshot_name;
664 xmlpath += pending_suffix;
666 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
668 /* there is pending state from a crashed capture attempt */
670 if (AskAboutPendingState()) {
671 state_was_pending = true;
675 if (!state_was_pending) {
678 xmlpath += snapshot_name;
679 xmlpath += statefile_suffix;
682 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
683 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
687 state_tree = new XMLTree;
691 if (!state_tree->read (xmlpath)) {
692 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
698 XMLNode& root (*state_tree->root());
700 if (root.name() != X_("Session")) {
701 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
707 const XMLProperty* prop;
710 if ((prop = root.property ("version")) == 0) {
711 /* no version implies very old version of Ardour */
715 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
716 if (major_version < 2) {
725 backup_path += snapshot_name;
727 backup_path += statefile_suffix;
729 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
730 xmlpath, backup_path)
733 copy_file (xmlpath, backup_path);
735 /* if it fails, don't worry. right? */
742 Session::load_options (const XMLNode& node)
746 LocaleGuard lg (X_("POSIX"));
748 Config->set_variables (node, ConfigVariableBase::Session);
750 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
751 if ((prop = child->property ("val")) != 0) {
752 _end_location_is_free = (prop->value() == "yes");
760 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
762 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
763 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
765 return owner & modified_by_session_or_user;
769 Session::get_options () const
772 LocaleGuard lg (X_("POSIX"));
774 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
776 child = option_root.add_child ("end-marker-is-free");
777 child->add_property ("val", _end_location_is_free ? "yes" : "no");
789 Session::get_template()
791 /* if we don't disable rec-enable, diskstreams
792 will believe they need to store their capture
793 sources in their state node.
796 disable_record (false);
802 Session::state(bool full_state)
804 XMLNode* node = new XMLNode("Session");
807 // store libardour version, just in case
809 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
810 libardour_major_version, libardour_minor_version, libardour_micro_version);
811 node->add_property("version", string(buf));
813 /* store configuration settings */
818 node->add_property ("name", _name);
820 if (session_dirs.size() > 1) {
824 vector<space_and_path>::iterator i = session_dirs.begin();
825 vector<space_and_path>::iterator next;
827 ++i; /* skip the first one */
831 while (i != session_dirs.end()) {
835 if (next != session_dirs.end()) {
845 child = node->add_child ("Path");
846 child->add_content (p);
850 /* save the ID counter */
852 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
853 node->add_property ("id-counter", buf);
855 /* various options */
857 node->add_child_nocopy (get_options());
859 child = node->add_child ("Sources");
862 Glib::Mutex::Lock sl (source_lock);
864 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
866 /* Don't save information about AudioFileSources that are empty */
868 boost::shared_ptr<AudioFileSource> fs;
870 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
872 /* Don't save sources that are empty, unless they're destructive (which are OK
873 if they are empty, because we will re-use them every time.)
876 if (!fs->destructive()) {
877 if (fs->length() == 0) {
883 child->add_child_nocopy (siter->second->get_state());
887 child = node->add_child ("Regions");
890 Glib::Mutex::Lock rl (region_lock);
892 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
894 /* only store regions not attached to playlists */
896 if (i->second->playlist() == 0) {
897 child->add_child_nocopy (i->second->state (true));
902 child = node->add_child ("DiskStreams");
905 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
906 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
907 if (!(*i)->hidden()) {
908 child->add_child_nocopy ((*i)->get_state());
914 node->add_child_nocopy (_locations.get_state());
916 // for a template, just create a new Locations, populate it
917 // with the default start and end, and get the state for that.
919 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
920 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
923 end->set_end(compute_initial_length());
925 node->add_child_nocopy (loc.get_state());
928 child = node->add_child ("Connections");
930 Glib::Mutex::Lock lm (bundle_lock);
931 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
932 if (!(*i)->dynamic()) {
933 child->add_child_nocopy ((*i)->get_state());
938 child = node->add_child ("Routes");
940 boost::shared_ptr<RouteList> r = routes.reader ();
942 RoutePublicOrderSorter cmp;
943 RouteList public_order (*r);
944 public_order.sort (cmp);
946 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
947 if (!(*i)->is_hidden()) {
949 child->add_child_nocopy ((*i)->get_state());
951 child->add_child_nocopy ((*i)->get_template());
958 child = node->add_child ("EditGroups");
959 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
960 child->add_child_nocopy ((*i)->get_state());
963 child = node->add_child ("MixGroups");
964 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
965 child->add_child_nocopy ((*i)->get_state());
968 child = node->add_child ("Playlists");
969 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
970 if (!(*i)->hidden()) {
971 if (!(*i)->empty()) {
973 child->add_child_nocopy ((*i)->get_state());
975 child->add_child_nocopy ((*i)->get_template());
981 child = node->add_child ("UnusedPlaylists");
982 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
983 if (!(*i)->hidden()) {
984 if (!(*i)->empty()) {
986 child->add_child_nocopy ((*i)->get_state());
988 child->add_child_nocopy ((*i)->get_template());
996 child = node->add_child ("Click");
997 child->add_child_nocopy (_click_io->state (full_state));
1001 child = node->add_child ("NamedSelections");
1002 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1004 child->add_child_nocopy ((*i)->get_state());
1009 node->add_child_nocopy (_tempo_map->get_state());
1011 node->add_child_nocopy (get_control_protocol_state());
1014 node->add_child_copy (*_extra_xml);
1021 Session::get_control_protocol_state ()
1023 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1024 return cpm.get_state();
1028 Session::set_state (const XMLNode& node)
1032 const XMLProperty* prop;
1035 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1037 if (node.name() != X_("Session")){
1038 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1042 if ((prop = node.property ("name")) != 0) {
1043 _name = prop->value ();
1046 setup_raid_path(_path);
1048 if ((prop = node.property (X_("id-counter"))) != 0) {
1050 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1051 ID::init_counter (x);
1053 /* old sessions used a timebased counter, so fake
1054 the startup ID counter based on a standard
1059 ID::init_counter (now);
1063 IO::disable_ports ();
1064 IO::disable_connecting ();
1066 /* Object loading order:
1084 if (use_config_midi_ports ()) {
1087 if ((child = find_named_node (node, "extra")) != 0) {
1088 _extra_xml = new XMLNode (*child);
1091 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1092 load_options (*child);
1093 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1094 load_options (*child);
1096 error << _("Session: XML state has no options section") << endmsg;
1099 if ((child = find_named_node (node, "Locations")) == 0) {
1100 error << _("Session: XML state has no locations section") << endmsg;
1102 } else if (_locations.set_state (*child)) {
1108 if ((location = _locations.auto_loop_location()) != 0) {
1109 set_auto_loop_location (location);
1112 if ((location = _locations.auto_punch_location()) != 0) {
1113 set_auto_punch_location (location);
1116 if ((location = _locations.end_location()) == 0) {
1117 _locations.add (end_location);
1119 delete end_location;
1120 end_location = location;
1123 if ((location = _locations.start_location()) == 0) {
1124 _locations.add (start_location);
1126 delete start_location;
1127 start_location = location;
1130 AudioFileSource::set_header_position_offset (start_location->start());
1132 if ((child = find_named_node (node, "Sources")) == 0) {
1133 error << _("Session: XML state has no sources section") << endmsg;
1135 } else if (load_sources (*child)) {
1139 if ((child = find_named_node (node, "Regions")) == 0) {
1140 error << _("Session: XML state has no Regions section") << endmsg;
1142 } else if (load_regions (*child)) {
1146 if ((child = find_named_node (node, "Playlists")) == 0) {
1147 error << _("Session: XML state has no playlists section") << endmsg;
1149 } else if (load_playlists (*child)) {
1153 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1155 } else if (load_unused_playlists (*child)) {
1159 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1160 if (load_named_selections (*child)) {
1165 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1166 error << _("Session: XML state has no diskstreams section") << endmsg;
1168 } else if (load_diskstreams (*child)) {
1172 if ((child = find_named_node (node, "Connections")) == 0) {
1173 error << _("Session: XML state has no connections section") << endmsg;
1175 } else if (load_bundles (*child)) {
1179 if ((child = find_named_node (node, "EditGroups")) == 0) {
1180 error << _("Session: XML state has no edit groups section") << endmsg;
1182 } else if (load_edit_groups (*child)) {
1186 if ((child = find_named_node (node, "MixGroups")) == 0) {
1187 error << _("Session: XML state has no mix groups section") << endmsg;
1189 } else if (load_mix_groups (*child)) {
1193 if ((child = find_named_node (node, "TempoMap")) == 0) {
1194 error << _("Session: XML state has no Tempo Map section") << endmsg;
1196 } else if (_tempo_map->set_state (*child)) {
1200 if ((child = find_named_node (node, "Routes")) == 0) {
1201 error << _("Session: XML state has no routes section") << endmsg;
1203 } else if (load_routes (*child)) {
1207 if ((child = find_named_node (node, "Click")) == 0) {
1208 warning << _("Session: XML state has no click section") << endmsg;
1209 } else if (_click_io) {
1210 _click_io->set_state (*child);
1213 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1214 ControlProtocolManager::instance().set_protocol_states (*child);
1217 /* here beginneth the second phase ... */
1219 StateReady (); /* EMIT SIGNAL */
1221 _state_of_the_state = Clean;
1223 if (state_was_pending) {
1224 save_state (_current_snapshot_name);
1225 remove_pending_capture_state ();
1226 state_was_pending = false;
1236 Session::load_routes (const XMLNode& node)
1239 XMLNodeConstIterator niter;
1240 RouteList new_routes;
1242 nlist = node.children();
1246 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1248 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1251 error << _("Session: cannot create Route from XML description.") << endmsg;
1255 new_routes.push_back (route);
1258 add_routes (new_routes);
1263 boost::shared_ptr<Route>
1264 Session::XMLRouteFactory (const XMLNode& node)
1266 if (node.name() != "Route") {
1267 return boost::shared_ptr<Route> ((Route*) 0);
1270 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1272 DataType type = DataType::AUDIO;
1273 const XMLProperty* prop = node.property("default-type");
1275 type = DataType(prop->value());
1277 assert(type != DataType::NIL);
1279 if (has_diskstream) {
1280 if (type == DataType::AUDIO) {
1281 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1284 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1288 boost::shared_ptr<Route> ret (new Route (*this, node));
1294 Session::load_regions (const XMLNode& node)
1297 XMLNodeConstIterator niter;
1298 boost::shared_ptr<Region> region;
1300 nlist = node.children();
1304 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1305 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1306 error << _("Session: cannot create Region from XML description.") << endmsg;
1313 boost::shared_ptr<Region>
1314 Session::XMLRegionFactory (const XMLNode& node, bool full)
1316 const XMLProperty* type = node.property("type");
1320 if ( !type || type->value() == "audio" ) {
1322 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1324 } else if (type->value() == "midi") {
1326 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1330 } catch (failed_constructor& err) {
1331 return boost::shared_ptr<Region> ();
1334 return boost::shared_ptr<Region> ();
1337 boost::shared_ptr<AudioRegion>
1338 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1340 const XMLProperty* prop;
1341 boost::shared_ptr<Source> source;
1342 boost::shared_ptr<AudioSource> as;
1344 uint32_t nchans = 1;
1347 if (node.name() != X_("Region")) {
1348 return boost::shared_ptr<AudioRegion>();
1351 if ((prop = node.property (X_("channels"))) != 0) {
1352 nchans = atoi (prop->value().c_str());
1355 if ((prop = node.property ("name")) == 0) {
1356 cerr << "no name for this region\n";
1360 if ((prop = node.property (X_("source-0"))) == 0) {
1361 if ((prop = node.property ("source")) == 0) {
1362 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1363 return boost::shared_ptr<AudioRegion>();
1367 PBD::ID s_id (prop->value());
1369 if ((source = source_by_id (s_id)) == 0) {
1370 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1371 return boost::shared_ptr<AudioRegion>();
1374 as = boost::dynamic_pointer_cast<AudioSource>(source);
1376 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1377 return boost::shared_ptr<AudioRegion>();
1380 sources.push_back (as);
1382 /* pickup other channels */
1384 for (uint32_t n=1; n < nchans; ++n) {
1385 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1386 if ((prop = node.property (buf)) != 0) {
1388 PBD::ID id2 (prop->value());
1390 if ((source = source_by_id (id2)) == 0) {
1391 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1392 return boost::shared_ptr<AudioRegion>();
1395 as = boost::dynamic_pointer_cast<AudioSource>(source);
1397 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1398 return boost::shared_ptr<AudioRegion>();
1400 sources.push_back (as);
1405 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1407 /* a final detail: this is the one and only place that we know how long missing files are */
1409 if (region->whole_file()) {
1410 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1411 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1413 sfp->set_length (region->length());
1422 catch (failed_constructor& err) {
1423 return boost::shared_ptr<AudioRegion>();
1427 boost::shared_ptr<MidiRegion>
1428 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1430 const XMLProperty* prop;
1431 boost::shared_ptr<Source> source;
1432 boost::shared_ptr<MidiSource> ms;
1434 uint32_t nchans = 1;
1436 if (node.name() != X_("Region")) {
1437 return boost::shared_ptr<MidiRegion>();
1440 if ((prop = node.property (X_("channels"))) != 0) {
1441 nchans = atoi (prop->value().c_str());
1444 if ((prop = node.property ("name")) == 0) {
1445 cerr << "no name for this region\n";
1449 // Multiple midi channels? that's just crazy talk
1450 assert(nchans == 1);
1452 if ((prop = node.property (X_("source-0"))) == 0) {
1453 if ((prop = node.property ("source")) == 0) {
1454 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1455 return boost::shared_ptr<MidiRegion>();
1459 PBD::ID s_id (prop->value());
1461 if ((source = source_by_id (s_id)) == 0) {
1462 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1463 return boost::shared_ptr<MidiRegion>();
1466 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1468 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1469 return boost::shared_ptr<MidiRegion>();
1472 sources.push_back (ms);
1475 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1476 /* a final detail: this is the one and only place that we know how long missing files are */
1478 if (region->whole_file()) {
1479 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1480 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1482 sfp->set_length (region->length());
1490 catch (failed_constructor& err) {
1491 return boost::shared_ptr<MidiRegion>();
1496 Session::get_sources_as_xml ()
1499 XMLNode* node = new XMLNode (X_("Sources"));
1500 Glib::Mutex::Lock lm (source_lock);
1502 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1503 node->add_child_nocopy (i->second->get_state());
1510 Session::path_from_region_name (DataType type, string name, string identifier)
1512 char buf[PATH_MAX+1];
1514 SessionDirectory sdir(get_best_session_directory_for_new_source());
1515 string sound_dir = ((type == DataType::AUDIO)
1516 ? sdir.sound_path().to_string()
1517 : sdir.midi_path().to_string());
1519 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1521 for (n = 0; n < 999999; ++n) {
1522 if (identifier.length()) {
1523 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1524 identifier.c_str(), n, ext.c_str());
1526 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1530 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1535 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1544 Session::load_sources (const XMLNode& node)
1547 XMLNodeConstIterator niter;
1548 boost::shared_ptr<Source> source;
1550 nlist = node.children();
1554 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1557 if ((source = XMLSourceFactory (**niter)) == 0) {
1558 error << _("Session: cannot create Source from XML description.") << endmsg;
1562 catch (non_existent_source& err) {
1563 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1564 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1571 boost::shared_ptr<Source>
1572 Session::XMLSourceFactory (const XMLNode& node)
1574 if (node.name() != "Source") {
1575 return boost::shared_ptr<Source>();
1579 return SourceFactory::create (*this, node);
1582 catch (failed_constructor& err) {
1583 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1584 return boost::shared_ptr<Source>();
1589 Session::save_template (string template_name)
1592 string xml_path, bak_path, template_path;
1594 if (_state_of_the_state & CannotSave) {
1598 sys::path user_template_dir(user_template_directory());
1602 sys::create_directories (user_template_dir);
1604 catch(sys::filesystem_error& ex)
1606 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1607 user_template_dir.to_string(), ex.what()) << endmsg;
1611 tree.set_root (&get_template());
1613 sys::path template_file_path(user_template_dir);
1614 template_file_path /= template_name + template_suffix;
1616 if (sys::exists (template_file_path))
1618 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1619 template_file_path.to_string()) << endmsg;
1623 if (!tree.write (template_file_path.to_string())) {
1624 error << _("mix template not saved") << endmsg;
1632 Session::refresh_disk_space ()
1635 struct statfs statfsbuf;
1636 vector<space_and_path>::iterator i;
1637 Glib::Mutex::Lock lm (space_lock);
1640 /* get freespace on every FS that is part of the session path */
1642 _total_free_4k_blocks = 0;
1644 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1645 statfs ((*i).path.c_str(), &statfsbuf);
1647 scale = statfsbuf.f_bsize/4096.0;
1649 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1650 _total_free_4k_blocks += (*i).blocks;
1656 Session::get_best_session_directory_for_new_source ()
1658 vector<space_and_path>::iterator i;
1659 string result = _session_dir->root_path().to_string();
1661 /* handle common case without system calls */
1663 if (session_dirs.size() == 1) {
1667 /* OK, here's the algorithm we're following here:
1669 We want to select which directory to use for
1670 the next file source to be created. Ideally,
1671 we'd like to use a round-robin process so as to
1672 get maximum performance benefits from splitting
1673 the files across multiple disks.
1675 However, in situations without much diskspace, an
1676 RR approach may end up filling up a filesystem
1677 with new files while others still have space.
1678 Its therefore important to pay some attention to
1679 the freespace in the filesystem holding each
1680 directory as well. However, if we did that by
1681 itself, we'd keep creating new files in the file
1682 system with the most space until it was as full
1683 as all others, thus negating any performance
1684 benefits of this RAID-1 like approach.
1686 So, we use a user-configurable space threshold. If
1687 there are at least 2 filesystems with more than this
1688 much space available, we use RR selection between them.
1689 If not, then we pick the filesystem with the most space.
1691 This gets a good balance between the two
1695 refresh_disk_space ();
1697 int free_enough = 0;
1699 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1700 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1705 if (free_enough >= 2) {
1706 /* use RR selection process, ensuring that the one
1710 i = last_rr_session_dir;
1713 if (++i == session_dirs.end()) {
1714 i = session_dirs.begin();
1717 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1718 if (create_session_directory ((*i).path)) {
1720 last_rr_session_dir = i;
1725 } while (i != last_rr_session_dir);
1729 /* pick FS with the most freespace (and that
1730 seems to actually work ...)
1733 vector<space_and_path> sorted;
1734 space_and_path_ascending_cmp cmp;
1736 sorted = session_dirs;
1737 sort (sorted.begin(), sorted.end(), cmp);
1739 for (i = sorted.begin(); i != sorted.end(); ++i) {
1740 if (create_session_directory ((*i).path)) {
1742 last_rr_session_dir = i;
1752 Session::load_playlists (const XMLNode& node)
1755 XMLNodeConstIterator niter;
1756 boost::shared_ptr<Playlist> playlist;
1758 nlist = node.children();
1762 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1764 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1765 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1773 Session::load_unused_playlists (const XMLNode& node)
1776 XMLNodeConstIterator niter;
1777 boost::shared_ptr<Playlist> playlist;
1779 nlist = node.children();
1783 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1785 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1786 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1790 // now manually untrack it
1792 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1798 boost::shared_ptr<Playlist>
1799 Session::XMLPlaylistFactory (const XMLNode& node)
1802 return PlaylistFactory::create (*this, node);
1805 catch (failed_constructor& err) {
1806 return boost::shared_ptr<Playlist>();
1811 Session::load_named_selections (const XMLNode& node)
1814 XMLNodeConstIterator niter;
1817 nlist = node.children();
1821 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1823 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1824 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1832 Session::XMLNamedSelectionFactory (const XMLNode& node)
1835 return new NamedSelection (*this, node);
1838 catch (failed_constructor& err) {
1844 Session::automation_dir () const
1847 res += "automation/";
1852 Session::load_bundles (const XMLNode& node)
1854 XMLNodeList nlist = node.children();
1855 XMLNodeConstIterator niter;
1859 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1860 if ((*niter)->name() == "InputConnection") {
1861 add_bundle (new ARDOUR::InputBundle (**niter));
1862 } else if ((*niter)->name() == "OutputConnection") {
1863 add_bundle (new ARDOUR::OutputBundle (**niter));
1865 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1874 Session::load_edit_groups (const XMLNode& node)
1876 return load_route_groups (node, true);
1880 Session::load_mix_groups (const XMLNode& node)
1882 return load_route_groups (node, false);
1886 Session::load_route_groups (const XMLNode& node, bool edit)
1888 XMLNodeList nlist = node.children();
1889 XMLNodeConstIterator niter;
1894 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1895 if ((*niter)->name() == "RouteGroup") {
1897 rg = add_edit_group ("");
1898 rg->set_state (**niter);
1900 rg = add_mix_group ("");
1901 rg->set_state (**niter);
1910 state_file_filter (const string &str, void *arg)
1912 return (str.length() > strlen(statefile_suffix) &&
1913 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
1917 bool operator()(const string* a, const string* b) {
1923 remove_end(string* state)
1925 string statename(*state);
1927 string::size_type start,end;
1928 if ((start = statename.find_last_of ('/')) != string::npos) {
1929 statename = statename.substr (start+1);
1932 if ((end = statename.rfind(".ardour")) == string::npos) {
1933 end = statename.length();
1936 return new string(statename.substr (0, end));
1940 Session::possible_states (string path)
1942 PathScanner scanner;
1943 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
1945 transform(states->begin(), states->end(), states->begin(), remove_end);
1948 sort (states->begin(), states->end(), cmp);
1954 Session::possible_states () const
1956 return possible_states(_path);
1960 Session::auto_save()
1962 save_state (_current_snapshot_name);
1966 Session::add_edit_group (string name)
1968 RouteGroup* rg = new RouteGroup (*this, name);
1969 edit_groups.push_back (rg);
1970 edit_group_added (rg); /* EMIT SIGNAL */
1976 Session::add_mix_group (string name)
1978 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
1979 mix_groups.push_back (rg);
1980 mix_group_added (rg); /* EMIT SIGNAL */
1986 Session::remove_edit_group (RouteGroup& rg)
1988 list<RouteGroup*>::iterator i;
1990 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
1991 (*i)->apply (&Route::drop_edit_group, this);
1992 edit_groups.erase (i);
1993 edit_group_removed (); /* EMIT SIGNAL */
2000 Session::remove_mix_group (RouteGroup& rg)
2002 list<RouteGroup*>::iterator i;
2004 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2005 (*i)->apply (&Route::drop_mix_group, this);
2006 mix_groups.erase (i);
2007 mix_group_removed (); /* EMIT SIGNAL */
2014 Session::mix_group_by_name (string name)
2016 list<RouteGroup *>::iterator i;
2018 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2019 if ((*i)->name() == name) {
2027 Session::edit_group_by_name (string name)
2029 list<RouteGroup *>::iterator i;
2031 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2032 if ((*i)->name() == name) {
2040 Session::begin_reversible_command (const string& name)
2042 current_trans = new UndoTransaction;
2043 current_trans->set_name (name);
2047 Session::commit_reversible_command (Command *cmd)
2052 current_trans->add_command (cmd);
2055 gettimeofday (&now, 0);
2056 current_trans->set_timestamp (now);
2058 _history.add (current_trans);
2061 Session::GlobalRouteBooleanState
2062 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2064 GlobalRouteBooleanState s;
2065 boost::shared_ptr<RouteList> r = routes.reader ();
2067 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2068 if (!(*i)->is_hidden()) {
2069 RouteBooleanState v;
2072 Route* r = (*i).get();
2073 v.second = (r->*method)();
2082 Session::GlobalRouteMeterState
2083 Session::get_global_route_metering ()
2085 GlobalRouteMeterState s;
2086 boost::shared_ptr<RouteList> r = routes.reader ();
2088 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2089 if (!(*i)->is_hidden()) {
2093 v.second = (*i)->meter_point();
2103 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2105 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2107 boost::shared_ptr<Route> r = (i->first.lock());
2110 r->set_meter_point (i->second, arg);
2116 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2118 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2120 boost::shared_ptr<Route> r = (i->first.lock());
2123 Route* rp = r.get();
2124 (rp->*method) (i->second, arg);
2130 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2132 set_global_route_boolean (s, &Route::set_mute, src);
2136 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2138 set_global_route_boolean (s, &Route::set_solo, src);
2142 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2144 set_global_route_boolean (s, &Route::set_record_enable, src);
2149 Session::global_mute_memento (void* src)
2151 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2155 Session::global_metering_memento (void* src)
2157 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2161 Session::global_solo_memento (void* src)
2163 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2167 Session::global_record_enable_memento (void* src)
2169 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2174 accept_all_non_peak_files (const string& path, void *arg)
2176 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2180 accept_all_state_files (const string& path, void *arg)
2182 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2186 Session::find_all_sources (string path, set<string>& result)
2191 if (!tree.read (path)) {
2195 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2200 XMLNodeConstIterator niter;
2202 nlist = node->children();
2206 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2210 if ((prop = (*niter)->property (X_("name"))) == 0) {
2214 if (prop->value()[0] == '/') {
2215 /* external file, ignore */
2219 sys::path source_path = _session_dir->sound_path ();
2221 source_path /= prop->value ();
2223 result.insert (source_path.to_string ());
2230 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2232 PathScanner scanner;
2233 vector<string*>* state_files;
2235 string this_snapshot_path;
2241 if (ripped[ripped.length()-1] == '/') {
2242 ripped = ripped.substr (0, ripped.length() - 1);
2245 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2247 if (state_files == 0) {
2252 this_snapshot_path = _path;
2253 this_snapshot_path += _current_snapshot_name;
2254 this_snapshot_path += statefile_suffix;
2256 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2258 if (exclude_this_snapshot && **i == this_snapshot_path) {
2262 if (find_all_sources (**i, result) < 0) {
2270 struct RegionCounter {
2271 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2272 AudioSourceList::iterator iter;
2273 boost::shared_ptr<Region> region;
2276 RegionCounter() : count (0) {}
2280 Session::cleanup_sources (Session::cleanup_report& rep)
2282 // FIXME: needs adaptation to midi
2284 vector<boost::shared_ptr<Source> > dead_sources;
2285 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2286 PathScanner scanner;
2288 vector<space_and_path>::iterator i;
2289 vector<space_and_path>::iterator nexti;
2290 vector<string*>* soundfiles;
2291 vector<string> unused;
2292 set<string> all_sources;
2297 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2299 /* step 1: consider deleting all unused playlists */
2301 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2304 status = AskAboutPlaylistDeletion (*x);
2313 playlists_tbd.push_back (*x);
2317 /* leave it alone */
2322 /* now delete any that were marked for deletion */
2324 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2325 (*x)->drop_references ();
2328 playlists_tbd.clear ();
2330 /* step 2: find all un-used sources */
2335 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2337 SourceMap::iterator tmp;
2342 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2346 if (!i->second->used() && i->second->length() > 0) {
2347 dead_sources.push_back (i->second);
2348 i->second->GoingAway();
2354 /* build a list of all the possible sound directories for the session */
2356 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2361 SessionDirectory sdir ((*i).path);
2362 sound_path += sdir.sound_path().to_string();
2364 if (nexti != session_dirs.end()) {
2371 /* now do the same thing for the files that ended up in the sounds dir(s)
2372 but are not referenced as sources in any snapshot.
2375 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2377 if (soundfiles == 0) {
2381 /* find all sources, but don't use this snapshot because the
2382 state file on disk still references sources we may have already
2386 find_all_sources_across_snapshots (all_sources, true);
2388 /* add our current source list
2391 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2392 boost::shared_ptr<AudioFileSource> fs;
2394 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2395 all_sources.insert (fs->path());
2399 char tmppath1[PATH_MAX+1];
2400 char tmppath2[PATH_MAX+1];
2402 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2407 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2409 realpath(spath.c_str(), tmppath1);
2410 realpath((*i).c_str(), tmppath2);
2412 if (strcmp(tmppath1, tmppath2) == 0) {
2419 unused.push_back (spath);
2423 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2425 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2426 struct stat statbuf;
2428 rep.paths.push_back (*x);
2429 if (stat ((*x).c_str(), &statbuf) == 0) {
2430 rep.space += statbuf.st_size;
2435 /* don't move the file across filesystems, just
2436 stick it in the `dead_sound_dir_name' directory
2437 on whichever filesystem it was already on.
2440 if ((*x).find ("/sounds/") != string::npos) {
2442 /* old school, go up 1 level */
2444 newpath = Glib::path_get_dirname (*x); // "sounds"
2445 newpath = Glib::path_get_dirname (newpath); // "session-name"
2449 /* new school, go up 4 levels */
2451 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2452 newpath = Glib::path_get_dirname (newpath); // "session-name"
2453 newpath = Glib::path_get_dirname (newpath); // "interchange"
2454 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2458 newpath += dead_sound_dir_name;
2460 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2461 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2466 newpath += Glib::path_get_basename ((*x));
2468 if (access (newpath.c_str(), F_OK) == 0) {
2470 /* the new path already exists, try versioning */
2472 char buf[PATH_MAX+1];
2476 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2479 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2480 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2484 if (version == 999) {
2485 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2489 newpath = newpath_v;
2494 /* it doesn't exist, or we can't read it or something */
2498 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2499 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2500 (*x), newpath, strerror (errno))
2505 /* see if there an easy to find peakfile for this file, and remove it.
2508 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2509 peakpath += peakfile_suffix;
2511 if (access (peakpath.c_str(), W_OK) == 0) {
2512 if (::unlink (peakpath.c_str()) != 0) {
2513 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2514 peakpath, _path, strerror (errno))
2516 /* try to back out */
2517 rename (newpath.c_str(), _path.c_str());
2525 /* dump the history list */
2529 /* save state so we don't end up a session file
2530 referring to non-existent sources.
2536 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2541 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2543 // FIXME: needs adaptation for MIDI
2545 vector<space_and_path>::iterator i;
2546 string dead_sound_dir;
2547 struct dirent* dentry;
2548 struct stat statbuf;
2554 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2556 dead_sound_dir = (*i).path;
2557 dead_sound_dir += dead_sound_dir_name;
2559 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2563 while ((dentry = readdir (dead)) != 0) {
2565 /* avoid '.' and '..' */
2567 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2568 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2574 fullpath = dead_sound_dir;
2576 fullpath += dentry->d_name;
2578 if (stat (fullpath.c_str(), &statbuf)) {
2582 if (!S_ISREG (statbuf.st_mode)) {
2586 if (unlink (fullpath.c_str())) {
2587 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2588 fullpath, strerror (errno))
2592 rep.paths.push_back (dentry->d_name);
2593 rep.space += statbuf.st_size;
2604 Session::set_dirty ()
2606 bool was_dirty = dirty();
2608 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2611 DirtyChanged(); /* EMIT SIGNAL */
2617 Session::set_clean ()
2619 bool was_dirty = dirty();
2621 _state_of_the_state = Clean;
2624 DirtyChanged(); /* EMIT SIGNAL */
2629 Session::set_deletion_in_progress ()
2631 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2635 Session::add_controllable (boost::shared_ptr<Controllable> c)
2637 /* this adds a controllable to the list managed by the Session.
2638 this is a subset of those managed by the Controllable class
2639 itself, and represents the only ones whose state will be saved
2640 as part of the session.
2643 Glib::Mutex::Lock lm (controllables_lock);
2644 controllables.insert (c);
2647 struct null_deleter { void operator()(void const *) const {} };
2650 Session::remove_controllable (Controllable* c)
2652 if (_state_of_the_state | Deletion) {
2656 Glib::Mutex::Lock lm (controllables_lock);
2658 Controllables::iterator x = controllables.find(
2659 boost::shared_ptr<Controllable>(c, null_deleter()));
2661 if (x != controllables.end()) {
2662 controllables.erase (x);
2666 boost::shared_ptr<Controllable>
2667 Session::controllable_by_id (const PBD::ID& id)
2669 Glib::Mutex::Lock lm (controllables_lock);
2671 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2672 if ((*i)->id() == id) {
2677 return boost::shared_ptr<Controllable>();
2681 Session::add_instant_xml (XMLNode& node)
2683 Stateful::add_instant_xml (node, _path);
2684 Config->add_instant_xml (node);
2688 Session::instant_xml (const string& node_name)
2690 return Stateful::instant_xml (node_name, _path);
2694 Session::save_history (string snapshot_name)
2700 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2702 if (snapshot_name.empty()) {
2703 snapshot_name = _current_snapshot_name;
2706 xml_path = _path + snapshot_name + ".history";
2708 bak_path = xml_path + ".bak";
2710 if ((access (xml_path.c_str(), F_OK) == 0) &&
2711 (rename (xml_path.c_str(), bak_path.c_str())))
2713 error << _("could not backup old history file, current history not saved.") << endmsg;
2717 if (!tree.write (xml_path))
2719 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2721 /* don't leave a corrupt file lying around if it is
2725 if (unlink (xml_path.c_str())) {
2726 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2728 if (rename (bak_path.c_str(), xml_path.c_str()))
2730 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2741 Session::restore_history (string snapshot_name)
2746 if (snapshot_name.empty()) {
2747 snapshot_name = _current_snapshot_name;
2751 xmlpath = _path + snapshot_name + ".history";
2752 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2754 if (access (xmlpath.c_str(), F_OK)) {
2755 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2759 if (!tree.read (xmlpath)) {
2760 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2764 /* replace history */
2767 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2770 UndoTransaction* ut = new UndoTransaction ();
2773 ut->set_name(t->property("name")->value());
2774 stringstream ss(t->property("tv_sec")->value());
2776 ss.str(t->property("tv_usec")->value());
2778 ut->set_timestamp(tv);
2780 for (XMLNodeConstIterator child_it = t->children().begin();
2781 child_it != t->children().end();
2784 XMLNode *n = *child_it;
2787 if (n->name() == "MementoCommand" ||
2788 n->name() == "MementoUndoCommand" ||
2789 n->name() == "MementoRedoCommand") {
2791 if ((c = memento_command_factory(n))) {
2795 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2797 if ((c = global_state_command_factory (*n))) {
2798 ut->add_command (c);
2803 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2814 Session::config_changed (const char* parameter_name)
2816 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2818 if (PARAM_IS ("seamless-loop")) {
2820 } else if (PARAM_IS ("rf-speed")) {
2822 } else if (PARAM_IS ("auto-loop")) {
2824 } else if (PARAM_IS ("auto-input")) {
2826 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2827 /* auto-input only makes a difference if we're rolling */
2829 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2831 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2832 if ((*i)->record_enabled ()) {
2833 (*i)->monitor_input (!Config->get_auto_input());
2838 } else if (PARAM_IS ("punch-in")) {
2842 if ((location = _locations.auto_punch_location()) != 0) {
2844 if (Config->get_punch_in ()) {
2845 replace_event (Event::PunchIn, location->start());
2847 remove_event (location->start(), Event::PunchIn);
2851 } else if (PARAM_IS ("punch-out")) {
2855 if ((location = _locations.auto_punch_location()) != 0) {
2857 if (Config->get_punch_out()) {
2858 replace_event (Event::PunchOut, location->end());
2860 clear_events (Event::PunchOut);
2864 } else if (PARAM_IS ("edit-mode")) {
2866 Glib::Mutex::Lock lm (playlist_lock);
2868 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2869 (*i)->set_edit_mode (Config->get_edit_mode ());
2872 } else if (PARAM_IS ("use-video-sync")) {
2874 waiting_for_sync_offset = Config->get_use_video_sync();
2876 } else if (PARAM_IS ("mmc-control")) {
2878 //poke_midi_thread ();
2880 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
2883 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
2886 } else if (PARAM_IS ("mmc-send-id")) {
2889 mmc->set_send_device_id (Config->get_mmc_send_device_id());
2892 } else if (PARAM_IS ("midi-control")) {
2894 //poke_midi_thread ();
2896 } else if (PARAM_IS ("raid-path")) {
2898 setup_raid_path (Config->get_raid_path());
2900 } else if (PARAM_IS ("smpte-format")) {
2904 } else if (PARAM_IS ("video-pullup")) {
2908 } else if (PARAM_IS ("seamless-loop")) {
2910 if (play_loop && transport_rolling()) {
2911 // to reset diskstreams etc
2912 request_play_loop (true);
2915 } else if (PARAM_IS ("rf-speed")) {
2917 cumulative_rf_motion = 0;
2920 } else if (PARAM_IS ("click-sound")) {
2922 setup_click_sounds (1);
2924 } else if (PARAM_IS ("click-emphasis-sound")) {
2926 setup_click_sounds (-1);
2928 } else if (PARAM_IS ("clicking")) {
2930 if (Config->get_clicking()) {
2931 if (_click_io && click_data) { // don't require emphasis data
2938 } else if (PARAM_IS ("send-mtc")) {
2940 /* only set the internal flag if we have
2944 if (_mtc_port != 0) {
2945 session_send_mtc = Config->get_send_mtc();
2946 if (session_send_mtc) {
2947 /* mark us ready to send */
2948 next_quarter_frame_to_send = 0;
2951 session_send_mtc = false;
2954 } else if (PARAM_IS ("send-mmc")) {
2956 /* only set the internal flag if we have
2960 if (_mmc_port != 0) {
2961 session_send_mmc = Config->get_send_mmc();
2964 session_send_mmc = false;
2967 } else if (PARAM_IS ("midi-feedback")) {
2969 /* only set the internal flag if we have
2973 if (_mtc_port != 0) {
2974 session_midi_feedback = Config->get_midi_feedback();
2977 } else if (PARAM_IS ("jack-time-master")) {
2979 engine().reset_timebase ();
2981 } else if (PARAM_IS ("native-file-header-format")) {
2983 if (!first_file_header_format_reset) {
2984 reset_native_file_format ();
2987 first_file_header_format_reset = false;
2989 } else if (PARAM_IS ("native-file-data-format")) {
2991 if (!first_file_data_format_reset) {
2992 reset_native_file_format ();
2995 first_file_data_format_reset = false;
2997 } else if (PARAM_IS ("slave-source")) {
2998 set_slave_source (Config->get_slave_source());
2999 } else if (PARAM_IS ("remote-model")) {
3000 set_remote_control_ids ();
3001 } else if (PARAM_IS ("denormal-model")) {