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>
50 #include <glibmm/thread.h>
52 #include <midi++/mmc.h>
53 #include <midi++/port.h>
55 #include <pbd/error.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);
184 butler_mixdown_buffer = 0;
185 butler_gain_buffer = 0;
187 session_send_mmc = false;
188 session_send_mtc = false;
189 post_transport_work = PostTransportWork (0);
190 g_atomic_int_set (&butler_should_do_transport_work, 0);
191 g_atomic_int_set (&butler_active, 0);
192 g_atomic_int_set (&_playback_load, 100);
193 g_atomic_int_set (&_capture_load, 100);
194 g_atomic_int_set (&_playback_load_min, 100);
195 g_atomic_int_set (&_capture_load_min, 100);
197 waiting_to_start = false;
199 _gain_automation_buffer = 0;
200 _pan_automation_buffer = 0;
202 pending_abort = false;
203 destructive_index = 0;
205 first_file_data_format_reset = true;
206 first_file_header_format_reset = true;
207 butler_thread = (pthread_t) 0;
208 //midi_thread = (pthread_t) 0;
210 AudioDiskstream::allocate_working_buffers();
212 /* default short fade = 15ms */
214 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
215 SndFileSource::setup_standard_crossfades (frame_rate());
217 last_mmc_step.tv_sec = 0;
218 last_mmc_step.tv_usec = 0;
221 /* click sounds are unset by default, which causes us to internal
222 waveforms for clicks.
226 click_emphasis_data = 0;
228 click_emphasis_length = 0;
231 process_function = &Session::process_with_events;
233 if (Config->get_use_video_sync()) {
234 waiting_for_sync_offset = true;
236 waiting_for_sync_offset = false;
239 _current_frame_rate = 48000;
240 _base_frame_rate = 48000;
244 _smpte_offset_negative = true;
245 last_smpte_valid = false;
249 last_rr_session_dir = session_dirs.begin();
250 refresh_disk_space ();
252 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
256 average_slave_delta = 1800;
257 have_first_delta_accumulator = false;
258 delta_accumulator_cnt = 0;
259 slave_state = Stopped;
261 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
263 /* These are all static "per-class" signals */
265 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
266 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
267 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
268 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
269 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
270 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
272 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
274 IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
276 /* stop IO objects from doing stuff until we're ready for them */
278 IO::disable_panners ();
279 IO::disable_ports ();
280 IO::disable_connecting ();
284 Session::second_stage_init (bool new_session)
286 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
289 if (load_state (_current_snapshot_name)) {
292 remove_empty_sounds ();
295 if (start_butler_thread()) {
299 /*if (start_midi_thread ()) {
303 // set_state() will call setup_raid_path(), but if it's a new session we need
304 // to call setup_raid_path() here.
307 if (set_state (*state_tree->root())) {
311 setup_raid_path(_path);
314 /* we can't save till after ::when_engine_running() is called,
315 because otherwise we save state with no connections made.
316 therefore, we reset _state_of_the_state because ::set_state()
317 will have cleared it.
319 we also have to include Loading so that any events that get
320 generated between here and the end of ::when_engine_running()
321 will be processed directly rather than queued.
324 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
327 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
328 _locations.added.connect (mem_fun (this, &Session::locations_added));
329 setup_click_sounds (0);
330 setup_midi_control ();
332 /* Pay attention ... */
334 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
335 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
338 when_engine_running();
341 /* handle this one in a different way than all others, so that its clear what happened */
343 catch (AudioEngine::PortRegistrationFailure& err) {
344 error << _("Unable to create all required ports")
353 //send_full_time_code ();
354 _engine.transport_locate (0);
355 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
356 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
358 ControlProtocolManager::instance().set_session (*this);
361 _end_location_is_free = true;
363 _end_location_is_free = false;
366 _state_of_the_state = Clean;
369 DirtyChanged (); /* EMIT SIGNAL */
371 if (state_was_pending) {
372 save_state (_current_snapshot_name);
373 remove_pending_capture_state ();
374 state_was_pending = false;
381 Session::raid_path () const
383 SearchPath raid_search_path;
385 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
386 raid_search_path += sys::path((*i).path);
389 return raid_search_path.to_string ();
393 Session::setup_raid_path (string path)
402 session_dirs.clear ();
404 SearchPath search_path(path);
405 SearchPath sound_search_path;
406 SearchPath midi_search_path;
409 SearchPath::const_iterator i = search_path.begin();
410 i != search_path.end();
414 sp.path = (*i).to_string ();
415 sp.blocks = 0; // not needed
416 session_dirs.push_back (sp);
418 SessionDirectory sdir(sp.path);
420 sound_search_path += sdir.sound_path ();
421 midi_search_path += sdir.midi_path ();
424 // set the AudioFileSource and SMFSource search path
426 AudioFileSource::set_search_path (sound_search_path.to_string ());
427 SMFSource::set_search_path (midi_search_path.to_string ());
429 // reset the round-robin soundfile path thingie
431 last_rr_session_dir = session_dirs.begin();
435 Session::ensure_subdirs ()
439 dir = session_directory().peak_path().to_string();
441 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
442 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
446 dir = session_directory().sound_path().to_string();
448 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
449 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
453 dir = session_directory().midi_path().to_string();
455 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
456 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
460 dir = session_directory().dead_sound_path().to_string();
462 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
463 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
467 dir = session_directory().export_path().to_string();
469 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
470 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
474 dir = analysis_dir ();
476 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
477 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
485 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
488 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
489 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
493 if (ensure_subdirs ()) {
497 /* check new_session so we don't overwrite an existing one */
499 if (!mix_template.empty()) {
500 std::string in_path = mix_template;
502 ifstream in(in_path.c_str());
505 string out_path = _path;
507 out_path += statefile_suffix;
509 ofstream out(out_path.c_str());
514 // okay, session is set up. Treat like normal saved
515 // session from now on.
521 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
527 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
534 /* set initial start + end point */
536 start_location->set_end (0);
537 _locations.add (start_location);
539 end_location->set_end (initial_length);
540 _locations.add (end_location);
542 _state_of_the_state = Clean;
551 Session::load_diskstreams (const XMLNode& node)
554 XMLNodeConstIterator citer;
556 clist = node.children();
558 for (citer = clist.begin(); citer != clist.end(); ++citer) {
561 /* diskstreams added automatically by DiskstreamCreated handler */
562 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
563 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
564 add_diskstream (dstream);
565 } else if ((*citer)->name() == "MidiDiskstream") {
566 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
567 add_diskstream (dstream);
569 error << _("Session: unknown diskstream type in XML") << endmsg;
573 catch (failed_constructor& err) {
574 error << _("Session: could not load diskstream via XML state") << endmsg;
583 Session::maybe_write_autosave()
585 if (dirty() && record_status() != Recording) {
586 save_state("", true);
591 Session::remove_pending_capture_state ()
593 sys::path pending_state_file_path(_session_dir->root_path());
595 pending_state_file_path /= _current_snapshot_name + pending_suffix;
599 sys::remove (pending_state_file_path);
601 catch(sys::filesystem_error& ex)
603 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
604 pending_state_file_path.to_string(), ex.what()) << endmsg;
608 /** Rename a state file.
609 * @param snapshot_name Snapshot name.
612 Session::rename_state (string old_name, string new_name)
614 if (old_name == _current_snapshot_name || old_name == _name) {
615 /* refuse to rename the current snapshot or the "main" one */
619 const string old_xml_filename = old_name + statefile_suffix;
620 const string new_xml_filename = new_name + statefile_suffix;
622 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
623 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
627 sys::rename (old_xml_path, new_xml_path);
629 catch (const sys::filesystem_error& err)
631 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
632 old_name, new_name, err.what()) << endmsg;
636 /** Remove a state file.
637 * @param snapshot_name Snapshot name.
640 Session::remove_state (string snapshot_name)
642 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
643 // refuse to remove the current snapshot or the "main" one
647 sys::path xml_path(_session_dir->root_path());
649 xml_path /= snapshot_name + statefile_suffix;
651 if (!create_backup_file (xml_path)) {
652 // don't remove it if a backup can't be made
653 // create_backup_file will log the error.
658 sys::remove (xml_path);
662 Session::save_state (string snapshot_name, bool pending)
665 sys::path xml_path(_session_dir->root_path());
667 if (_state_of_the_state & CannotSave) {
671 if (!_engine.connected ()) {
672 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
677 /* tell sources we're saving first, in case they write out to a new file
678 * which should be saved with the state rather than the old one */
679 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
680 i->second->session_saved();
682 tree.set_root (&get_state());
684 if (snapshot_name.empty()) {
685 snapshot_name = _current_snapshot_name;
690 /* proper save: use statefile_suffix (.ardour in English) */
692 xml_path /= snapshot_name + statefile_suffix;
694 /* make a backup copy of the old file */
696 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
697 // create_backup_file will log the error
703 /* pending save: use pending_suffix (.pending in English) */
704 xml_path /= snapshot_name + pending_suffix;
707 sys::path tmp_path(_session_dir->root_path());
709 tmp_path /= snapshot_name + temp_suffix;
711 // cerr << "actually writing state to " << xml_path.to_string() << endl;
713 if (!tree.write (tmp_path.to_string())) {
714 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
715 sys::remove (tmp_path);
720 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
721 error << string_compose (_("could not rename temporary session file %1 to %2"),
722 tmp_path.to_string(), xml_path.to_string()) << endmsg;
723 sys::remove (tmp_path);
730 save_history (snapshot_name);
732 bool was_dirty = dirty();
734 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
737 DirtyChanged (); /* EMIT SIGNAL */
740 StateSaved (snapshot_name); /* EMIT SIGNAL */
747 Session::restore_state (string snapshot_name)
749 if (load_state (snapshot_name) == 0) {
750 set_state (*state_tree->root());
757 Session::load_state (string snapshot_name)
764 state_was_pending = false;
766 /* check for leftover pending state from a crashed capture attempt */
768 sys::path xmlpath(_session_dir->root_path());
769 xmlpath /= snapshot_name + pending_suffix;
771 if (sys::exists (xmlpath)) {
773 /* there is pending state from a crashed capture attempt */
775 if (AskAboutPendingState()) {
776 state_was_pending = true;
780 if (!state_was_pending) {
781 xmlpath = _session_dir->root_path();
782 xmlpath /= snapshot_name + statefile_suffix;
785 if (!sys::exists (xmlpath)) {
786 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
790 state_tree = new XMLTree;
794 if (!state_tree->read (xmlpath.to_string())) {
795 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
801 XMLNode& root (*state_tree->root());
803 if (root.name() != X_("Session")) {
804 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
810 const XMLProperty* prop;
813 if ((prop = root.property ("version")) == 0) {
814 /* no version implies very old version of Ardour */
818 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
819 if (major_version < 2) {
826 sys::path backup_path(_session_dir->root_path());
828 backup_path /= snapshot_name + "-1" + statefile_suffix;
830 // only create a backup once
831 if (sys::exists (backup_path)) {
835 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
836 xmlpath.to_string(), backup_path.to_string())
841 sys::copy_file (xmlpath, backup_path);
843 catch(sys::filesystem_error& ex)
845 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
846 xmlpath.to_string(), ex.what())
856 Session::load_options (const XMLNode& node)
860 LocaleGuard lg (X_("POSIX"));
862 Config->set_variables (node, ConfigVariableBase::Session);
864 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
865 if ((prop = child->property ("val")) != 0) {
866 _end_location_is_free = (prop->value() == "yes");
874 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
876 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
877 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
879 return owner & modified_by_session_or_user;
883 Session::get_options () const
886 LocaleGuard lg (X_("POSIX"));
888 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
890 child = option_root.add_child ("end-marker-is-free");
891 child->add_property ("val", _end_location_is_free ? "yes" : "no");
903 Session::get_template()
905 /* if we don't disable rec-enable, diskstreams
906 will believe they need to store their capture
907 sources in their state node.
910 disable_record (false);
916 Session::state(bool full_state)
918 XMLNode* node = new XMLNode("Session");
921 // store libardour version, just in case
923 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
924 libardour_major_version, libardour_minor_version, libardour_micro_version);
925 node->add_property("version", string(buf));
927 /* store configuration settings */
932 node->add_property ("name", _name);
934 if (session_dirs.size() > 1) {
938 vector<space_and_path>::iterator i = session_dirs.begin();
939 vector<space_and_path>::iterator next;
941 ++i; /* skip the first one */
945 while (i != session_dirs.end()) {
949 if (next != session_dirs.end()) {
959 child = node->add_child ("Path");
960 child->add_content (p);
964 /* save the ID counter */
966 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
967 node->add_property ("id-counter", buf);
969 /* various options */
971 node->add_child_nocopy (get_options());
973 child = node->add_child ("Sources");
976 Glib::Mutex::Lock sl (source_lock);
978 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
980 /* Don't save information about AudioFileSources that are empty */
982 boost::shared_ptr<AudioFileSource> fs;
984 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
986 /* Don't save sources that are empty, unless they're destructive (which are OK
987 if they are empty, because we will re-use them every time.)
990 if (!fs->destructive()) {
991 if (fs->length() == 0) {
997 child->add_child_nocopy (siter->second->get_state());
1001 child = node->add_child ("Regions");
1004 Glib::Mutex::Lock rl (region_lock);
1006 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
1008 /* only store regions not attached to playlists */
1010 if (i->second->playlist() == 0) {
1011 child->add_child_nocopy (i->second->state (true));
1016 child = node->add_child ("DiskStreams");
1019 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1020 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1021 if (!(*i)->hidden()) {
1022 child->add_child_nocopy ((*i)->get_state());
1028 node->add_child_nocopy (_locations.get_state());
1030 // for a template, just create a new Locations, populate it
1031 // with the default start and end, and get the state for that.
1033 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1034 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1037 end->set_end(compute_initial_length());
1039 node->add_child_nocopy (loc.get_state());
1042 child = node->add_child ("Bundles");
1044 Glib::Mutex::Lock lm (bundle_lock);
1045 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
1046 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1048 child->add_child_nocopy (b->get_state());
1053 child = node->add_child ("Routes");
1055 boost::shared_ptr<RouteList> r = routes.reader ();
1057 RoutePublicOrderSorter cmp;
1058 RouteList public_order (*r);
1059 public_order.sort (cmp);
1061 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1062 if (!(*i)->is_hidden()) {
1064 child->add_child_nocopy ((*i)->get_state());
1066 child->add_child_nocopy ((*i)->get_template());
1073 child = node->add_child ("EditGroups");
1074 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1075 child->add_child_nocopy ((*i)->get_state());
1078 child = node->add_child ("MixGroups");
1079 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1080 child->add_child_nocopy ((*i)->get_state());
1083 child = node->add_child ("Playlists");
1084 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1085 if (!(*i)->hidden()) {
1086 if (!(*i)->empty()) {
1088 child->add_child_nocopy ((*i)->get_state());
1090 child->add_child_nocopy ((*i)->get_template());
1096 child = node->add_child ("UnusedPlaylists");
1097 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1098 if (!(*i)->hidden()) {
1099 if (!(*i)->empty()) {
1101 child->add_child_nocopy ((*i)->get_state());
1103 child->add_child_nocopy ((*i)->get_template());
1111 child = node->add_child ("Click");
1112 child->add_child_nocopy (_click_io->state (full_state));
1116 child = node->add_child ("NamedSelections");
1117 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1119 child->add_child_nocopy ((*i)->get_state());
1124 node->add_child_nocopy (_tempo_map->get_state());
1126 node->add_child_nocopy (get_control_protocol_state());
1129 node->add_child_copy (*_extra_xml);
1136 Session::get_control_protocol_state ()
1138 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1139 return cpm.get_state();
1143 Session::set_state (const XMLNode& node)
1147 const XMLProperty* prop;
1150 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1153 if (node.name() != X_("Session")){
1154 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1158 if ((prop = node.property ("name")) != 0) {
1159 _name = prop->value ();
1162 setup_raid_path(_session_dir->root_path().to_string());
1164 if ((prop = node.property (X_("id-counter"))) != 0) {
1166 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1167 ID::init_counter (x);
1169 /* old sessions used a timebased counter, so fake
1170 the startup ID counter based on a standard
1175 ID::init_counter (now);
1179 IO::disable_ports ();
1180 IO::disable_connecting ();
1182 /* Object loading order:
1200 if (use_config_midi_ports ()) {
1203 if ((child = find_named_node (node, "extra")) != 0) {
1204 _extra_xml = new XMLNode (*child);
1207 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1208 load_options (*child);
1209 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1210 load_options (*child);
1212 error << _("Session: XML state has no options section") << endmsg;
1215 if ((child = find_named_node (node, "Locations")) == 0) {
1216 error << _("Session: XML state has no locations section") << endmsg;
1218 } else if (_locations.set_state (*child)) {
1224 if ((location = _locations.auto_loop_location()) != 0) {
1225 set_auto_loop_location (location);
1228 if ((location = _locations.auto_punch_location()) != 0) {
1229 set_auto_punch_location (location);
1232 if ((location = _locations.end_location()) == 0) {
1233 _locations.add (end_location);
1235 delete end_location;
1236 end_location = location;
1239 if ((location = _locations.start_location()) == 0) {
1240 _locations.add (start_location);
1242 delete start_location;
1243 start_location = location;
1246 AudioFileSource::set_header_position_offset (start_location->start());
1248 if ((child = find_named_node (node, "Sources")) == 0) {
1249 error << _("Session: XML state has no sources section") << endmsg;
1251 } else if (load_sources (*child)) {
1255 if ((child = find_named_node (node, "Regions")) == 0) {
1256 error << _("Session: XML state has no Regions section") << endmsg;
1258 } else if (load_regions (*child)) {
1262 if ((child = find_named_node (node, "Playlists")) == 0) {
1263 error << _("Session: XML state has no playlists section") << endmsg;
1265 } else if (load_playlists (*child)) {
1269 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1271 } else if (load_unused_playlists (*child)) {
1275 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1276 if (load_named_selections (*child)) {
1281 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1282 error << _("Session: XML state has no diskstreams section") << endmsg;
1284 } else if (load_diskstreams (*child)) {
1288 if ((child = find_named_node (node, "Bundles")) == 0) {
1289 warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg;
1292 /* We can't load Bundles yet as they need to be able
1293 to convert from port names to Port objects, which can't happen until
1295 _bundle_xml_node = new XMLNode (*child);
1298 if ((child = find_named_node (node, "EditGroups")) == 0) {
1299 error << _("Session: XML state has no edit groups section") << endmsg;
1301 } else if (load_edit_groups (*child)) {
1305 if ((child = find_named_node (node, "MixGroups")) == 0) {
1306 error << _("Session: XML state has no mix groups section") << endmsg;
1308 } else if (load_mix_groups (*child)) {
1312 if ((child = find_named_node (node, "TempoMap")) == 0) {
1313 error << _("Session: XML state has no Tempo Map section") << endmsg;
1315 } else if (_tempo_map->set_state (*child)) {
1319 if ((child = find_named_node (node, "Routes")) == 0) {
1320 error << _("Session: XML state has no routes section") << endmsg;
1322 } else if (load_routes (*child)) {
1326 if ((child = find_named_node (node, "Click")) == 0) {
1327 warning << _("Session: XML state has no click section") << endmsg;
1328 } else if (_click_io) {
1329 _click_io->set_state (*child);
1332 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1333 ControlProtocolManager::instance().set_protocol_states (*child);
1336 /* here beginneth the second phase ... */
1338 StateReady (); /* EMIT SIGNAL */
1347 Session::load_routes (const XMLNode& node)
1350 XMLNodeConstIterator niter;
1351 RouteList new_routes;
1353 nlist = node.children();
1357 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1359 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1362 error << _("Session: cannot create Route from XML description.") << endmsg;
1366 new_routes.push_back (route);
1369 add_routes (new_routes, false);
1374 boost::shared_ptr<Route>
1375 Session::XMLRouteFactory (const XMLNode& node)
1377 if (node.name() != "Route") {
1378 return boost::shared_ptr<Route> ((Route*) 0);
1381 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1383 DataType type = DataType::AUDIO;
1384 const XMLProperty* prop = node.property("default-type");
1386 type = DataType(prop->value());
1388 assert(type != DataType::NIL);
1390 if (has_diskstream) {
1391 if (type == DataType::AUDIO) {
1392 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1395 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1399 boost::shared_ptr<Route> ret (new Route (*this, node));
1405 Session::load_regions (const XMLNode& node)
1408 XMLNodeConstIterator niter;
1409 boost::shared_ptr<Region> region;
1411 nlist = node.children();
1415 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1416 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1417 error << _("Session: cannot create Region from XML description.");
1418 const XMLProperty *name = (**niter).property("name");
1421 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1431 boost::shared_ptr<Region>
1432 Session::XMLRegionFactory (const XMLNode& node, bool full)
1434 const XMLProperty* type = node.property("type");
1438 if ( !type || type->value() == "audio" ) {
1440 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1442 } else if (type->value() == "midi") {
1444 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1448 } catch (failed_constructor& err) {
1449 return boost::shared_ptr<Region> ();
1452 return boost::shared_ptr<Region> ();
1455 boost::shared_ptr<AudioRegion>
1456 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1458 const XMLProperty* prop;
1459 boost::shared_ptr<Source> source;
1460 boost::shared_ptr<AudioSource> as;
1462 SourceList master_sources;
1463 uint32_t nchans = 1;
1466 if (node.name() != X_("Region")) {
1467 return boost::shared_ptr<AudioRegion>();
1470 if ((prop = node.property (X_("channels"))) != 0) {
1471 nchans = atoi (prop->value().c_str());
1474 if ((prop = node.property ("name")) == 0) {
1475 cerr << "no name for this region\n";
1479 if ((prop = node.property (X_("source-0"))) == 0) {
1480 if ((prop = node.property ("source")) == 0) {
1481 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1482 return boost::shared_ptr<AudioRegion>();
1486 PBD::ID s_id (prop->value());
1488 if ((source = source_by_id (s_id)) == 0) {
1489 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1490 return boost::shared_ptr<AudioRegion>();
1493 as = boost::dynamic_pointer_cast<AudioSource>(source);
1495 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1496 return boost::shared_ptr<AudioRegion>();
1499 sources.push_back (as);
1501 /* pickup other channels */
1503 for (uint32_t n=1; n < nchans; ++n) {
1504 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1505 if ((prop = node.property (buf)) != 0) {
1507 PBD::ID id2 (prop->value());
1509 if ((source = source_by_id (id2)) == 0) {
1510 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1511 return boost::shared_ptr<AudioRegion>();
1514 as = boost::dynamic_pointer_cast<AudioSource>(source);
1516 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1517 return boost::shared_ptr<AudioRegion>();
1519 sources.push_back (as);
1523 for (uint32_t n=1; n < nchans; ++n) {
1524 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1525 if ((prop = node.property (buf)) != 0) {
1527 PBD::ID id2 (prop->value());
1529 if ((source = source_by_id (id2)) == 0) {
1530 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1531 return boost::shared_ptr<AudioRegion>();
1534 as = boost::dynamic_pointer_cast<AudioSource>(source);
1536 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1537 return boost::shared_ptr<AudioRegion>();
1539 master_sources.push_back (as);
1544 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1546 /* a final detail: this is the one and only place that we know how long missing files are */
1548 if (region->whole_file()) {
1549 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1550 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1552 sfp->set_length (region->length());
1557 if (!master_sources.empty()) {
1558 if (master_sources.size() == nchans) {
1559 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1561 region->set_master_sources (master_sources);
1569 catch (failed_constructor& err) {
1570 return boost::shared_ptr<AudioRegion>();
1574 boost::shared_ptr<MidiRegion>
1575 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1577 const XMLProperty* prop;
1578 boost::shared_ptr<Source> source;
1579 boost::shared_ptr<MidiSource> ms;
1581 uint32_t nchans = 1;
1583 if (node.name() != X_("Region")) {
1584 return boost::shared_ptr<MidiRegion>();
1587 if ((prop = node.property (X_("channels"))) != 0) {
1588 nchans = atoi (prop->value().c_str());
1591 if ((prop = node.property ("name")) == 0) {
1592 cerr << "no name for this region\n";
1596 // Multiple midi channels? that's just crazy talk
1597 assert(nchans == 1);
1599 if ((prop = node.property (X_("source-0"))) == 0) {
1600 if ((prop = node.property ("source")) == 0) {
1601 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1602 return boost::shared_ptr<MidiRegion>();
1606 PBD::ID s_id (prop->value());
1608 if ((source = source_by_id (s_id)) == 0) {
1609 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1610 return boost::shared_ptr<MidiRegion>();
1613 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1615 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1616 return boost::shared_ptr<MidiRegion>();
1619 sources.push_back (ms);
1622 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1623 /* a final detail: this is the one and only place that we know how long missing files are */
1625 if (region->whole_file()) {
1626 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1627 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1629 sfp->set_length (region->length());
1637 catch (failed_constructor& err) {
1638 return boost::shared_ptr<MidiRegion>();
1643 Session::get_sources_as_xml ()
1646 XMLNode* node = new XMLNode (X_("Sources"));
1647 Glib::Mutex::Lock lm (source_lock);
1649 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1650 node->add_child_nocopy (i->second->get_state());
1657 Session::path_from_region_name (DataType type, string name, string identifier)
1659 char buf[PATH_MAX+1];
1661 SessionDirectory sdir(get_best_session_directory_for_new_source());
1662 sys::path source_dir = ((type == DataType::AUDIO)
1663 ? sdir.sound_path() : sdir.midi_path());
1665 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1667 for (n = 0; n < 999999; ++n) {
1668 if (identifier.length()) {
1669 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1670 identifier.c_str(), n, ext.c_str());
1672 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1676 sys::path source_path = source_dir / buf;
1678 if (!sys::exists (source_path)) {
1679 return source_path.to_string();
1683 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1692 Session::load_sources (const XMLNode& node)
1695 XMLNodeConstIterator niter;
1696 boost::shared_ptr<Source> source;
1698 nlist = node.children();
1702 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1705 if ((source = XMLSourceFactory (**niter)) == 0) {
1706 error << _("Session: cannot create Source from XML description.") << endmsg;
1710 catch (non_existent_source& err) {
1711 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1712 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1719 boost::shared_ptr<Source>
1720 Session::XMLSourceFactory (const XMLNode& node)
1722 if (node.name() != "Source") {
1723 return boost::shared_ptr<Source>();
1727 return SourceFactory::create (*this, node);
1730 catch (failed_constructor& err) {
1731 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1732 return boost::shared_ptr<Source>();
1737 Session::save_template (string template_name)
1741 if (_state_of_the_state & CannotSave) {
1745 sys::path user_template_dir(user_template_directory());
1749 sys::create_directories (user_template_dir);
1751 catch(sys::filesystem_error& ex)
1753 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1754 user_template_dir.to_string(), ex.what()) << endmsg;
1758 tree.set_root (&get_template());
1760 sys::path template_file_path(user_template_dir);
1761 template_file_path /= template_name + template_suffix;
1763 if (sys::exists (template_file_path))
1765 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1766 template_file_path.to_string()) << endmsg;
1770 if (!tree.write (template_file_path.to_string())) {
1771 error << _("mix template not saved") << endmsg;
1779 Session::refresh_disk_space ()
1782 struct statfs statfsbuf;
1783 vector<space_and_path>::iterator i;
1784 Glib::Mutex::Lock lm (space_lock);
1787 /* get freespace on every FS that is part of the session path */
1789 _total_free_4k_blocks = 0;
1791 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1792 statfs ((*i).path.c_str(), &statfsbuf);
1794 scale = statfsbuf.f_bsize/4096.0;
1796 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1797 _total_free_4k_blocks += (*i).blocks;
1803 Session::get_best_session_directory_for_new_source ()
1805 vector<space_and_path>::iterator i;
1806 string result = _session_dir->root_path().to_string();
1808 /* handle common case without system calls */
1810 if (session_dirs.size() == 1) {
1814 /* OK, here's the algorithm we're following here:
1816 We want to select which directory to use for
1817 the next file source to be created. Ideally,
1818 we'd like to use a round-robin process so as to
1819 get maximum performance benefits from splitting
1820 the files across multiple disks.
1822 However, in situations without much diskspace, an
1823 RR approach may end up filling up a filesystem
1824 with new files while others still have space.
1825 Its therefore important to pay some attention to
1826 the freespace in the filesystem holding each
1827 directory as well. However, if we did that by
1828 itself, we'd keep creating new files in the file
1829 system with the most space until it was as full
1830 as all others, thus negating any performance
1831 benefits of this RAID-1 like approach.
1833 So, we use a user-configurable space threshold. If
1834 there are at least 2 filesystems with more than this
1835 much space available, we use RR selection between them.
1836 If not, then we pick the filesystem with the most space.
1838 This gets a good balance between the two
1842 refresh_disk_space ();
1844 int free_enough = 0;
1846 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1847 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1852 if (free_enough >= 2) {
1853 /* use RR selection process, ensuring that the one
1857 i = last_rr_session_dir;
1860 if (++i == session_dirs.end()) {
1861 i = session_dirs.begin();
1864 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1865 if (create_session_directory ((*i).path)) {
1867 last_rr_session_dir = i;
1872 } while (i != last_rr_session_dir);
1876 /* pick FS with the most freespace (and that
1877 seems to actually work ...)
1880 vector<space_and_path> sorted;
1881 space_and_path_ascending_cmp cmp;
1883 sorted = session_dirs;
1884 sort (sorted.begin(), sorted.end(), cmp);
1886 for (i = sorted.begin(); i != sorted.end(); ++i) {
1887 if (create_session_directory ((*i).path)) {
1889 last_rr_session_dir = i;
1899 Session::load_playlists (const XMLNode& node)
1902 XMLNodeConstIterator niter;
1903 boost::shared_ptr<Playlist> playlist;
1905 nlist = node.children();
1909 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1911 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1912 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1920 Session::load_unused_playlists (const XMLNode& node)
1923 XMLNodeConstIterator niter;
1924 boost::shared_ptr<Playlist> playlist;
1926 nlist = node.children();
1930 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1932 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1933 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1937 // now manually untrack it
1939 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1945 boost::shared_ptr<Playlist>
1946 Session::XMLPlaylistFactory (const XMLNode& node)
1949 return PlaylistFactory::create (*this, node);
1952 catch (failed_constructor& err) {
1953 return boost::shared_ptr<Playlist>();
1958 Session::load_named_selections (const XMLNode& node)
1961 XMLNodeConstIterator niter;
1964 nlist = node.children();
1968 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1970 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1971 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1979 Session::XMLNamedSelectionFactory (const XMLNode& node)
1982 return new NamedSelection (*this, node);
1985 catch (failed_constructor& err) {
1991 Session::automation_dir () const
1994 res += "automation/";
1999 Session::analysis_dir () const
2007 Session::load_bundles (XMLNode const & node)
2009 XMLNodeList nlist = node.children();
2010 XMLNodeConstIterator niter;
2014 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2015 if ((*niter)->name() == "InputBundle") {
2016 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2017 } else if ((*niter)->name() == "OutputBundle") {
2018 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2020 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2029 Session::load_edit_groups (const XMLNode& node)
2031 return load_route_groups (node, true);
2035 Session::load_mix_groups (const XMLNode& node)
2037 return load_route_groups (node, false);
2041 Session::load_route_groups (const XMLNode& node, bool edit)
2043 XMLNodeList nlist = node.children();
2044 XMLNodeConstIterator niter;
2049 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2050 if ((*niter)->name() == "RouteGroup") {
2052 rg = add_edit_group ("");
2053 rg->set_state (**niter);
2055 rg = add_mix_group ("");
2056 rg->set_state (**niter);
2065 Session::auto_save()
2067 save_state (_current_snapshot_name);
2071 Session::add_edit_group (string name)
2073 RouteGroup* rg = new RouteGroup (*this, name);
2074 edit_groups.push_back (rg);
2075 edit_group_added (rg); /* EMIT SIGNAL */
2081 Session::add_mix_group (string name)
2083 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2084 mix_groups.push_back (rg);
2085 mix_group_added (rg); /* EMIT SIGNAL */
2091 Session::remove_edit_group (RouteGroup& rg)
2093 list<RouteGroup*>::iterator i;
2095 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2096 (*i)->apply (&Route::drop_edit_group, this);
2097 edit_groups.erase (i);
2098 edit_group_removed (); /* EMIT SIGNAL */
2105 Session::remove_mix_group (RouteGroup& rg)
2107 list<RouteGroup*>::iterator i;
2109 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2110 (*i)->apply (&Route::drop_mix_group, this);
2111 mix_groups.erase (i);
2112 mix_group_removed (); /* EMIT SIGNAL */
2119 Session::mix_group_by_name (string name)
2121 list<RouteGroup *>::iterator i;
2123 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2124 if ((*i)->name() == name) {
2132 Session::edit_group_by_name (string name)
2134 list<RouteGroup *>::iterator i;
2136 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2137 if ((*i)->name() == name) {
2145 Session::begin_reversible_command (const string& name)
2147 current_trans = new UndoTransaction;
2148 current_trans->set_name (name);
2152 Session::commit_reversible_command (Command *cmd)
2157 current_trans->add_command (cmd);
2160 if (current_trans->empty()) {
2164 gettimeofday (&now, 0);
2165 current_trans->set_timestamp (now);
2167 _history.add (current_trans);
2170 Session::GlobalRouteBooleanState
2171 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2173 GlobalRouteBooleanState s;
2174 boost::shared_ptr<RouteList> r = routes.reader ();
2176 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2177 if (!(*i)->is_hidden()) {
2178 RouteBooleanState v;
2181 Route* r = (*i).get();
2182 v.second = (r->*method)();
2191 Session::GlobalRouteMeterState
2192 Session::get_global_route_metering ()
2194 GlobalRouteMeterState s;
2195 boost::shared_ptr<RouteList> r = routes.reader ();
2197 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2198 if (!(*i)->is_hidden()) {
2202 v.second = (*i)->meter_point();
2212 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2214 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2216 boost::shared_ptr<Route> r = (i->first.lock());
2219 r->set_meter_point (i->second, arg);
2225 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2227 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2229 boost::shared_ptr<Route> r = (i->first.lock());
2232 Route* rp = r.get();
2233 (rp->*method) (i->second, arg);
2239 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2241 set_global_route_boolean (s, &Route::set_mute, src);
2245 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2247 set_global_route_boolean (s, &Route::set_solo, src);
2251 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2253 set_global_route_boolean (s, &Route::set_record_enable, src);
2258 Session::global_mute_memento (void* src)
2260 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2264 Session::global_metering_memento (void* src)
2266 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2270 Session::global_solo_memento (void* src)
2272 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2276 Session::global_record_enable_memento (void* src)
2278 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2283 accept_all_non_peak_files (const string& path, void *arg)
2285 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2289 accept_all_state_files (const string& path, void *arg)
2291 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2295 Session::find_all_sources (string path, set<string>& result)
2300 if (!tree.read (path)) {
2304 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2309 XMLNodeConstIterator niter;
2311 nlist = node->children();
2315 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2319 if ((prop = (*niter)->property (X_("name"))) == 0) {
2323 if (prop->value()[0] == '/') {
2324 /* external file, ignore */
2328 sys::path source_path = _session_dir->sound_path ();
2330 source_path /= prop->value ();
2332 result.insert (source_path.to_string ());
2339 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2341 PathScanner scanner;
2342 vector<string*>* state_files;
2344 string this_snapshot_path;
2350 if (ripped[ripped.length()-1] == '/') {
2351 ripped = ripped.substr (0, ripped.length() - 1);
2354 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2356 if (state_files == 0) {
2361 this_snapshot_path = _path;
2362 this_snapshot_path += _current_snapshot_name;
2363 this_snapshot_path += statefile_suffix;
2365 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2367 if (exclude_this_snapshot && **i == this_snapshot_path) {
2371 if (find_all_sources (**i, result) < 0) {
2379 struct RegionCounter {
2380 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2381 AudioSourceList::iterator iter;
2382 boost::shared_ptr<Region> region;
2385 RegionCounter() : count (0) {}
2389 Session::cleanup_sources (Session::cleanup_report& rep)
2391 // FIXME: needs adaptation to midi
2393 vector<boost::shared_ptr<Source> > dead_sources;
2394 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2395 PathScanner scanner;
2397 vector<space_and_path>::iterator i;
2398 vector<space_and_path>::iterator nexti;
2399 vector<string*>* soundfiles;
2400 vector<string> unused;
2401 set<string> all_sources;
2406 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2409 /* step 1: consider deleting all unused playlists */
2411 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2414 status = AskAboutPlaylistDeletion (*x);
2423 playlists_tbd.push_back (*x);
2427 /* leave it alone */
2432 /* now delete any that were marked for deletion */
2434 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2435 (*x)->drop_references ();
2438 playlists_tbd.clear ();
2440 /* step 2: find all un-used sources */
2445 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2447 SourceMap::iterator tmp;
2452 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2456 if (!i->second->used() && i->second->length() > 0) {
2457 dead_sources.push_back (i->second);
2458 i->second->GoingAway();
2464 /* build a list of all the possible sound directories for the session */
2466 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2471 SessionDirectory sdir ((*i).path);
2472 sound_path += sdir.sound_path().to_string();
2474 if (nexti != session_dirs.end()) {
2481 /* now do the same thing for the files that ended up in the sounds dir(s)
2482 but are not referenced as sources in any snapshot.
2485 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2487 if (soundfiles == 0) {
2491 /* find all sources, but don't use this snapshot because the
2492 state file on disk still references sources we may have already
2496 find_all_sources_across_snapshots (all_sources, true);
2498 /* add our current source list
2501 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2502 boost::shared_ptr<AudioFileSource> fs;
2504 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2505 all_sources.insert (fs->path());
2509 char tmppath1[PATH_MAX+1];
2510 char tmppath2[PATH_MAX+1];
2512 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2517 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2519 realpath(spath.c_str(), tmppath1);
2520 realpath((*i).c_str(), tmppath2);
2522 if (strcmp(tmppath1, tmppath2) == 0) {
2529 unused.push_back (spath);
2533 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2535 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2536 struct stat statbuf;
2538 rep.paths.push_back (*x);
2539 if (stat ((*x).c_str(), &statbuf) == 0) {
2540 rep.space += statbuf.st_size;
2545 /* don't move the file across filesystems, just
2546 stick it in the `dead_sound_dir_name' directory
2547 on whichever filesystem it was already on.
2550 if ((*x).find ("/sounds/") != string::npos) {
2552 /* old school, go up 1 level */
2554 newpath = Glib::path_get_dirname (*x); // "sounds"
2555 newpath = Glib::path_get_dirname (newpath); // "session-name"
2559 /* new school, go up 4 levels */
2561 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2562 newpath = Glib::path_get_dirname (newpath); // "session-name"
2563 newpath = Glib::path_get_dirname (newpath); // "interchange"
2564 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2568 newpath += dead_sound_dir_name;
2570 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2571 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2576 newpath += Glib::path_get_basename ((*x));
2578 if (access (newpath.c_str(), F_OK) == 0) {
2580 /* the new path already exists, try versioning */
2582 char buf[PATH_MAX+1];
2586 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2589 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2590 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2594 if (version == 999) {
2595 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2599 newpath = newpath_v;
2604 /* it doesn't exist, or we can't read it or something */
2608 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2609 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2610 (*x), newpath, strerror (errno))
2615 /* see if there an easy to find peakfile for this file, and remove it.
2618 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2619 peakpath += peakfile_suffix;
2621 if (access (peakpath.c_str(), W_OK) == 0) {
2622 if (::unlink (peakpath.c_str()) != 0) {
2623 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2624 peakpath, _path, strerror (errno))
2626 /* try to back out */
2627 rename (newpath.c_str(), _path.c_str());
2635 /* dump the history list */
2639 /* save state so we don't end up a session file
2640 referring to non-existent sources.
2646 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2652 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2654 // FIXME: needs adaptation for MIDI
2656 vector<space_and_path>::iterator i;
2657 string dead_sound_dir;
2658 struct dirent* dentry;
2659 struct stat statbuf;
2665 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2667 dead_sound_dir = (*i).path;
2668 dead_sound_dir += dead_sound_dir_name;
2670 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2674 while ((dentry = readdir (dead)) != 0) {
2676 /* avoid '.' and '..' */
2678 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2679 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2685 fullpath = dead_sound_dir;
2687 fullpath += dentry->d_name;
2689 if (stat (fullpath.c_str(), &statbuf)) {
2693 if (!S_ISREG (statbuf.st_mode)) {
2697 if (unlink (fullpath.c_str())) {
2698 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2699 fullpath, strerror (errno))
2703 rep.paths.push_back (dentry->d_name);
2704 rep.space += statbuf.st_size;
2715 Session::set_dirty ()
2717 bool was_dirty = dirty();
2719 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2723 DirtyChanged(); /* EMIT SIGNAL */
2729 Session::set_clean ()
2731 bool was_dirty = dirty();
2733 _state_of_the_state = Clean;
2737 DirtyChanged(); /* EMIT SIGNAL */
2742 Session::set_deletion_in_progress ()
2744 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2749 Session::add_controllable (boost::shared_ptr<Controllable> c)
2751 /* this adds a controllable to the list managed by the Session.
2752 this is a subset of those managed by the Controllable class
2753 itself, and represents the only ones whose state will be saved
2754 as part of the session.
2757 Glib::Mutex::Lock lm (controllables_lock);
2758 controllables.insert (c);
2761 struct null_deleter { void operator()(void const *) const {} };
2764 Session::remove_controllable (Controllable* c)
2766 if (_state_of_the_state | Deletion) {
2770 Glib::Mutex::Lock lm (controllables_lock);
2772 Controllables::iterator x = controllables.find(
2773 boost::shared_ptr<Controllable>(c, null_deleter()));
2775 if (x != controllables.end()) {
2776 controllables.erase (x);
2780 boost::shared_ptr<Controllable>
2781 Session::controllable_by_id (const PBD::ID& id)
2783 Glib::Mutex::Lock lm (controllables_lock);
2785 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2786 if ((*i)->id() == id) {
2791 return boost::shared_ptr<Controllable>();
2795 Session::add_instant_xml (XMLNode& node)
2797 Stateful::add_instant_xml (node, _path);
2798 Config->add_instant_xml (node);
2802 Session::instant_xml (const string& node_name)
2804 return Stateful::instant_xml (node_name, _path);
2808 Session::save_history (string snapshot_name)
2812 if (snapshot_name.empty()) {
2813 snapshot_name = _current_snapshot_name;
2816 const string history_filename = snapshot_name + history_suffix;
2817 const string backup_filename = history_filename + backup_suffix;
2818 const sys::path xml_path = _session_dir->root_path() / history_filename;
2819 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2821 if (sys::exists (xml_path)) {
2824 sys::rename (xml_path, backup_path);
2826 catch (const sys::filesystem_error& err)
2828 error << _("could not backup old history file, current history not saved") << endmsg;
2834 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2838 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2840 if (!tree.write (xml_path.to_string()))
2842 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2846 sys::remove (xml_path);
2847 sys::rename (backup_path, xml_path);
2849 catch (const sys::filesystem_error& err)
2851 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2852 backup_path.to_string(), err.what()) << endmsg;
2862 Session::restore_history (string snapshot_name)
2866 if (snapshot_name.empty()) {
2867 snapshot_name = _current_snapshot_name;
2870 const string xml_filename = snapshot_name + history_suffix;
2871 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2873 cerr << "Loading history from " << xml_path.to_string() << endmsg;
2875 if (!sys::exists (xml_path)) {
2876 info << string_compose (_("%1: no history file \"%2\" for this session."),
2877 _name, xml_path.to_string()) << endmsg;
2881 if (!tree.read (xml_path.to_string())) {
2882 error << string_compose (_("Could not understand session history file \"%1\""),
2883 xml_path.to_string()) << endmsg;
2890 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2893 UndoTransaction* ut = new UndoTransaction ();
2896 ut->set_name(t->property("name")->value());
2897 stringstream ss(t->property("tv_sec")->value());
2899 ss.str(t->property("tv_usec")->value());
2901 ut->set_timestamp(tv);
2903 for (XMLNodeConstIterator child_it = t->children().begin();
2904 child_it != t->children().end();
2907 XMLNode *n = *child_it;
2910 if (n->name() == "MementoCommand" ||
2911 n->name() == "MementoUndoCommand" ||
2912 n->name() == "MementoRedoCommand") {
2914 if ((c = memento_command_factory(n))) {
2918 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2920 if ((c = global_state_command_factory (*n))) {
2921 ut->add_command (c);
2926 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2937 Session::config_changed (const char* parameter_name)
2939 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2941 if (PARAM_IS ("seamless-loop")) {
2943 } else if (PARAM_IS ("rf-speed")) {
2945 } else if (PARAM_IS ("auto-loop")) {
2947 } else if (PARAM_IS ("auto-input")) {
2949 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2950 /* auto-input only makes a difference if we're rolling */
2952 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2954 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2955 if ((*i)->record_enabled ()) {
2956 (*i)->monitor_input (!Config->get_auto_input());
2961 } else if (PARAM_IS ("punch-in")) {
2965 if ((location = _locations.auto_punch_location()) != 0) {
2967 if (Config->get_punch_in ()) {
2968 replace_event (Event::PunchIn, location->start());
2970 remove_event (location->start(), Event::PunchIn);
2974 } else if (PARAM_IS ("punch-out")) {
2978 if ((location = _locations.auto_punch_location()) != 0) {
2980 if (Config->get_punch_out()) {
2981 replace_event (Event::PunchOut, location->end());
2983 clear_events (Event::PunchOut);
2987 } else if (PARAM_IS ("edit-mode")) {
2989 Glib::Mutex::Lock lm (playlist_lock);
2991 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2992 (*i)->set_edit_mode (Config->get_edit_mode ());
2995 } else if (PARAM_IS ("use-video-sync")) {
2997 waiting_for_sync_offset = Config->get_use_video_sync();
2999 } else if (PARAM_IS ("mmc-control")) {
3001 //poke_midi_thread ();
3003 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
3006 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3009 } else if (PARAM_IS ("mmc-send-id")) {
3012 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3015 } else if (PARAM_IS ("midi-control")) {
3017 //poke_midi_thread ();
3019 } else if (PARAM_IS ("raid-path")) {
3021 setup_raid_path (Config->get_raid_path());
3023 } else if (PARAM_IS ("smpte-format")) {
3027 } else if (PARAM_IS ("video-pullup")) {
3031 } else if (PARAM_IS ("seamless-loop")) {
3033 if (play_loop && transport_rolling()) {
3034 // to reset diskstreams etc
3035 request_play_loop (true);
3038 } else if (PARAM_IS ("rf-speed")) {
3040 cumulative_rf_motion = 0;
3043 } else if (PARAM_IS ("click-sound")) {
3045 setup_click_sounds (1);
3047 } else if (PARAM_IS ("click-emphasis-sound")) {
3049 setup_click_sounds (-1);
3051 } else if (PARAM_IS ("clicking")) {
3053 if (Config->get_clicking()) {
3054 if (_click_io && click_data) { // don't require emphasis data
3061 } else if (PARAM_IS ("send-mtc")) {
3063 /* only set the internal flag if we have
3067 if (_mtc_port != 0) {
3068 session_send_mtc = Config->get_send_mtc();
3069 if (session_send_mtc) {
3070 /* mark us ready to send */
3071 next_quarter_frame_to_send = 0;
3074 session_send_mtc = false;
3077 } else if (PARAM_IS ("send-mmc")) {
3079 /* only set the internal flag if we have
3083 if (_mmc_port != 0) {
3084 session_send_mmc = Config->get_send_mmc();
3087 session_send_mmc = false;
3090 } else if (PARAM_IS ("midi-feedback")) {
3092 /* only set the internal flag if we have
3096 if (_mtc_port != 0) {
3097 session_midi_feedback = Config->get_midi_feedback();
3100 } else if (PARAM_IS ("jack-time-master")) {
3102 engine().reset_timebase ();
3104 } else if (PARAM_IS ("native-file-header-format")) {
3106 if (!first_file_header_format_reset) {
3107 reset_native_file_format ();
3110 first_file_header_format_reset = false;
3112 } else if (PARAM_IS ("native-file-data-format")) {
3114 if (!first_file_data_format_reset) {
3115 reset_native_file_format ();
3118 first_file_data_format_reset = false;
3120 } else if (PARAM_IS ("slave-source")) {
3121 set_slave_source (Config->get_slave_source());
3122 } else if (PARAM_IS ("remote-model")) {
3123 set_remote_control_ids ();
3124 } else if (PARAM_IS ("denormal-model")) {
3126 } else if (PARAM_IS ("history-depth")) {
3127 set_history_depth (Config->get_history_depth());
3128 } else if (PARAM_IS ("sync-all-route-ordering")) {
3139 Session::set_history_depth (uint32_t d)
3141 _history.set_depth (d);