2 Copyright (C) 1999-2010 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.
27 #include <cstdio> /* sprintf(3) ... grrr */
33 #include <glibmm/threads.h>
34 #include <glibmm/miscutils.h>
35 #include <glibmm/fileutils.h>
37 #include <boost/algorithm/string/erase.hpp>
39 #include "pbd/basename.h"
40 #include "pbd/boost_debug.h"
41 #include "pbd/convert.h"
42 #include "pbd/convert.h"
43 #include "pbd/error.h"
44 #include "pbd/file_utils.h"
46 #include "pbd/search_path.h"
47 #include "pbd/stacktrace.h"
48 #include "pbd/stl_delete.h"
49 #include "pbd/unwind.h"
51 #include "ardour/amp.h"
52 #include "ardour/analyser.h"
53 #include "ardour/async_midi_port.h"
54 #include "ardour/audio_buffer.h"
55 #include "ardour/audio_diskstream.h"
56 #include "ardour/audio_port.h"
57 #include "ardour/audio_track.h"
58 #include "ardour/audioengine.h"
59 #include "ardour/audiofilesource.h"
60 #include "ardour/auditioner.h"
61 #include "ardour/buffer_manager.h"
62 #include "ardour/buffer_set.h"
63 #include "ardour/bundle.h"
64 #include "ardour/butler.h"
65 #include "ardour/click.h"
66 #include "ardour/control_protocol_manager.h"
67 #include "ardour/data_type.h"
68 #include "ardour/debug.h"
69 #include "ardour/directory_names.h"
70 #include "ardour/filename_extensions.h"
71 #include "ardour/graph.h"
72 #include "ardour/midiport_manager.h"
73 #include "ardour/scene_changer.h"
74 #include "ardour/midi_track.h"
75 #include "ardour/midi_ui.h"
76 #include "ardour/operations.h"
77 #include "ardour/playlist.h"
78 #include "ardour/plugin.h"
79 #include "ardour/plugin_insert.h"
80 #include "ardour/process_thread.h"
81 #include "ardour/profile.h"
82 #include "ardour/rc_configuration.h"
83 #include "ardour/recent_sessions.h"
84 #include "ardour/region.h"
85 #include "ardour/region_factory.h"
86 #include "ardour/route_graph.h"
87 #include "ardour/route_group.h"
88 #include "ardour/route_sorters.h"
89 #include "ardour/send.h"
90 #include "ardour/session.h"
91 #include "ardour/session_directory.h"
92 #include "ardour/session_playlists.h"
93 #include "ardour/smf_source.h"
94 #include "ardour/source_factory.h"
95 #include "ardour/speakers.h"
96 #include "ardour/tempo.h"
97 #include "ardour/track.h"
98 #include "ardour/user_bundle.h"
99 #include "ardour/utils.h"
101 #include "midi++/port.h"
102 #include "midi++/mmc.h"
113 using namespace ARDOUR;
116 const char * Session::default_trx_track_name_pattern = "Track "; // add track number to the pattern
117 const char * Session::default_ardour_track_name_pattern = "Audio "; // add track number to the pattern
119 bool Session::_disable_all_loaded_plugins = false;
121 PBD::Signal1<int,uint32_t> Session::AudioEngineSetupRequired;
122 PBD::Signal1<void,std::string> Session::Dialog;
123 PBD::Signal0<int> Session::AskAboutPendingState;
124 PBD::Signal2<int, framecnt_t, framecnt_t> Session::AskAboutSampleRateMismatch;
125 PBD::Signal0<void> Session::SendFeedback;
126 PBD::Signal3<int,Session*,std::string,DataType> Session::MissingFile;
128 PBD::Signal1<void, framepos_t> Session::StartTimeChanged;
129 PBD::Signal1<void, framepos_t> Session::EndTimeChanged;
130 PBD::Signal2<void,std::string, std::string> Session::Exported;
131 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
132 PBD::Signal0<void> Session::Quit;
133 PBD::Signal0<void> Session::FeedbackDetected;
134 PBD::Signal0<void> Session::SuccessfulGraphSort;
135 PBD::Signal2<void,std::string,std::string> Session::VersionMismatch;
137 const framecnt_t Session::bounce_chunk_size = 65536;
138 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
139 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
141 /** @param snapshot_name Snapshot name, without .ardour suffix */
142 Session::Session (AudioEngine &eng,
143 const string& fullpath,
144 const string& snapshot_name,
145 BusProfile* bus_profile,
147 : playlists (new SessionPlaylists)
149 , process_function (&Session::process_with_events)
150 , _bounce_processing_active (false)
151 , waiting_for_sync_offset (false)
152 , _base_frame_rate (0)
153 , _current_frame_rate (0)
154 , _nominal_frame_rate (0)
155 , transport_sub_state (0)
156 , _record_status (Disabled)
157 , _transport_frame (0)
158 , _session_range_location (0)
161 , _transport_speed (0)
162 , _default_transport_speed (1.0)
163 , _last_transport_speed (0)
164 , _target_transport_speed (0.0)
165 , auto_play_legal (false)
166 , _last_slave_transport_frame (0)
167 , maximum_output_latency (0)
168 , _requested_return_frame (-1)
169 , current_block_size (0)
170 , _worst_output_latency (0)
171 , _worst_input_latency (0)
172 , _worst_track_latency (0)
173 , _have_captured (false)
174 , _non_soloed_outs_muted (false)
176 , _solo_isolated_cnt (0)
178 , _was_seamless (Config->get_seamless_loop ())
179 , _under_nsm_control (false)
181 , delta_accumulator_cnt (0)
182 , average_slave_delta (1800) // !!! why 1800 ???
184 , have_first_delta_accumulator (false)
185 , _slave_state (Stopped)
186 , post_export_sync (false)
187 , post_export_position (0)
189 , _export_started (false)
190 , _export_rolling (false)
191 , _pre_export_mmc_enabled (false)
192 , _name (snapshot_name)
194 , _send_qf_mtc (false)
195 , _pframes_since_last_mtc (0)
196 , session_midi_feedback (0)
198 , loop_changing (false)
200 , _session_dir (new SessionDirectory (fullpath))
201 , _current_snapshot_name (snapshot_name)
203 , state_was_pending (false)
204 , _state_of_the_state (StateOfTheState(CannotSave|InitialConnecting|Loading))
206 , _save_queued (false)
207 , _last_roll_location (0)
208 , _last_roll_or_reversal_location (0)
209 , _last_record_location (0)
210 , pending_locate_roll (false)
211 , pending_locate_frame (0)
212 , pending_locate_flush (false)
213 , pending_abort (false)
214 , pending_auto_loop (false)
215 , _butler (new Butler (*this))
216 , _post_transport_work (0)
217 , cumulative_rf_motion (0)
219 , _locations (new Locations (*this))
220 , _ignore_skips_updates (false)
221 , _rt_thread_active (false)
222 , _rt_emit_pending (false)
224 , outbound_mtc_timecode_frame (0)
225 , next_quarter_frame_to_send (-1)
226 , _frames_per_timecode_frame (0)
227 , _frames_per_hour (0)
228 , _timecode_frames_per_hour (0)
229 , last_timecode_valid (false)
230 , last_timecode_when (0)
231 , _send_timecode_update (false)
243 , ltc_timecode_offset (0)
244 , ltc_timecode_negative_offset (false)
245 , midi_control_ui (0)
247 , _all_route_group (new RouteGroup (*this, "all"))
248 , routes (new RouteList)
249 , _adding_routes_in_progress (false)
250 , destructive_index (0)
251 , _track_number_decimals(1)
252 , solo_update_disabled (false)
253 , default_fade_steepness (0)
254 , default_fade_msecs (0)
255 , _total_free_4k_blocks (0)
256 , _total_free_4k_blocks_uncertain (false)
257 , no_questions_about_missing_files (false)
260 , _bundles (new BundleList)
261 , _bundle_xml_node (0)
265 , click_emphasis_data (0)
267 , click_emphasis_length (0)
268 , _clicks_cleared (0)
269 , _play_range (false)
271 , first_file_data_format_reset (true)
272 , first_file_header_format_reset (true)
273 , have_looped (false)
274 , _have_rec_enabled_track (false)
275 , _have_rec_disabled_track (true)
277 , _suspend_timecode_transmission (0)
278 , _speakers (new Speakers)
280 , ignore_route_processor_changes (false)
287 pthread_mutex_init (&_rt_emit_mutex, 0);
288 pthread_cond_init (&_rt_emit_cond, 0);
290 pre_engine_init (fullpath);
293 if (ensure_engine (sr)) {
295 throw failed_constructor ();
298 if (create (mix_template, bus_profile)) {
300 throw failed_constructor ();
303 /* if a mix template was provided, then ::create() will
304 * have copied it into the session and we need to load it
305 * so that we have the state ready for ::set_state()
306 * after the engine is started.
308 * Note that we do NOT try to get the sample rate from
309 * the template at this time, though doing so would
310 * be easy if we decided this was an appropriate part
314 if (!mix_template.empty()) {
315 if (load_state (_current_snapshot_name)) {
316 throw failed_constructor ();
318 store_recent_templates (mix_template);
321 /* load default session properties - if any */
326 if (load_state (_current_snapshot_name)) {
327 throw failed_constructor ();
330 /* try to get sample rate from XML state so that we
331 * can influence the SR if we set up the audio
336 const XMLProperty* prop;
337 if ((prop = state_tree->root()->property (X_("sample-rate"))) != 0) {
338 sr = atoi (prop->value());
342 if (ensure_engine (sr)) {
344 throw failed_constructor ();
348 if (post_engine_init ()) {
350 throw failed_constructor ();
353 store_recent_sessions (_name, _path);
355 bool was_dirty = dirty();
357 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
359 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
360 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
363 DirtyChanged (); /* EMIT SIGNAL */
366 StartTimeChanged.connect_same_thread (*this, boost::bind (&Session::start_time_changed, this, _1));
367 EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
371 emit_thread_start ();
373 /* hook us up to the engine since we are now completely constructed */
375 BootMessage (_("Connect to engine"));
377 _engine.set_session (this);
378 _engine.reset_timebase ();
380 BootMessage (_("Session loading complete"));
393 Session::ensure_engine (uint32_t desired_sample_rate)
395 if (_engine.current_backend() == 0) {
396 /* backend is unknown ... */
397 boost::optional<int> r = AudioEngineSetupRequired (desired_sample_rate);
398 if (r.get_value_or (-1) != 0) {
401 } else if (_engine.setup_required()) {
402 /* backend is known, but setup is needed */
403 boost::optional<int> r = AudioEngineSetupRequired (desired_sample_rate);
404 if (r.get_value_or (-1) != 0) {
407 } else if (!_engine.running()) {
408 if (_engine.start()) {
413 /* at this point the engine should be running
416 if (!_engine.running()) {
420 return immediately_post_engine ();
425 Session::immediately_post_engine ()
427 /* Do various initializations that should take place directly after we
428 * know that the engine is running, but before we either create a
429 * session or set state for an existing one.
432 if (how_many_dsp_threads () > 1) {
433 /* For now, only create the graph if we are using >1 DSP threads, as
434 it is a bit slower than the old code with 1 thread.
436 _process_graph.reset (new Graph (*this));
439 /* every time we reconnect, recompute worst case output latencies */
441 _engine.Running.connect_same_thread (*this, boost::bind (&Session::initialize_latencies, this));
443 if (synced_to_engine()) {
444 _engine.transport_stop ();
447 if (config.get_jack_time_master()) {
448 _engine.transport_locate (_transport_frame);
452 BootMessage (_("Set up LTC"));
454 BootMessage (_("Set up Click"));
456 BootMessage (_("Set up standard connections"));
460 catch (failed_constructor& err) {
464 /* TODO, connect in different thread. (PortRegisteredOrUnregistered may be in RT context)
466 _engine.PortRegisteredOrUnregistered.connect_same_thread (*this, boost::bind (&Session::setup_bundles, this));
474 vector<void*> debug_pointers;
476 /* if we got to here, leaving pending capture state around
480 remove_pending_capture_state ();
482 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
484 /* disconnect from any and all signals that we are connected to */
488 _engine.remove_session ();
490 /* deregister all ports - there will be no process or any other
491 * callbacks from the engine any more.
494 Port::PortDrop (); /* EMIT SIGNAL */
498 /* clear history so that no references to objects are held any more */
502 /* clear state tree so that no references to objects are held any more */
507 /* reset dynamic state version back to default */
509 Stateful::loading_state_version = 0;
511 _butler->drop_references ();
515 delete _all_route_group;
517 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
518 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
522 if (click_data != default_click) {
523 delete [] click_data;
526 if (click_emphasis_data != default_click_emphasis) {
527 delete [] click_emphasis_data;
532 /* need to remove auditioner before monitoring section
533 * otherwise it is re-connected */
536 /* drop references to routes held by the monitoring section
537 * specifically _monitor_out aux/listen references */
538 remove_monitor_section();
540 /* clear out any pending dead wood from RCU managed objects */
545 AudioDiskstream::free_working_buffers();
547 /* tell everyone who is still standing that we're about to die */
550 /* tell everyone to drop references and delete objects as we go */
552 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
553 RegionFactory::delete_all_regions ();
555 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
557 /* reset these three references to special routes before we do the usual route delete thing */
559 _master_out.reset ();
560 _monitor_out.reset ();
563 RCUWriter<RouteList> writer (routes);
564 boost::shared_ptr<RouteList> r = writer.get_copy ();
566 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
567 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
568 (*i)->drop_references ();
572 /* writer goes out of scope and updates master */
577 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
578 Glib::Threads::Mutex::Lock lm (source_lock);
579 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
580 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count()));
581 i->second->drop_references ();
587 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
590 emit_thread_terminate ();
592 pthread_cond_destroy (&_rt_emit_cond);
593 pthread_mutex_destroy (&_rt_emit_mutex);
595 delete _scene_changer; _scene_changer = 0;
596 delete midi_control_ui; midi_control_ui = 0;
598 delete _mmc; _mmc = 0;
599 delete _midi_ports; _midi_ports = 0;
600 delete _locations; _locations = 0;
604 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
606 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
607 boost_debug_list_ptrs ();
612 Session::setup_ltc ()
616 _ltc_input.reset (new IO (*this, X_("LTC In"), IO::Input));
617 _ltc_output.reset (new IO (*this, X_("LTC Out"), IO::Output));
619 if (state_tree && (child = find_named_node (*state_tree->root(), X_("LTC In"))) != 0) {
620 _ltc_input->set_state (*(child->children().front()), Stateful::loading_state_version);
623 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
624 _ltc_input->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
626 reconnect_ltc_input ();
629 if (state_tree && (child = find_named_node (*state_tree->root(), X_("LTC Out"))) != 0) {
630 _ltc_output->set_state (*(child->children().front()), Stateful::loading_state_version);
633 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
634 _ltc_output->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
636 reconnect_ltc_output ();
639 /* fix up names of LTC ports because we don't want the normal
640 * IO style of NAME/TYPE-{in,out}N
643 _ltc_input->nth (0)->set_name (X_("LTC-in"));
644 _ltc_output->nth (0)->set_name (X_("LTC-out"));
648 Session::setup_click ()
651 _click_io.reset (new ClickIO (*this, X_("Click")));
652 _click_gain.reset (new Amp (*this));
653 _click_gain->activate ();
655 setup_click_state (state_tree->root());
657 setup_click_state (0);
662 Session::setup_click_state (const XMLNode* node)
664 const XMLNode* child = 0;
666 if (node && (child = find_named_node (*node, "Click")) != 0) {
668 /* existing state for Click */
671 if (Stateful::loading_state_version < 3000) {
672 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
674 const XMLNodeList& children (child->children());
675 XMLNodeList::const_iterator i = children.begin();
676 if ((c = _click_io->set_state (**i, Stateful::loading_state_version)) == 0) {
678 if (i != children.end()) {
679 c = _click_gain->set_state (**i, Stateful::loading_state_version);
685 _clicking = Config->get_clicking ();
689 error << _("could not setup Click I/O") << endmsg;
696 /* default state for Click: dual-mono to first 2 physical outputs */
699 _engine.get_physical_outputs (DataType::AUDIO, outs);
701 for (uint32_t physport = 0; physport < 2; ++physport) {
702 if (outs.size() > physport) {
703 if (_click_io->add_port (outs[physport], this)) {
704 // relax, even though its an error
709 if (_click_io->n_ports () > ChanCount::ZERO) {
710 _clicking = Config->get_clicking ();
716 Session::setup_bundles ()
720 RCUWriter<BundleList> writer (_bundles);
721 boost::shared_ptr<BundleList> b = writer.get_copy ();
722 for (BundleList::iterator i = b->begin(); i != b->end();) {
723 if (boost::dynamic_pointer_cast<UserBundle>(*i)) {
731 vector<string> inputs[DataType::num_types];
732 vector<string> outputs[DataType::num_types];
733 for (uint32_t i = 0; i < DataType::num_types; ++i) {
734 _engine.get_physical_inputs (DataType (DataType::Symbol (i)), inputs[i]);
735 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
738 /* Create a set of Bundle objects that map
739 to the physical I/O currently available. We create both
740 mono and stereo bundles, so that the common cases of mono
741 and stereo tracks get bundles to put in their mixer strip
742 in / out menus. There may be a nicer way of achieving that;
743 it doesn't really scale that well to higher channel counts
746 /* mono output bundles */
748 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
750 std::string pn = _engine.get_pretty_name_by_name (outputs[DataType::AUDIO][np]);
752 snprintf (buf, sizeof (buf), _("out %s"), pn.substr(0,12).c_str());
754 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
757 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
758 c->add_channel (_("mono"), DataType::AUDIO);
759 c->set_port (0, outputs[DataType::AUDIO][np]);
761 add_bundle (c, false);
764 /* stereo output bundles */
766 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
767 if (np + 1 < outputs[DataType::AUDIO].size()) {
769 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
770 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
771 c->add_channel (_("L"), DataType::AUDIO);
772 c->set_port (0, outputs[DataType::AUDIO][np]);
773 c->add_channel (_("R"), DataType::AUDIO);
774 c->set_port (1, outputs[DataType::AUDIO][np + 1]);
776 add_bundle (c, false);
780 /* mono input bundles */
782 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
784 std::string pn = _engine.get_pretty_name_by_name (inputs[DataType::AUDIO][np]);
786 snprintf (buf, sizeof (buf), _("in %s"), pn.substr(0,12).c_str());
788 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
791 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
792 c->add_channel (_("mono"), DataType::AUDIO);
793 c->set_port (0, inputs[DataType::AUDIO][np]);
795 add_bundle (c, false);
798 /* stereo input bundles */
800 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
801 if (np + 1 < inputs[DataType::AUDIO].size()) {
803 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
805 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
806 c->add_channel (_("L"), DataType::AUDIO);
807 c->set_port (0, inputs[DataType::AUDIO][np]);
808 c->add_channel (_("R"), DataType::AUDIO);
809 c->set_port (1, inputs[DataType::AUDIO][np + 1]);
811 add_bundle (c, false);
815 /* MIDI input bundles */
817 for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
818 string n = inputs[DataType::MIDI][np];
819 std::string pn = _engine.get_pretty_name_by_name (n);
823 boost::erase_first (n, X_("alsa_pcm:"));
825 boost::shared_ptr<Bundle> c (new Bundle (n, false));
826 c->add_channel ("", DataType::MIDI);
827 c->set_port (0, inputs[DataType::MIDI][np]);
828 add_bundle (c, false);
831 /* MIDI output bundles */
833 for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
834 string n = outputs[DataType::MIDI][np];
835 std::string pn = _engine.get_pretty_name_by_name (n);
839 boost::erase_first (n, X_("alsa_pcm:"));
841 boost::shared_ptr<Bundle> c (new Bundle (n, true));
842 c->add_channel ("", DataType::MIDI);
843 c->set_port (0, outputs[DataType::MIDI][np]);
844 add_bundle (c, false);
847 // we trust the backend to only calls us if there's a change
848 BundleAddedOrRemoved (); /* EMIT SIGNAL */
852 Session::auto_connect_master_bus ()
854 if (!_master_out || !Config->get_auto_connect_standard_busses() || _monitor_out) {
858 /* if requested auto-connect the outputs to the first N physical ports.
861 uint32_t limit = _master_out->n_outputs().n_total();
862 vector<string> outputs[DataType::num_types];
864 for (uint32_t i = 0; i < DataType::num_types; ++i) {
865 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
868 for (uint32_t n = 0; n < limit; ++n) {
869 boost::shared_ptr<Port> p = _master_out->output()->nth (n);
871 if (outputs[p->type()].size() > n) {
872 connect_to = outputs[p->type()][n];
875 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
876 if (_master_out->output()->connect (p, connect_to, this)) {
877 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
886 Session::remove_monitor_section ()
892 /* force reversion to Solo-In-Place */
893 Config->set_solo_control_is_listen_control (false);
895 /* if we are auditioning, cancel it ... this is a workaround
896 to a problem (auditioning does not execute the process graph,
897 which is needed to remove routes when using >1 core for processing)
902 /* Hold process lock while doing this so that we don't hear bits and
903 * pieces of audio as we work on each route.
906 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
908 /* Connect tracks to monitor section. Note that in an
909 existing session, the internal sends will already exist, but we want the
910 routes to notice that they connect to the control out specifically.
914 boost::shared_ptr<RouteList> r = routes.reader ();
915 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
917 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
919 if ((*x)->is_monitor()) {
921 } else if ((*x)->is_master()) {
924 (*x)->remove_aux_or_listen (_monitor_out);
929 remove_route (_monitor_out);
930 auto_connect_master_bus ();
933 auditioner->connect ();
938 Session::add_monitor_section ()
942 if (_monitor_out || !_master_out) {
946 boost::shared_ptr<Route> r (new Route (*this, _("Monitor"), Route::MonitorOut, DataType::AUDIO));
952 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
953 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
956 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
957 r->input()->ensure_io (_master_out->output()->n_ports(), false, this);
958 r->output()->ensure_io (_master_out->output()->n_ports(), false, this);
962 add_routes (rl, false, false, false);
964 assert (_monitor_out);
966 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
967 are undefined, at best.
970 uint32_t limit = _monitor_out->n_inputs().n_audio();
974 /* connect the inputs to the master bus outputs. this
975 * represents a separate data feed from the internal sends from
976 * each route. as of jan 2011, it allows the monitor section to
977 * conditionally ignore either the internal sends or the normal
978 * input feed, but we should really find a better way to do
982 _master_out->output()->disconnect (this);
984 for (uint32_t n = 0; n < limit; ++n) {
985 boost::shared_ptr<AudioPort> p = _monitor_out->input()->ports().nth_audio_port (n);
986 boost::shared_ptr<AudioPort> o = _master_out->output()->ports().nth_audio_port (n);
989 string connect_to = o->name();
990 if (_monitor_out->input()->connect (p, connect_to, this)) {
991 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
999 /* if monitor section is not connected, connect it to physical outs
1002 if (Config->get_auto_connect_standard_busses() && !_monitor_out->output()->connected ()) {
1004 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
1006 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
1009 _monitor_out->output()->connect_ports_to_bundle (b, true, this);
1011 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
1012 Config->get_monitor_bus_preferred_bundle())
1018 /* Monitor bus is audio only */
1020 vector<string> outputs[DataType::num_types];
1022 for (uint32_t i = 0; i < DataType::num_types; ++i) {
1023 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
1026 uint32_t mod = outputs[DataType::AUDIO].size();
1027 uint32_t limit = _monitor_out->n_outputs().get (DataType::AUDIO);
1031 for (uint32_t n = 0; n < limit; ++n) {
1033 boost::shared_ptr<Port> p = _monitor_out->output()->ports().port(DataType::AUDIO, n);
1035 if (outputs[DataType::AUDIO].size() > (n % mod)) {
1036 connect_to = outputs[DataType::AUDIO][n % mod];
1039 if (!connect_to.empty()) {
1040 if (_monitor_out->output()->connect (p, connect_to, this)) {
1041 error << string_compose (
1042 _("cannot connect control output %1 to %2"),
1053 /* Hold process lock while doing this so that we don't hear bits and
1054 * pieces of audio as we work on each route.
1057 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1059 /* Connect tracks to monitor section. Note that in an
1060 existing session, the internal sends will already exist, but we want the
1061 routes to notice that they connect to the control out specifically.
1065 boost::shared_ptr<RouteList> rls = routes.reader ();
1067 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
1069 for (RouteList::iterator x = rls->begin(); x != rls->end(); ++x) {
1071 if ((*x)->is_monitor()) {
1073 } else if ((*x)->is_master()) {
1076 (*x)->enable_monitor_send ();
1081 auditioner->connect ();
1086 Session::reset_monitor_section ()
1088 /* Process lock should be held by the caller.*/
1090 if (!_monitor_out) {
1094 uint32_t limit = _master_out->n_outputs().n_audio();
1096 /* connect the inputs to the master bus outputs. this
1097 * represents a separate data feed from the internal sends from
1098 * each route. as of jan 2011, it allows the monitor section to
1099 * conditionally ignore either the internal sends or the normal
1100 * input feed, but we should really find a better way to do
1104 _master_out->output()->disconnect (this);
1105 _monitor_out->output()->disconnect (this);
1107 _monitor_out->input()->ensure_io (_master_out->output()->n_ports(), false, this);
1108 _monitor_out->output()->ensure_io (_master_out->output()->n_ports(), false, this);
1110 for (uint32_t n = 0; n < limit; ++n) {
1111 boost::shared_ptr<AudioPort> p = _monitor_out->input()->ports().nth_audio_port (n);
1112 boost::shared_ptr<AudioPort> o = _master_out->output()->ports().nth_audio_port (n);
1115 string connect_to = o->name();
1116 if (_monitor_out->input()->connect (p, connect_to, this)) {
1117 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
1124 /* connect monitor section to physical outs
1127 if (Config->get_auto_connect_standard_busses()) {
1129 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
1131 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
1134 _monitor_out->output()->connect_ports_to_bundle (b, true, this);
1136 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
1137 Config->get_monitor_bus_preferred_bundle())
1143 /* Monitor bus is audio only */
1145 vector<string> outputs[DataType::num_types];
1147 for (uint32_t i = 0; i < DataType::num_types; ++i) {
1148 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
1151 uint32_t mod = outputs[DataType::AUDIO].size();
1152 uint32_t limit = _monitor_out->n_outputs().get (DataType::AUDIO);
1156 for (uint32_t n = 0; n < limit; ++n) {
1158 boost::shared_ptr<Port> p = _monitor_out->output()->ports().port(DataType::AUDIO, n);
1160 if (outputs[DataType::AUDIO].size() > (n % mod)) {
1161 connect_to = outputs[DataType::AUDIO][n % mod];
1164 if (!connect_to.empty()) {
1165 if (_monitor_out->output()->connect (p, connect_to, this)) {
1166 error << string_compose (
1167 _("cannot connect control output %1 to %2"),
1178 /* Connect tracks to monitor section. Note that in an
1179 existing session, the internal sends will already exist, but we want the
1180 routes to notice that they connect to the control out specifically.
1184 boost::shared_ptr<RouteList> rls = routes.reader ();
1186 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
1188 for (RouteList::iterator x = rls->begin(); x != rls->end(); ++x) {
1190 if ((*x)->is_monitor()) {
1192 } else if ((*x)->is_master()) {
1195 (*x)->enable_monitor_send ();
1201 Session::hookup_io ()
1203 /* stop graph reordering notifications from
1204 causing resorts, etc.
1207 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
1211 /* we delay creating the auditioner till now because
1212 it makes its own connections to ports.
1216 boost::shared_ptr<Auditioner> a (new Auditioner (*this));
1218 throw failed_constructor ();
1220 a->use_new_diskstream ();
1224 catch (failed_constructor& err) {
1225 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
1229 /* load bundles, which we may have postponed earlier on */
1230 if (_bundle_xml_node) {
1231 load_bundles (*_bundle_xml_node);
1232 delete _bundle_xml_node;
1235 /* Tell all IO objects to connect themselves together */
1237 IO::enable_connecting ();
1239 /* Now tell all "floating" ports to connect to whatever
1240 they should be connected to.
1243 AudioEngine::instance()->reconnect_ports ();
1245 /* Anyone who cares about input state, wake up and do something */
1247 IOConnectionsComplete (); /* EMIT SIGNAL */
1249 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
1251 /* now handle the whole enchilada as if it was one
1252 graph reorder event.
1257 /* update the full solo state, which can't be
1258 correctly determined on a per-route basis, but
1259 needs the global overview that only the session
1263 update_route_solo_state ();
1267 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
1269 boost::shared_ptr<Track> track = wp.lock ();
1274 boost::shared_ptr<Playlist> playlist;
1276 if ((playlist = track->playlist()) != 0) {
1277 playlist->RegionAdded.connect_same_thread (*this, boost::bind (&Session::playlist_region_added, this, _1));
1278 playlist->RangesMoved.connect_same_thread (*this, boost::bind (&Session::playlist_ranges_moved, this, _1));
1279 playlist->RegionsExtended.connect_same_thread (*this, boost::bind (&Session::playlist_regions_extended, this, _1));
1284 Session::record_enabling_legal () const
1286 /* this used to be in here, but survey says.... we don't need to restrict it */
1287 // if (record_status() == Recording) {
1291 if (Config->get_all_safe()) {
1298 Session::set_track_monitor_input_status (bool yn)
1300 boost::shared_ptr<RouteList> rl = routes.reader ();
1301 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1302 boost::shared_ptr<AudioTrack> tr = boost::dynamic_pointer_cast<AudioTrack> (*i);
1303 if (tr && tr->record_enabled ()) {
1304 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1305 tr->request_input_monitoring (yn);
1311 Session::auto_punch_start_changed (Location* location)
1313 replace_event (SessionEvent::PunchIn, location->start());
1315 if (get_record_enabled() && config.get_punch_in()) {
1316 /* capture start has been changed, so save new pending state */
1317 save_state ("", true);
1322 Session::auto_punch_end_changed (Location* location)
1324 framepos_t when_to_stop = location->end();
1325 // when_to_stop += _worst_output_latency + _worst_input_latency;
1326 replace_event (SessionEvent::PunchOut, when_to_stop);
1330 Session::auto_punch_changed (Location* location)
1332 framepos_t when_to_stop = location->end();
1334 replace_event (SessionEvent::PunchIn, location->start());
1335 //when_to_stop += _worst_output_latency + _worst_input_latency;
1336 replace_event (SessionEvent::PunchOut, when_to_stop);
1339 /** @param loc A loop location.
1340 * @param pos Filled in with the start time of the required fade-out (in session frames).
1341 * @param length Filled in with the length of the required fade-out.
1344 Session::auto_loop_declick_range (Location* loc, framepos_t & pos, framepos_t & length)
1346 pos = max (loc->start(), loc->end() - 64);
1347 length = loc->end() - pos;
1351 Session::auto_loop_changed (Location* location)
1353 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
1356 auto_loop_declick_range (location, dcp, dcl);
1358 if (transport_rolling() && play_loop) {
1360 replace_event (SessionEvent::AutoLoopDeclick, dcp, dcl);
1362 // if (_transport_frame > location->end()) {
1364 if (_transport_frame < location->start() || _transport_frame > location->end()) {
1365 // relocate to beginning of loop
1366 clear_events (SessionEvent::LocateRoll);
1368 request_locate (location->start(), true);
1371 else if (Config->get_seamless_loop() && !loop_changing) {
1373 // schedule a locate-roll to refill the diskstreams at the
1374 // previous loop end
1375 loop_changing = true;
1377 if (location->end() > last_loopend) {
1378 clear_events (SessionEvent::LocateRoll);
1379 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
1385 clear_events (SessionEvent::AutoLoopDeclick);
1386 clear_events (SessionEvent::AutoLoop);
1389 last_loopend = location->end();
1394 Session::set_auto_punch_location (Location* location)
1398 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
1399 punch_connections.drop_connections();
1400 existing->set_auto_punch (false, this);
1401 remove_event (existing->start(), SessionEvent::PunchIn);
1402 clear_events (SessionEvent::PunchOut);
1403 auto_punch_location_changed (0);
1408 if (location == 0) {
1412 if (location->end() <= location->start()) {
1413 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1417 punch_connections.drop_connections ();
1419 location->StartChanged.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, location));
1420 location->EndChanged.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, location));
1421 location->Changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, location));
1423 location->set_auto_punch (true, this);
1425 auto_punch_changed (location);
1427 auto_punch_location_changed (location);
1431 Session::set_session_extents (framepos_t start, framepos_t end)
1434 if ((existing = _locations->session_range_location()) == 0) {
1435 //if there is no existing session, we need to make a new session location (should never happen)
1436 existing = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1440 error << _("Session: you can't use that location for session start/end)") << endmsg;
1444 existing->set( start, end );
1450 Session::set_auto_loop_location (Location* location)
1454 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
1455 loop_connections.drop_connections ();
1456 existing->set_auto_loop (false, this);
1457 remove_event (existing->end(), SessionEvent::AutoLoop);
1460 auto_loop_declick_range (existing, dcp, dcl);
1461 remove_event (dcp, SessionEvent::AutoLoopDeclick);
1462 auto_loop_location_changed (0);
1467 if (location == 0) {
1471 if (location->end() <= location->start()) {
1472 error << _("You cannot use this location for auto-loop because it has zero or negative length") << endmsg;
1476 last_loopend = location->end();
1478 loop_connections.drop_connections ();
1480 location->StartChanged.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, location));
1481 location->EndChanged.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, location));
1482 location->Changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, location));
1484 location->set_auto_loop (true, this);
1486 /* take care of our stuff first */
1488 auto_loop_changed (location);
1490 /* now tell everyone else */
1492 auto_loop_location_changed (location);
1496 Session::update_loop (Location*)
1502 Session::update_marks (Location*)
1508 Session::update_skips (Location* loc, bool consolidate)
1510 if (_ignore_skips_updates) {
1514 Locations::LocationList skips;
1517 PBD::Unwinder<bool> uw (_ignore_skips_updates, true);
1518 consolidate_skips (loc);
1521 sync_locations_to_skips ();
1527 Session::consolidate_skips (Location* loc)
1529 Locations::LocationList all_locations = _locations->list ();
1531 for (Locations::LocationList::iterator l = all_locations.begin(); l != all_locations.end(); ) {
1533 if (!(*l)->is_skip ()) {
1538 /* don't test against self */
1545 switch (Evoral::coverage ((*l)->start(), (*l)->end(), loc->start(), loc->end())) {
1546 case Evoral::OverlapInternal:
1547 case Evoral::OverlapExternal:
1548 case Evoral::OverlapStart:
1549 case Evoral::OverlapEnd:
1550 /* adjust new location to cover existing one */
1551 loc->set_start (min (loc->start(), (*l)->start()));
1552 loc->set_end (max (loc->end(), (*l)->end()));
1553 /* we don't need this one any more */
1554 _locations->remove (*l);
1555 /* the location has been deleted, so remove reference to it in our local list */
1556 l = all_locations.erase (l);
1559 case Evoral::OverlapNone:
1567 Session::sync_locations_to_skips ()
1569 /* This happens asynchronously (in the audioengine thread). After the clear is done, we will call
1570 * Session::_sync_locations_to_skips() from the audioengine thread.
1572 clear_events (SessionEvent::Skip, boost::bind (&Session::_sync_locations_to_skips, this));
1576 Session::_sync_locations_to_skips ()
1578 /* called as a callback after existing Skip events have been cleared from a realtime audioengine thread */
1580 Locations::LocationList const & locs (_locations->list());
1582 for (Locations::LocationList::const_iterator i = locs.begin(); i != locs.end(); ++i) {
1584 Location* location = *i;
1586 if (location->is_skip() && location->is_skipping()) {
1587 SessionEvent* ev = new SessionEvent (SessionEvent::Skip, SessionEvent::Add, location->start(), location->end(), 1.0);
1595 Session::location_added (Location *location)
1597 if (location->is_auto_punch()) {
1598 set_auto_punch_location (location);
1601 if (location->is_auto_loop()) {
1602 set_auto_loop_location (location);
1605 if (location->is_session_range()) {
1606 /* no need for any signal handling or event setting with the session range,
1607 because we keep a direct reference to it and use its start/end directly.
1609 _session_range_location = location;
1612 if (location->is_mark()) {
1613 /* listen for per-location signals that require us to do any * global updates for marks */
1615 location->StartChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1616 location->EndChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1617 location->Changed.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1618 location->FlagsChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1621 if (location->is_skip()) {
1622 /* listen for per-location signals that require us to update skip-locate events */
1624 location->StartChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_skips, this, location, true));
1625 location->EndChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_skips, this, location, true));
1626 location->Changed.connect_same_thread (skip_update_connections, boost::bind (&Session::update_skips, this, location, true));
1627 location->FlagsChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_skips, this, location, false));
1629 update_skips (location, true);
1636 Session::location_removed (Location *location)
1638 if (location->is_auto_loop()) {
1639 set_auto_loop_location (0);
1640 set_track_loop (false);
1643 if (location->is_auto_punch()) {
1644 set_auto_punch_location (0);
1647 if (location->is_session_range()) {
1648 /* this is never supposed to happen */
1649 error << _("programming error: session range removed!") << endl;
1652 if (location->is_skip()) {
1654 update_skips (location, false);
1661 Session::locations_changed ()
1663 _locations->apply (*this, &Session::_locations_changed);
1667 Session::_locations_changed (const Locations::LocationList& locations)
1669 /* There was some mass-change in the Locations object.
1671 We might be re-adding a location here but it doesn't actually matter
1672 for all the locations that the Session takes an interest in.
1675 for (Locations::LocationList::const_iterator i = locations.begin(); i != locations.end(); ++i) {
1676 location_added (*i);
1681 Session::enable_record ()
1683 if (_transport_speed != 0.0 && _transport_speed != 1.0) {
1684 /* no recording at anything except normal speed */
1689 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1691 if (rs == Recording) {
1695 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1697 _last_record_location = _transport_frame;
1698 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1700 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1701 set_track_monitor_input_status (true);
1704 RecordStateChanged ();
1711 Session::disable_record (bool rt_context, bool force)
1715 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1717 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1718 g_atomic_int_set (&_record_status, Disabled);
1719 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1721 if (rs == Recording) {
1722 g_atomic_int_set (&_record_status, Enabled);
1726 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1727 set_track_monitor_input_status (false);
1730 RecordStateChanged (); /* emit signal */
1733 remove_pending_capture_state ();
1739 Session::step_back_from_record ()
1741 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1743 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1744 set_track_monitor_input_status (false);
1747 RecordStateChanged (); /* emit signal */
1752 Session::maybe_enable_record ()
1754 if (_step_editors > 0) {
1758 g_atomic_int_set (&_record_status, Enabled);
1760 /* This function is currently called from somewhere other than an RT thread.
1761 This save_state() call therefore doesn't impact anything. Doing it here
1762 means that we save pending state of which sources the next record will use,
1763 which gives us some chance of recovering from a crash during the record.
1766 save_state ("", true);
1768 if (_transport_speed) {
1769 if (!config.get_punch_in()) {
1773 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1774 RecordStateChanged (); /* EMIT SIGNAL */
1781 Session::audible_frame () const
1787 offset = worst_playback_latency ();
1789 if (synced_to_engine()) {
1790 /* Note: this is basically just sync-to-JACK */
1791 tf = _engine.transport_frame();
1793 tf = _transport_frame;
1798 if (!non_realtime_work_pending()) {
1802 /* Check to see if we have passed the first guaranteed
1803 audible frame past our last start position. if not,
1804 return that last start point because in terms
1805 of audible frames, we have not moved yet.
1807 `Start position' in this context means the time we last
1808 either started, located, or changed transport direction.
1811 if (_transport_speed > 0.0f) {
1813 if (!play_loop || !have_looped) {
1814 if (tf < _last_roll_or_reversal_location + offset) {
1815 return _last_roll_or_reversal_location;
1823 } else if (_transport_speed < 0.0f) {
1825 /* XXX wot? no backward looping? */
1827 if (tf > _last_roll_or_reversal_location - offset) {
1828 return _last_roll_or_reversal_location;
1840 Session::set_frame_rate (framecnt_t frames_per_second)
1842 /** \fn void Session::set_frame_size(framecnt_t)
1843 the AudioEngine object that calls this guarantees
1844 that it will not be called while we are also in
1845 ::process(). Its fine to do things that block
1849 _base_frame_rate = frames_per_second;
1850 _nominal_frame_rate = frames_per_second;
1856 // XXX we need some equivalent to this, somehow
1857 // SndFileSource::setup_standard_crossfades (frames_per_second);
1861 /* XXX need to reset/reinstantiate all LADSPA plugins */
1865 Session::set_block_size (pframes_t nframes)
1867 /* the AudioEngine guarantees
1868 that it will not be called while we are also in
1869 ::process(). It is therefore fine to do things that block
1874 current_block_size = nframes;
1878 boost::shared_ptr<RouteList> r = routes.reader ();
1880 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1881 (*i)->set_block_size (nframes);
1884 boost::shared_ptr<RouteList> rl = routes.reader ();
1885 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1886 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1888 tr->set_block_size (nframes);
1892 set_worst_io_latencies ();
1898 trace_terminal (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> rbase)
1900 boost::shared_ptr<Route> r2;
1902 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1903 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1907 /* make a copy of the existing list of routes that feed r1 */
1909 Route::FedBy existing (r1->fed_by());
1911 /* for each route that feeds r1, recurse, marking it as feeding
1915 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1916 if (!(r2 = i->r.lock ())) {
1917 /* (*i) went away, ignore it */
1921 /* r2 is a route that feeds r1 which somehow feeds base. mark
1922 base as being fed by r2
1925 rbase->add_fed_by (r2, i->sends_only);
1929 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1933 if (r1->feeds (r2) && r2->feeds (r1)) {
1937 /* now recurse, so that we can mark base as being fed by
1938 all routes that feed r2
1941 trace_terminal (r2, rbase);
1948 Session::resort_routes ()
1950 /* don't do anything here with signals emitted
1951 by Routes during initial setup or while we
1952 are being destroyed.
1955 if (_state_of_the_state & (InitialConnecting | Deletion)) {
1960 RCUWriter<RouteList> writer (routes);
1961 boost::shared_ptr<RouteList> r = writer.get_copy ();
1962 resort_routes_using (r);
1963 /* writer goes out of scope and forces update */
1967 boost::shared_ptr<RouteList> rl = routes.reader ();
1968 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1969 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1971 const Route::FedBy& fb ((*i)->fed_by());
1973 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1974 boost::shared_ptr<Route> sf = f->r.lock();
1976 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1984 /** This is called whenever we need to rebuild the graph of how we will process
1986 * @param r List of routes, in any order.
1990 Session::resort_routes_using (boost::shared_ptr<RouteList> r)
1992 /* We are going to build a directed graph of our routes;
1993 this is where the edges of that graph are put.
1998 /* Go through all routes doing two things:
2000 * 1. Collect the edges of the route graph. Each of these edges
2001 * is a pair of routes, one of which directly feeds the other
2002 * either by a JACK connection or by an internal send.
2004 * 2. Begin the process of making routes aware of which other
2005 * routes directly or indirectly feed them. This information
2006 * is used by the solo code.
2009 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2011 /* Clear out the route's list of direct or indirect feeds */
2012 (*i)->clear_fed_by ();
2014 for (RouteList::iterator j = r->begin(); j != r->end(); ++j) {
2016 bool via_sends_only;
2018 /* See if this *j feeds *i according to the current state of the JACK
2019 connections and internal sends.
2021 if ((*j)->direct_feeds_according_to_reality (*i, &via_sends_only)) {
2022 /* add the edge to the graph (part #1) */
2023 edges.add (*j, *i, via_sends_only);
2024 /* tell the route (for part #2) */
2025 (*i)->add_fed_by (*j, via_sends_only);
2030 /* Attempt a topological sort of the route graph */
2031 boost::shared_ptr<RouteList> sorted_routes = topological_sort (r, edges);
2033 if (sorted_routes) {
2034 /* We got a satisfactory topological sort, so there is no feedback;
2037 Note: the process graph rechain does not require a
2038 topologically-sorted list, but hey ho.
2040 if (_process_graph) {
2041 _process_graph->rechain (sorted_routes, edges);
2044 _current_route_graph = edges;
2046 /* Complete the building of the routes' lists of what directly
2047 or indirectly feeds them.
2049 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2050 trace_terminal (*i, *i);
2053 *r = *sorted_routes;
2056 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
2057 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2058 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
2059 (*i)->name(), (*i)->order_key ()));
2063 SuccessfulGraphSort (); /* EMIT SIGNAL */
2066 /* The topological sort failed, so we have a problem. Tell everyone
2067 and stick to the old graph; this will continue to be processed, so
2068 until the feedback is fixed, what is played back will not quite
2069 reflect what is actually connected. Note also that we do not
2070 do trace_terminal here, as it would fail due to an endless recursion,
2071 so the solo code will think that everything is still connected
2075 FeedbackDetected (); /* EMIT SIGNAL */
2080 /** Find a route name starting with \a base, maybe followed by the
2081 * lowest \a id. \a id will always be added if \a definitely_add_number
2082 * is true on entry; otherwise it will only be added if required
2083 * to make the name unique.
2085 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
2086 * The available route name with the lowest ID will be used, and \a id
2087 * will be set to the ID.
2089 * \return false if a route name could not be found, and \a track_name
2090 * and \a id do not reflect a free route name.
2093 Session::find_route_name (string const & base, uint32_t& id, char* name, size_t name_len, bool definitely_add_number)
2095 if (!definitely_add_number && route_by_name (base) == 0) {
2096 /* juse use the base */
2097 snprintf (name, name_len, "%s", base.c_str());
2102 snprintf (name, name_len, "%s %" PRIu32, base.c_str(), id);
2104 if (route_by_name (name) == 0) {
2110 } while (id < (UINT_MAX-1));
2115 /** Count the total ins and outs of all non-hidden tracks in the session and return them in in and out */
2117 Session::count_existing_track_channels (ChanCount& in, ChanCount& out)
2119 in = ChanCount::ZERO;
2120 out = ChanCount::ZERO;
2122 boost::shared_ptr<RouteList> r = routes.reader ();
2124 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2125 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2126 if (tr && !tr->is_auditioner()) {
2127 in += tr->n_inputs();
2128 out += tr->n_outputs();
2133 /** Caller must not hold process lock
2134 * @param name_template string to use for the start of the name, or "" to use "MIDI".
2135 * @param instrument plugin info for the instrument to insert pre-fader, if any
2137 list<boost::shared_ptr<MidiTrack> >
2138 Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost::shared_ptr<PluginInfo> instrument,
2139 TrackMode mode, RouteGroup* route_group, uint32_t how_many, string name_template)
2141 char track_name[32];
2142 uint32_t track_id = 0;
2144 RouteList new_routes;
2145 list<boost::shared_ptr<MidiTrack> > ret;
2147 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("MIDI");
2150 if (!find_route_name (name_template.empty() ? _("MIDI") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
2151 error << "cannot find name for new midi track" << endmsg;
2155 boost::shared_ptr<MidiTrack> track;
2158 track.reset (new MidiTrack (*this, track_name, Route::Flag (0), mode));
2160 if (track->init ()) {
2164 track->use_new_diskstream();
2166 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
2167 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
2170 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2171 if (track->input()->ensure_io (input, false, this)) {
2172 error << "cannot configure " << input << " out configuration for new midi track" << endmsg;
2176 if (track->output()->ensure_io (output, false, this)) {
2177 error << "cannot configure " << output << " out configuration for new midi track" << endmsg;
2182 track->non_realtime_input_change();
2185 route_group->add (track);
2188 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
2190 if (Config->get_remote_model() == UserOrdered) {
2191 track->set_remote_control_id (next_control_id());
2194 new_routes.push_back (track);
2195 ret.push_back (track);
2198 catch (failed_constructor &err) {
2199 error << _("Session: could not create new midi track.") << endmsg;
2203 catch (AudioEngine::PortRegistrationFailure& pfe) {
2205 error << string_compose (_("No more JACK ports are available. You will need to stop %1 and restart JACK with more ports if you need this many tracks."), PROGRAM_NAME) << endmsg;
2213 if (!new_routes.empty()) {
2214 StateProtector sp (this);
2215 if (Profile->get_trx()) {
2216 add_routes (new_routes, false, false, false);
2218 add_routes (new_routes, true, true, false);
2222 for (RouteList::iterator r = new_routes.begin(); r != new_routes.end(); ++r) {
2223 PluginPtr plugin = instrument->load (*this);
2224 boost::shared_ptr<Processor> p (new PluginInsert (*this, plugin));
2225 (*r)->add_processor (p, PreFader);
2235 Session::midi_output_change_handler (IOChange change, void * /*src*/, boost::weak_ptr<Route> wmt)
2237 boost::shared_ptr<Route> midi_track (wmt.lock());
2243 if ((change.type & IOChange::ConfigurationChanged) && Config->get_output_auto_connect() != ManualConnect) {
2245 if (change.after.n_audio() <= change.before.n_audio()) {
2249 /* new audio ports: make sure the audio goes somewhere useful,
2250 unless the user has no-auto-connect selected.
2252 The existing ChanCounts don't matter for this call as they are only
2253 to do with matching input and output indices, and we are only changing
2259 auto_connect_route (midi_track, dummy, dummy, false, false, ChanCount(), change.before);
2263 /** @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
2264 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
2265 * @param output_start As \a input_start, but for outputs.
2268 Session::auto_connect_route (boost::shared_ptr<Route> route, ChanCount& existing_inputs, ChanCount& existing_outputs,
2269 bool with_lock, bool connect_inputs, ChanCount input_start, ChanCount output_start)
2271 if (!IO::connecting_legal) {
2275 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock (), Glib::Threads::NOT_LOCK);
2281 /* If both inputs and outputs are auto-connected to physical ports,
2282 use the max of input and output offsets to ensure auto-connected
2283 port numbers always match up (e.g. the first audio input and the
2284 first audio output of the route will have the same physical
2285 port number). Otherwise just use the lowest input or output
2289 DEBUG_TRACE (DEBUG::Graph,
2290 string_compose("Auto-connect: existing in = %1 out = %2\n",
2291 existing_inputs, existing_outputs));
2293 const bool in_out_physical =
2294 (Config->get_input_auto_connect() & AutoConnectPhysical)
2295 && (Config->get_output_auto_connect() & AutoConnectPhysical)
2298 const ChanCount in_offset = in_out_physical
2299 ? ChanCount::max(existing_inputs, existing_outputs)
2302 const ChanCount out_offset = in_out_physical
2303 ? ChanCount::max(existing_inputs, existing_outputs)
2306 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2307 vector<string> physinputs;
2308 vector<string> physoutputs;
2310 _engine.get_physical_outputs (*t, physoutputs);
2311 _engine.get_physical_inputs (*t, physinputs);
2313 if (!physinputs.empty() && connect_inputs) {
2314 uint32_t nphysical_in = physinputs.size();
2316 DEBUG_TRACE (DEBUG::Graph,
2317 string_compose("There are %1 physical inputs of type %2\n",
2320 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
2323 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
2324 DEBUG_TRACE (DEBUG::Graph,
2325 string_compose("Get index %1 + %2 % %3 = %4\n",
2326 in_offset.get(*t), i, nphysical_in,
2327 (in_offset.get(*t) + i) % nphysical_in));
2328 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
2331 DEBUG_TRACE (DEBUG::Graph,
2332 string_compose("Connect route %1 IN to %2\n",
2333 route->name(), port));
2335 if (!port.empty() && route->input()->connect (route->input()->ports().port(*t, i), port, this)) {
2339 ChanCount one_added (*t, 1);
2340 existing_inputs += one_added;
2344 if (!physoutputs.empty()) {
2345 uint32_t nphysical_out = physoutputs.size();
2346 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
2349 if ((*t) == DataType::MIDI && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
2350 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
2351 } else if ((*t) == DataType::AUDIO && (Config->get_output_auto_connect() & AutoConnectMaster)) {
2352 /* master bus is audio only */
2353 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
2354 port = _master_out->input()->ports().port(*t,
2355 i % _master_out->input()->n_ports().get(*t))->name();
2359 DEBUG_TRACE (DEBUG::Graph,
2360 string_compose("Connect route %1 OUT to %2\n",
2361 route->name(), port));
2363 if (!port.empty() && route->output()->connect (route->output()->ports().port(*t, i), port, this)) {
2367 ChanCount one_added (*t, 1);
2368 existing_outputs += one_added;
2375 Session::reconnect_existing_routes (bool withLock, bool reconnect_master, bool reconnect_inputs, bool reconnect_outputs)
2377 /* TRX does stuff here, ardour does not (but probably should). This is called after an engine reset (in particular).
2381 #ifdef USE_TRACKS_CODE_FEATURES
2384 Session::reconnect_midi_scene_ports(bool inputs)
2387 scene_in()->disconnect_all ();
2389 std::vector<EngineStateController::MidiPortState> midi_port_states;
2390 EngineStateController::instance()->get_physical_midi_input_states (midi_port_states);
2392 std::vector<EngineStateController::MidiPortState>::iterator state_iter = midi_port_states.begin();
2394 for (; state_iter != midi_port_states.end(); ++state_iter) {
2395 if (state_iter->active && state_iter->available && state_iter->connected) {
2396 scene_in()->connect (state_iter->name);
2401 scene_out()->disconnect_all ();
2403 std::vector<EngineStateController::MidiPortState> midi_port_states;
2404 EngineStateController::instance()->get_physical_midi_output_states (midi_port_states);
2406 std::vector<EngineStateController::MidiPortState>::iterator state_iter = midi_port_states.begin();
2408 for (; state_iter != midi_port_states.end(); ++state_iter) {
2409 if (state_iter->active && state_iter->available && state_iter->connected) {
2410 scene_out()->connect (state_iter->name);
2419 /** Caller must not hold process lock
2420 * @param name_template string to use for the start of the name, or "" to use "Audio".
2422 list< boost::shared_ptr<AudioTrack> >
2423 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group,
2424 uint32_t how_many, string name_template)
2426 char track_name[32];
2427 uint32_t track_id = 0;
2429 RouteList new_routes;
2430 list<boost::shared_ptr<AudioTrack> > ret;
2432 string name_pattern("");
2433 if (Profile->get_trx() ) {
2434 name_pattern = default_trx_track_name_pattern;
2436 name_pattern = default_ardour_track_name_pattern;
2439 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _(name_pattern.c_str() );
2443 if (!find_route_name (name_template.empty() ? _(name_pattern.c_str() ) : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
2444 error << "cannot find name for new audio track" << endmsg;
2448 boost::shared_ptr<AudioTrack> track;
2451 track.reset (new AudioTrack (*this, track_name, Route::Flag (0), mode));
2453 if (track->init ()) {
2457 track->use_new_diskstream();
2459 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
2460 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
2463 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2465 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
2466 error << string_compose (
2467 _("cannot configure %1 in/%2 out configuration for new audio track"),
2468 input_channels, output_channels)
2473 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
2474 error << string_compose (
2475 _("cannot configure %1 in/%2 out configuration for new audio track"),
2476 input_channels, output_channels)
2483 route_group->add (track);
2486 track->non_realtime_input_change();
2488 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
2489 if (Config->get_remote_model() == UserOrdered) {
2490 track->set_remote_control_id (next_control_id());
2493 new_routes.push_back (track);
2494 ret.push_back (track);
2497 catch (failed_constructor &err) {
2498 error << _("Session: could not create new audio track.") << endmsg;
2502 catch (AudioEngine::PortRegistrationFailure& pfe) {
2504 error << pfe.what() << endmsg;
2512 if (!new_routes.empty()) {
2513 StateProtector sp (this);
2514 if (Profile->get_trx()) {
2515 add_routes (new_routes, false, false, false);
2517 add_routes (new_routes, true, true, false);
2524 /** Caller must not hold process lock.
2525 * @param name_template string to use for the start of the name, or "" to use "Bus".
2528 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template)
2531 uint32_t bus_id = 0;
2535 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Bus");
2538 if (!find_route_name (name_template.empty () ? _("Bus") : name_template, ++bus_id, bus_name, sizeof(bus_name), use_number)) {
2539 error << "cannot find name for new audio bus" << endmsg;
2544 boost::shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
2550 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
2551 // boost_debug_shared_ptr_mark_interesting (bus.get(), "Route");
2554 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2556 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
2557 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
2558 input_channels, output_channels)
2564 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
2565 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
2566 input_channels, output_channels)
2573 route_group->add (bus);
2575 if (Config->get_remote_model() == UserOrdered) {
2576 bus->set_remote_control_id (next_control_id());
2579 bus->add_internal_return ();
2581 ret.push_back (bus);
2587 catch (failed_constructor &err) {
2588 error << _("Session: could not create new audio route.") << endmsg;
2592 catch (AudioEngine::PortRegistrationFailure& pfe) {
2593 error << pfe.what() << endmsg;
2603 StateProtector sp (this);
2604 if (Profile->get_trx()) {
2605 add_routes (ret, false, false, false);
2607 add_routes (ret, false, true, true); // autoconnect // outputs only
2616 Session::new_route_from_template (uint32_t how_many, const std::string& template_path, const std::string& name_base)
2619 uint32_t control_id;
2621 uint32_t number = 0;
2622 const uint32_t being_added = how_many;
2624 if (!tree.read (template_path.c_str())) {
2628 XMLNode* node = tree.root();
2630 IO::disable_connecting ();
2632 control_id = next_control_id ();
2636 XMLNode node_copy (*node);
2638 /* Remove IDs of everything so that new ones are used */
2639 node_copy.remove_property_recursively (X_("id"));
2644 if (!name_base.empty()) {
2646 /* if we're adding more than one routes, force
2647 * all the names of the new routes to be
2648 * numbered, via the final parameter.
2651 if (!find_route_name (name_base.c_str(), ++number, name, sizeof(name), (being_added > 1))) {
2652 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2658 string const route_name = node_copy.property(X_("name"))->value ();
2660 /* generate a new name by adding a number to the end of the template name */
2661 if (!find_route_name (route_name.c_str(), ++number, name, sizeof(name), true)) {
2662 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2663 abort(); /*NOTREACHED*/
2667 /* set this name in the XML description that we are about to use */
2668 Route::set_name_in_state (node_copy, name);
2670 /* trim bitslots from listen sends so that new ones are used */
2671 XMLNodeList children = node_copy.children ();
2672 for (XMLNodeList::iterator i = children.begin(); i != children.end(); ++i) {
2673 if ((*i)->name() == X_("Processor")) {
2674 XMLProperty* role = (*i)->property (X_("role"));
2675 if (role && role->value() == X_("Listen")) {
2676 (*i)->remove_property (X_("bitslot"));
2681 boost::shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2684 error << _("Session: cannot create track/bus from template description") << endmsg;
2688 if (boost::dynamic_pointer_cast<Track>(route)) {
2689 /* force input/output change signals so that the new diskstream
2690 picks up the configuration of the route. During session
2691 loading this normally happens in a different way.
2694 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2696 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
2697 change.after = route->input()->n_ports();
2698 route->input()->changed (change, this);
2699 change.after = route->output()->n_ports();
2700 route->output()->changed (change, this);
2703 route->set_remote_control_id (control_id);
2706 ret.push_back (route);
2709 catch (failed_constructor &err) {
2710 error << _("Session: could not create new route from template") << endmsg;
2714 catch (AudioEngine::PortRegistrationFailure& pfe) {
2715 error << pfe.what() << endmsg;
2724 StateProtector sp (this);
2725 if (Profile->get_trx()) {
2726 add_routes (ret, false, false, false);
2728 add_routes (ret, true, true, false);
2730 IO::enable_connecting ();
2737 Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, bool save)
2740 PBD::Unwinder<bool> aip (_adding_routes_in_progress, true);
2741 add_routes_inner (new_routes, input_auto_connect, output_auto_connect);
2744 error << _("Adding new tracks/busses failed") << endmsg;
2749 update_latency (true);
2750 update_latency (false);
2755 save_state (_current_snapshot_name);
2758 reassign_track_numbers();
2760 update_route_record_state ();
2762 RouteAdded (new_routes); /* EMIT SIGNAL */
2766 Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect)
2768 ChanCount existing_inputs;
2769 ChanCount existing_outputs;
2770 uint32_t order = next_control_id();
2772 if (_order_hint > -1) {
2773 order = _order_hint;
2777 count_existing_track_channels (existing_inputs, existing_outputs);
2780 RCUWriter<RouteList> writer (routes);
2781 boost::shared_ptr<RouteList> r = writer.get_copy ();
2782 r->insert (r->end(), new_routes.begin(), new_routes.end());
2784 /* if there is no control out and we're not in the middle of loading,
2785 resort the graph here. if there is a control out, we will resort
2786 toward the end of this method. if we are in the middle of loading,
2787 we will resort when done.
2790 if (!_monitor_out && IO::connecting_legal) {
2791 resort_routes_using (r);
2795 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2797 boost::weak_ptr<Route> wpr (*x);
2798 boost::shared_ptr<Route> r (*x);
2800 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
2801 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
2802 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
2803 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
2804 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
2805 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
2807 if (r->is_master()) {
2811 if (r->is_monitor()) {
2815 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
2817 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
2818 track_playlist_changed (boost::weak_ptr<Track> (tr));
2819 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_route_record_state, this));
2821 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
2823 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
2824 mt->output()->changed.connect_same_thread (*this, boost::bind (&Session::midi_output_change_handler, this, _1, _2, boost::weak_ptr<Route>(mt)));
2829 if (input_auto_connect || output_auto_connect) {
2830 auto_connect_route (r, existing_inputs, existing_outputs, true, input_auto_connect);
2833 /* order keys are a GUI responsibility but we need to set up
2834 reasonable defaults because they also affect the remote control
2835 ID in most situations.
2838 if (!r->has_order_key ()) {
2839 if (r->is_auditioner()) {
2840 /* use an arbitrarily high value */
2841 r->set_order_key (UINT_MAX);
2843 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("while adding, set %1 to order key %2\n", r->name(), order));
2844 r->set_order_key (order);
2852 if (_monitor_out && IO::connecting_legal) {
2853 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
2855 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2856 if ((*x)->is_monitor()) {
2858 } else if ((*x)->is_master()) {
2861 (*x)->enable_monitor_send ();
2868 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2870 boost::shared_ptr<RouteList> r = routes.reader ();
2871 boost::shared_ptr<Send> s;
2873 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2874 if ((s = (*i)->internal_send_for (dest)) != 0) {
2875 s->amp()->gain_control()->set_value (GAIN_COEFF_ZERO);
2881 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2883 boost::shared_ptr<RouteList> r = routes.reader ();
2884 boost::shared_ptr<Send> s;
2886 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2887 if ((s = (*i)->internal_send_for (dest)) != 0) {
2888 s->amp()->gain_control()->set_value (GAIN_COEFF_UNITY);
2894 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2896 boost::shared_ptr<RouteList> r = routes.reader ();
2897 boost::shared_ptr<Send> s;
2899 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2900 if ((s = (*i)->internal_send_for (dest)) != 0) {
2901 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2906 /** @param include_buses true to add sends to buses and tracks, false for just tracks */
2908 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p, bool include_buses)
2910 boost::shared_ptr<RouteList> r = routes.reader ();
2911 boost::shared_ptr<RouteList> t (new RouteList);
2913 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2914 /* no MIDI sends because there are no MIDI busses yet */
2915 if (include_buses || boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2920 add_internal_sends (dest, p, t);
2924 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2926 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2927 add_internal_send (dest, (*i)->before_processor_for_placement (p), *i);
2932 Session::add_internal_send (boost::shared_ptr<Route> dest, int index, boost::shared_ptr<Route> sender)
2934 add_internal_send (dest, sender->before_processor_for_index (index), sender);
2938 Session::add_internal_send (boost::shared_ptr<Route> dest, boost::shared_ptr<Processor> before, boost::shared_ptr<Route> sender)
2940 if (sender->is_monitor() || sender->is_master() || sender == dest || dest->is_monitor() || dest->is_master()) {
2944 if (!dest->internal_return()) {
2945 dest->add_internal_return ();
2948 sender->add_aux_send (dest, before);
2954 Session::remove_route (boost::shared_ptr<Route> route)
2956 if (route == _master_out) {
2960 route->set_solo (false, this);
2963 RCUWriter<RouteList> writer (routes);
2964 boost::shared_ptr<RouteList> rs = writer.get_copy ();
2968 /* deleting the master out seems like a dumb
2969 idea, but its more of a UI policy issue
2973 if (route == _master_out) {
2974 _master_out = boost::shared_ptr<Route> ();
2977 if (route == _monitor_out) {
2978 _monitor_out.reset ();
2981 /* writer goes out of scope, forces route list update */
2984 update_route_solo_state ();
2986 // We need to disconnect the route's inputs and outputs
2988 route->input()->disconnect (0);
2989 route->output()->disconnect (0);
2991 /* if the route had internal sends sending to it, remove them */
2992 if (route->internal_return()) {
2994 boost::shared_ptr<RouteList> r = routes.reader ();
2995 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2996 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2998 (*i)->remove_processor (s);
3003 /* if the monitoring section had a pointer to this route, remove it */
3004 if (_monitor_out && !route->is_master() && !route->is_monitor()) {
3005 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
3006 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
3007 route->remove_aux_or_listen (_monitor_out);
3010 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
3011 if (mt && mt->step_editing()) {
3012 if (_step_editors > 0) {
3017 update_latency_compensation ();
3020 /* Re-sort routes to remove the graph's current references to the one that is
3021 * going away, then flush old references out of the graph.
3025 if (_process_graph) {
3026 _process_graph->clear_other_chain ();
3029 /* get rid of it from the dead wood collection in the route list manager */
3031 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
3035 /* try to cause everyone to drop their references */
3037 route->drop_references ();
3039 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
3041 /* save the new state of the world */
3043 if (save_state (_current_snapshot_name)) {
3044 save_history (_current_snapshot_name);
3046 reassign_track_numbers();
3048 update_route_record_state ();
3052 Session::route_mute_changed (void* /*src*/)
3058 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
3060 boost::shared_ptr<Route> route = wpr.lock();
3062 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
3066 if (route->listening_via_monitor ()) {
3068 if (Config->get_exclusive_solo()) {
3069 /* new listen: disable all other listen */
3070 boost::shared_ptr<RouteList> r = routes.reader ();
3071 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3072 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner()) {
3075 (*i)->set_listen (false, this);
3081 } else if (_listen_cnt > 0) {
3086 update_route_solo_state ();
3089 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
3091 boost::shared_ptr<Route> route = wpr.lock ();
3094 /* should not happen */
3095 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
3099 bool send_changed = false;
3101 if (route->solo_isolated()) {
3102 if (_solo_isolated_cnt == 0) {
3103 send_changed = true;
3105 _solo_isolated_cnt++;
3106 } else if (_solo_isolated_cnt > 0) {
3107 _solo_isolated_cnt--;
3108 if (_solo_isolated_cnt == 0) {
3109 send_changed = true;
3114 IsolatedChanged (); /* EMIT SIGNAL */
3119 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
3121 DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_change));
3123 if (!self_solo_change) {
3124 // session doesn't care about changes to soloed-by-others
3128 if (solo_update_disabled) {
3130 DEBUG_TRACE (DEBUG::Solo, "solo update disabled - changed ignored\n");
3134 boost::shared_ptr<Route> route = wpr.lock ();
3137 boost::shared_ptr<RouteList> r = routes.reader ();
3140 if (route->self_soloed()) {
3146 RouteGroup* rg = route->route_group ();
3147 bool leave_group_alone = (rg && rg->is_active() && rg->is_solo());
3149 if (delta == 1 && Config->get_exclusive_solo()) {
3151 /* new solo: disable all other solos, but not the group if its solo-enabled */
3153 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3154 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner() ||
3155 (leave_group_alone && ((*i)->route_group() == rg))) {
3158 (*i)->set_solo (false, this);
3162 DEBUG_TRACE (DEBUG::Solo, string_compose ("propagate solo change, delta = %1\n", delta));
3164 solo_update_disabled = true;
3166 RouteList uninvolved;
3168 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1\n", route->name()));
3170 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3171 bool via_sends_only;
3172 bool in_signal_flow;
3174 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner() ||
3175 (leave_group_alone && ((*i)->route_group() == rg))) {
3179 in_signal_flow = false;
3181 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed from %1\n", (*i)->name()));
3183 if ((*i)->feeds (route, &via_sends_only)) {
3184 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a feed from %1\n", (*i)->name()));
3185 if (!via_sends_only) {
3186 if (!route->soloed_by_others_upstream()) {
3187 (*i)->mod_solo_by_others_downstream (delta);
3190 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a send-only feed from %1\n", (*i)->name()));
3192 in_signal_flow = true;
3194 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tno feed from %1\n", (*i)->name()));
3197 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed to %1\n", (*i)->name()));
3199 if (route->feeds (*i, &via_sends_only)) {
3200 /* propagate solo upstream only if routing other than
3201 sends is involved, but do consider the other route
3202 (*i) to be part of the signal flow even if only
3205 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 feeds %2 via sends only %3 sboD %4 sboU %5\n",
3209 route->soloed_by_others_downstream(),
3210 route->soloed_by_others_upstream()));
3211 if (!via_sends_only) {
3212 if (!route->soloed_by_others_downstream()) {
3213 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tmod %1 by %2\n", (*i)->name(), delta));
3214 (*i)->mod_solo_by_others_upstream (delta);
3216 DEBUG_TRACE (DEBUG::Solo, "\talready soloed by others downstream\n");
3219 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tfeed to %1 ignored, sends-only\n", (*i)->name()));
3221 in_signal_flow = true;
3223 DEBUG_TRACE (DEBUG::Solo, "\tno feed to\n");
3226 if (!in_signal_flow) {
3227 uninvolved.push_back (*i);
3231 solo_update_disabled = false;
3232 DEBUG_TRACE (DEBUG::Solo, "propagation complete\n");
3234 update_route_solo_state (r);
3236 /* now notify that the mute state of the routes not involved in the signal
3237 pathway of the just-solo-changed route may have altered.
3240 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
3241 DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1, which neither feeds or is fed by %2\n", (*i)->name(), route->name()));
3242 (*i)->act_on_mute ();
3243 (*i)->mute_changed (this);
3246 SoloChanged (); /* EMIT SIGNAL */
3251 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
3253 /* now figure out if anything that matters is soloed (or is "listening")*/
3255 bool something_soloed = false;
3256 uint32_t listeners = 0;
3257 uint32_t isolated = 0;
3260 r = routes.reader();
3263 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3264 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_auditioner() && (*i)->self_soloed()) {
3265 something_soloed = true;
3268 if (!(*i)->is_auditioner() && (*i)->listening_via_monitor()) {
3269 if (Config->get_solo_control_is_listen_control()) {
3272 (*i)->set_listen (false, this);
3276 if ((*i)->solo_isolated()) {
3281 if (something_soloed != _non_soloed_outs_muted) {
3282 _non_soloed_outs_muted = something_soloed;
3283 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
3286 _listen_cnt = listeners;
3288 if (isolated != _solo_isolated_cnt) {
3289 _solo_isolated_cnt = isolated;
3290 IsolatedChanged (); /* EMIT SIGNAL */
3293 DEBUG_TRACE (DEBUG::Solo, string_compose ("solo state updated by session, soloed? %1 listeners %2 isolated %3\n",
3294 something_soloed, listeners, isolated));
3297 boost::shared_ptr<RouteList>
3298 Session::get_routes_with_internal_returns() const
3300 boost::shared_ptr<RouteList> r = routes.reader ();
3301 boost::shared_ptr<RouteList> rl (new RouteList);
3303 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3304 if ((*i)->internal_return ()) {
3312 Session::io_name_is_legal (const std::string& name)
3314 boost::shared_ptr<RouteList> r = routes.reader ();
3316 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3317 if ((*i)->name() == name) {
3321 if ((*i)->has_io_processor_named (name)) {
3330 Session::set_exclusive_input_active (boost::shared_ptr<RouteList> rl, bool onoff, bool flip_others)
3333 vector<string> connections;
3335 /* if we are passed only a single route and we're not told to turn
3336 * others off, then just do the simple thing.
3339 if (flip_others == false && rl->size() == 1) {
3340 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (rl->front());
3342 mt->set_input_active (onoff);
3347 for (RouteList::iterator rt = rl->begin(); rt != rl->end(); ++rt) {
3349 PortSet& ps ((*rt)->input()->ports());
3351 for (PortSet::iterator p = ps.begin(); p != ps.end(); ++p) {
3352 p->get_connections (connections);
3355 for (vector<string>::iterator s = connections.begin(); s != connections.end(); ++s) {
3356 routes_using_input_from (*s, rl2);
3359 /* scan all relevant routes to see if others are on or off */
3361 bool others_are_already_on = false;
3363 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
3365 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
3371 if ((*r) != (*rt)) {
3372 if (mt->input_active()) {
3373 others_are_already_on = true;
3376 /* this one needs changing */
3377 mt->set_input_active (onoff);
3383 /* globally reverse other routes */
3385 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
3386 if ((*r) != (*rt)) {
3387 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
3389 mt->set_input_active (!others_are_already_on);
3398 Session::routes_using_input_from (const string& str, RouteList& rl)
3400 boost::shared_ptr<RouteList> r = routes.reader();
3402 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3403 if ((*i)->input()->connected_to (str)) {
3409 boost::shared_ptr<Route>
3410 Session::route_by_name (string name)
3412 boost::shared_ptr<RouteList> r = routes.reader ();
3414 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3415 if ((*i)->name() == name) {
3420 return boost::shared_ptr<Route> ((Route*) 0);
3423 boost::shared_ptr<Route>
3424 Session::route_by_id (PBD::ID id)
3426 boost::shared_ptr<RouteList> r = routes.reader ();
3428 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3429 if ((*i)->id() == id) {
3434 return boost::shared_ptr<Route> ((Route*) 0);
3437 boost::shared_ptr<Track>
3438 Session::track_by_diskstream_id (PBD::ID id)
3440 boost::shared_ptr<RouteList> r = routes.reader ();
3442 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3443 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
3444 if (t && t->using_diskstream_id (id)) {
3449 return boost::shared_ptr<Track> ();
3452 boost::shared_ptr<Route>
3453 Session::route_by_remote_id (uint32_t id)
3455 boost::shared_ptr<RouteList> r = routes.reader ();
3457 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3458 if ((*i)->remote_control_id() == id) {
3463 return boost::shared_ptr<Route> ((Route*) 0);
3468 Session::reassign_track_numbers ()
3472 RouteList r (*(routes.reader ()));
3473 SignalOrderRouteSorter sorter;
3476 StateProtector sp (this);
3478 for (RouteList::iterator i = r.begin(); i != r.end(); ++i) {
3479 if (boost::dynamic_pointer_cast<Track> (*i)) {
3480 (*i)->set_track_number(++tn);
3482 else if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_auditioner()) {
3483 (*i)->set_track_number(--bn);
3486 const uint32_t decimals = ceilf (log10f (tn + 1));
3487 const bool decimals_changed = _track_number_decimals != decimals;
3488 _track_number_decimals = decimals;
3490 if (decimals_changed && config.get_track_name_number ()) {
3491 for (RouteList::iterator i = r.begin(); i != r.end(); ++i) {
3492 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
3494 t->resync_track_name();
3497 // trigger GUI re-layout
3498 config.ParameterChanged("track-name-number");
3503 Session::playlist_region_added (boost::weak_ptr<Region> w)
3505 boost::shared_ptr<Region> r = w.lock ();
3510 /* These are the operations that are currently in progress... */
3511 list<GQuark> curr = _current_trans_quarks;
3514 /* ...and these are the operations during which we want to update
3515 the session range location markers.
3518 ops.push_back (Operations::capture);
3519 ops.push_back (Operations::paste);
3520 ops.push_back (Operations::duplicate_region);
3521 ops.push_back (Operations::insert_file);
3522 ops.push_back (Operations::insert_region);
3523 ops.push_back (Operations::drag_region_brush);
3524 ops.push_back (Operations::region_drag);
3525 ops.push_back (Operations::selection_grab);
3526 ops.push_back (Operations::region_fill);
3527 ops.push_back (Operations::fill_selection);
3528 ops.push_back (Operations::create_region);
3529 ops.push_back (Operations::region_copy);
3530 ops.push_back (Operations::fixed_time_region_copy);
3533 /* See if any of the current operations match the ones that we want */
3535 set_intersection (_current_trans_quarks.begin(), _current_trans_quarks.end(), ops.begin(), ops.end(), back_inserter (in));
3537 /* If so, update the session range markers */
3539 maybe_update_session_range (r->position (), r->last_frame ());
3543 /** Update the session range markers if a is before the current start or
3544 * b is after the current end.
3547 Session::maybe_update_session_range (framepos_t a, framepos_t b)
3549 if (_state_of_the_state & Loading) {
3553 if (_session_range_location == 0) {
3555 add_session_range_location (a, b);
3559 if (a < _session_range_location->start()) {
3560 _session_range_location->set_start (a);
3563 if (b > _session_range_location->end()) {
3564 _session_range_location->set_end (b);
3570 Session::playlist_ranges_moved (list<Evoral::RangeMove<framepos_t> > const & ranges)
3572 for (list<Evoral::RangeMove<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
3573 maybe_update_session_range (i->to, i->to + i->length);
3578 Session::playlist_regions_extended (list<Evoral::Range<framepos_t> > const & ranges)
3580 for (list<Evoral::Range<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
3581 maybe_update_session_range (i->from, i->to);
3585 /* Region management */
3587 boost::shared_ptr<Region>
3588 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
3590 const RegionFactory::RegionMap& regions (RegionFactory::regions());
3591 RegionFactory::RegionMap::const_iterator i;
3592 boost::shared_ptr<Region> region;
3594 Glib::Threads::Mutex::Lock lm (region_lock);
3596 for (i = regions.begin(); i != regions.end(); ++i) {
3600 if (region->whole_file()) {
3602 if (child->source_equivalent (region)) {
3608 return boost::shared_ptr<Region> ();
3612 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
3614 set<boost::shared_ptr<Region> > relevant_regions;
3616 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
3617 RegionFactory::get_regions_using_source (*s, relevant_regions);
3620 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
3621 set<boost::shared_ptr<Region> >::iterator tmp;
3626 playlists->destroy_region (*r);
3627 RegionFactory::map_remove (*r);
3629 (*r)->drop_sources ();
3630 (*r)->drop_references ();
3632 relevant_regions.erase (r);
3637 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
3640 Glib::Threads::Mutex::Lock ls (source_lock);
3641 /* remove from the main source list */
3642 sources.erase ((*s)->id());
3645 (*s)->mark_for_remove ();
3646 (*s)->drop_references ();
3655 Session::remove_last_capture ()
3657 list<boost::shared_ptr<Source> > srcs;
3659 boost::shared_ptr<RouteList> rl = routes.reader ();
3660 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3661 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3666 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
3669 srcs.insert (srcs.end(), l.begin(), l.end());
3674 destroy_sources (srcs);
3676 save_state (_current_snapshot_name);
3681 /* Source Management */
3684 Session::add_source (boost::shared_ptr<Source> source)
3686 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
3687 pair<SourceMap::iterator,bool> result;
3689 entry.first = source->id();
3690 entry.second = source;
3693 Glib::Threads::Mutex::Lock lm (source_lock);
3694 result = sources.insert (entry);
3697 if (result.second) {
3699 /* yay, new source */
3701 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
3704 if (!fs->within_session()) {
3705 ensure_search_path_includes (Glib::path_get_dirname (fs->path()), fs->type());
3711 boost::shared_ptr<AudioFileSource> afs;
3713 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3714 if (Config->get_auto_analyse_audio()) {
3715 Analyser::queue_source_for_analysis (source, false);
3719 source->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_source, this, boost::weak_ptr<Source> (source)));
3724 Session::remove_source (boost::weak_ptr<Source> src)
3726 if (_state_of_the_state & Deletion) {
3730 SourceMap::iterator i;
3731 boost::shared_ptr<Source> source = src.lock();
3738 Glib::Threads::Mutex::Lock lm (source_lock);
3740 if ((i = sources.find (source->id())) != sources.end()) {
3745 if (!(_state_of_the_state & StateOfTheState (InCleanup|Loading))) {
3747 /* save state so we don't end up with a session file
3748 referring to non-existent sources.
3751 save_state (_current_snapshot_name);
3755 boost::shared_ptr<Source>
3756 Session::source_by_id (const PBD::ID& id)
3758 Glib::Threads::Mutex::Lock lm (source_lock);
3759 SourceMap::iterator i;
3760 boost::shared_ptr<Source> source;
3762 if ((i = sources.find (id)) != sources.end()) {
3769 boost::shared_ptr<AudioFileSource>
3770 Session::audio_source_by_path_and_channel (const string& path, uint16_t chn) const
3772 /* Restricted to audio files because only audio sources have channel
3776 Glib::Threads::Mutex::Lock lm (source_lock);
3778 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
3779 boost::shared_ptr<AudioFileSource> afs
3780 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3782 if (afs && afs->path() == path && chn == afs->channel()) {
3787 return boost::shared_ptr<AudioFileSource>();
3790 boost::shared_ptr<MidiSource>
3791 Session::midi_source_by_path (const std::string& path) const
3793 /* Restricted to MIDI files because audio sources require a channel
3794 for unique identification, in addition to a path.
3797 Glib::Threads::Mutex::Lock lm (source_lock);
3799 for (SourceMap::const_iterator s = sources.begin(); s != sources.end(); ++s) {
3800 boost::shared_ptr<MidiSource> ms
3801 = boost::dynamic_pointer_cast<MidiSource>(s->second);
3802 boost::shared_ptr<FileSource> fs
3803 = boost::dynamic_pointer_cast<FileSource>(s->second);
3805 if (ms && fs && fs->path() == path) {
3810 return boost::shared_ptr<MidiSource>();
3814 Session::count_sources_by_origin (const string& path)
3817 Glib::Threads::Mutex::Lock lm (source_lock);
3819 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3820 boost::shared_ptr<FileSource> fs
3821 = boost::dynamic_pointer_cast<FileSource>(i->second);
3823 if (fs && fs->origin() == path) {
3832 Session::peak_path (string base) const
3834 if (Glib::path_is_absolute (base)) {
3836 /* rip the session dir from the audiofile source */
3838 string session_path;
3839 string interchange_dir_string = string (interchange_dir_name) + G_DIR_SEPARATOR;
3840 bool in_another_session = true;
3842 if (base.find (interchange_dir_string) != string::npos) {
3844 session_path = Glib::path_get_dirname (base); /* now ends in audiofiles */
3845 session_path = Glib::path_get_dirname (session_path); /* now ends in session name */
3846 session_path = Glib::path_get_dirname (session_path); /* now ends in interchange */
3847 session_path = Glib::path_get_dirname (session_path); /* now has session path */
3849 /* see if it is within our session */
3851 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3852 if (i->path == session_path) {
3853 in_another_session = false;
3858 in_another_session = false;
3862 if (in_another_session) {
3863 SessionDirectory sd (session_path);
3864 return Glib::build_filename (sd.peak_path(), Glib::path_get_basename (base) + peakfile_suffix);
3868 base = Glib::path_get_basename (base);
3869 return Glib::build_filename (_session_dir->peak_path(), base + peakfile_suffix);
3873 Session::new_audio_source_path_for_embedded (const std::string& path)
3877 * we know that the filename is already unique because it exists
3878 * out in the filesystem.
3880 * However, when we bring it into the session, we could get a
3883 * Eg. two embedded files:
3888 * When merged into session, these collide.
3890 * There will not be a conflict with in-memory sources
3891 * because when the source was created we already picked
3892 * a unique name for it.
3894 * This collision is not likely to be common, but we have to guard
3895 * against it. So, if there is a collision, take the md5 hash of the
3896 * the path, and use that as the filename instead.
3899 SessionDirectory sdir (get_best_session_directory_for_new_audio());
3900 string base = Glib::path_get_basename (path);
3901 string newpath = Glib::build_filename (sdir.sound_path(), base);
3903 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
3907 md5.digestString (path.c_str());
3908 md5.writeToString ();
3909 base = md5.digestChars;
3911 string ext = get_suffix (path);
3918 newpath = Glib::build_filename (sdir.sound_path(), base);
3920 /* if this collides, we're screwed */
3922 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
3923 error << string_compose (_("Merging embedded file %1: name collision AND md5 hash collision!"), path) << endmsg;
3932 /** Return true if there are no audio file sources that use @param name as
3933 * the filename component of their path.
3935 * Return false otherwise.
3937 * This method MUST ONLY be used to check in-session, mono files since it
3938 * hard-codes the channel of the audio file source we are looking for as zero.
3940 * If/when Ardour supports native files in non-mono formats, the logic here
3941 * will need to be revisited.
3944 Session::audio_source_name_is_unique (const string& name)
3946 std::vector<string> sdirs = source_search_path (DataType::AUDIO);
3947 vector<space_and_path>::iterator i;
3948 uint32_t existing = 0;
3950 for (vector<string>::const_iterator i = sdirs.begin(); i != sdirs.end(); ++i) {
3952 /* note that we search *without* the extension so that
3953 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
3954 in the event that this new name is required for
3955 a file format change.
3958 const string spath = *i;
3960 if (matching_unsuffixed_filename_exists_in (spath, name)) {
3965 /* it is possible that we have the path already
3966 * assigned to a source that has not yet been written
3967 * (ie. the write source for a diskstream). we have to
3968 * check this in order to make sure that our candidate
3969 * path isn't used again, because that can lead to
3970 * two Sources point to the same file with different
3971 * notions of their removability.
3975 string possible_path = Glib::build_filename (spath, name);
3977 if (audio_source_by_path_and_channel (possible_path, 0)) {
3983 return (existing == 0);
3987 Session::format_audio_source_name (const string& legalized_base, uint32_t nchan, uint32_t chan, bool destructive, bool take_required, uint32_t cnt, bool related_exists)
3990 const string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3994 sstr << setfill ('0') << setw (4) << cnt;
3995 sstr << legalized_base;
3997 sstr << legalized_base;
3999 if (take_required || related_exists) {
4011 } else if (nchan > 2) {
4016 /* XXX what? more than 26 channels! */
4027 /** Return a unique name based on \a base for a new internal audio source */
4029 Session::new_audio_source_path (const string& base, uint32_t nchan, uint32_t chan, bool destructive, bool take_required)
4032 string possible_name;
4033 const uint32_t limit = 9999; // arbitrary limit on number of files with the same basic name
4035 bool some_related_source_name_exists = false;
4037 legalized = legalize_for_path (base);
4039 // Find a "version" of the base name that doesn't exist in any of the possible directories.
4041 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
4043 possible_name = format_audio_source_name (legalized, nchan, chan, destructive, take_required, cnt, some_related_source_name_exists);
4045 if (audio_source_name_is_unique (possible_name)) {
4049 some_related_source_name_exists = true;
4052 error << string_compose(
4053 _("There are already %1 recordings for %2, which I consider too many."),
4054 limit, base) << endmsg;
4056 throw failed_constructor();
4060 /* We've established that the new name does not exist in any session
4061 * directory, so now find out which one we should use for this new
4065 SessionDirectory sdir (get_best_session_directory_for_new_audio());
4067 std::string s = Glib::build_filename (sdir.sound_path(), possible_name);
4072 /** Return a unique name based on `base` for a new internal MIDI source */
4074 Session::new_midi_source_path (const string& base)
4077 char buf[PATH_MAX+1];
4078 const uint32_t limit = 10000;
4080 string possible_path;
4081 string possible_name;
4084 legalized = legalize_for_path (base);
4086 // Find a "version" of the file name that doesn't exist in any of the possible directories.
4087 std::vector<string> sdirs = source_search_path(DataType::MIDI);
4089 /* - the main session folder is the first in the vector.
4090 * - after checking all locations for file-name uniqueness,
4091 * we keep the one from the last iteration as new file name
4092 * - midi files are small and should just be kept in the main session-folder
4094 * -> reverse the array, check main session folder last and use that as location
4097 std::reverse(sdirs.begin(), sdirs.end());
4099 for (cnt = 1; cnt <= limit; ++cnt) {
4101 vector<space_and_path>::iterator i;
4102 uint32_t existing = 0;
4104 for (vector<string>::const_iterator i = sdirs.begin(); i != sdirs.end(); ++i) {
4106 snprintf (buf, sizeof(buf), "%s-%u.mid", legalized.c_str(), cnt);
4107 possible_name = buf;
4109 possible_path = Glib::build_filename (*i, possible_name);
4111 if (Glib::file_test (possible_path, Glib::FILE_TEST_EXISTS)) {
4115 if (midi_source_by_path (possible_path)) {
4120 if (existing == 0) {
4125 error << string_compose(
4126 _("There are already %1 recordings for %2, which I consider too many."),
4127 limit, base) << endmsg;
4133 /* No need to "find best location" for software/app-based RAID, because
4134 MIDI is so small that we always put it in the same place.
4137 return possible_path;
4141 /** Create a new within-session audio source */
4142 boost::shared_ptr<AudioFileSource>
4143 Session::create_audio_source_for_session (size_t n_chans, string const & base, uint32_t chan, bool destructive)
4145 const string path = new_audio_source_path (base, n_chans, chan, destructive, true);
4147 if (!path.empty()) {
4148 return boost::dynamic_pointer_cast<AudioFileSource> (
4149 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
4151 throw failed_constructor ();
4155 /** Create a new within-session MIDI source */
4156 boost::shared_ptr<MidiSource>
4157 Session::create_midi_source_for_session (string const & basic_name)
4159 const string path = new_midi_source_path (basic_name);
4161 if (!path.empty()) {
4162 return boost::dynamic_pointer_cast<SMFSource> (
4163 SourceFactory::createWritable (
4164 DataType::MIDI, *this, path, false, frame_rate()));
4166 throw failed_constructor ();
4170 /** Create a new within-session MIDI source */
4171 boost::shared_ptr<MidiSource>
4172 Session::create_midi_source_by_stealing_name (boost::shared_ptr<Track> track)
4174 /* the caller passes in the track the source will be used in,
4175 so that we can keep the numbering sane.
4177 Rationale: a track with the name "Foo" that has had N
4178 captures carried out so far will ALREADY have a write source
4179 named "Foo-N+1.mid" waiting to be used for the next capture.
4181 If we call new_midi_source_name() we will get "Foo-N+2". But
4182 there is no region corresponding to "Foo-N+1", so when
4183 "Foo-N+2" appears in the track, the gap presents the user
4184 with odd behaviour - why did it skip past Foo-N+1?
4186 We could explain this to the user in some odd way, but
4187 instead we rename "Foo-N+1.mid" as "Foo-N+2.mid", and then
4190 If that attempted rename fails, we get "Foo-N+2.mid" anyway.
4193 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (track);
4195 std::string name = track->steal_write_source_name ();
4198 return boost::shared_ptr<MidiSource>();
4201 /* MIDI files are small, just put them in the first location of the
4202 session source search path.
4205 const string path = Glib::build_filename (source_search_path (DataType::MIDI).front(), name);
4207 return boost::dynamic_pointer_cast<SMFSource> (
4208 SourceFactory::createWritable (
4209 DataType::MIDI, *this, path, false, frame_rate()));
4214 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
4216 if (playlist->hidden()) {
4220 playlists->add (playlist);
4223 playlist->release();
4230 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
4232 if (_state_of_the_state & Deletion) {
4236 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
4242 playlists->remove (playlist);
4248 Session::set_audition (boost::shared_ptr<Region> r)
4250 pending_audition_region = r;
4251 add_post_transport_work (PostTransportAudition);
4252 _butler->schedule_transport_work ();
4256 Session::audition_playlist ()
4258 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
4259 ev->region.reset ();
4264 Session::non_realtime_set_audition ()
4266 assert (pending_audition_region);
4267 auditioner->audition_region (pending_audition_region);
4268 pending_audition_region.reset ();
4269 AuditionActive (true); /* EMIT SIGNAL */
4273 Session::audition_region (boost::shared_ptr<Region> r)
4275 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
4281 Session::cancel_audition ()
4286 if (auditioner->auditioning()) {
4287 auditioner->cancel_audition ();
4288 AuditionActive (false); /* EMIT SIGNAL */
4293 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
4295 if (a->is_monitor()) {
4298 if (b->is_monitor()) {
4301 return a->order_key () < b->order_key ();
4305 Session::is_auditioning () const
4307 /* can be called before we have an auditioner object */
4309 return auditioner->auditioning();
4316 Session::graph_reordered ()
4318 /* don't do this stuff if we are setting up connections
4319 from a set_state() call or creating new tracks. Ditto for deletion.
4322 if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress) {
4326 /* every track/bus asked for this to be handled but it was deferred because
4327 we were connecting. do it now.
4330 request_input_change_handling ();
4334 /* force all diskstreams to update their capture offset values to
4335 reflect any changes in latencies within the graph.
4338 boost::shared_ptr<RouteList> rl = routes.reader ();
4339 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
4340 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4342 tr->set_capture_offset ();
4347 /** @return Number of frames that there is disk space available to write,
4350 boost::optional<framecnt_t>
4351 Session::available_capture_duration ()
4353 Glib::Threads::Mutex::Lock lm (space_lock);
4355 if (_total_free_4k_blocks_uncertain) {
4356 return boost::optional<framecnt_t> ();
4359 float sample_bytes_on_disk = 4.0; // keep gcc happy
4361 switch (config.get_native_file_data_format()) {
4363 sample_bytes_on_disk = 4.0;
4367 sample_bytes_on_disk = 3.0;
4371 sample_bytes_on_disk = 2.0;
4375 /* impossible, but keep some gcc versions happy */
4376 fatal << string_compose (_("programming error: %1"),
4377 X_("illegal native file data format"))
4379 abort(); /*NOTREACHED*/
4382 double scale = 4096.0 / sample_bytes_on_disk;
4384 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
4385 return max_framecnt;
4388 return (framecnt_t) floor (_total_free_4k_blocks * scale);
4392 Session::add_bundle (boost::shared_ptr<Bundle> bundle, bool emit_signal)
4395 RCUWriter<BundleList> writer (_bundles);
4396 boost::shared_ptr<BundleList> b = writer.get_copy ();
4397 b->push_back (bundle);
4401 BundleAddedOrRemoved (); /* EMIT SIGNAL */
4408 Session::remove_bundle (boost::shared_ptr<Bundle> bundle)
4410 bool removed = false;
4413 RCUWriter<BundleList> writer (_bundles);
4414 boost::shared_ptr<BundleList> b = writer.get_copy ();
4415 BundleList::iterator i = find (b->begin(), b->end(), bundle);
4417 if (i != b->end()) {
4424 BundleAddedOrRemoved (); /* EMIT SIGNAL */
4430 boost::shared_ptr<Bundle>
4431 Session::bundle_by_name (string name) const
4433 boost::shared_ptr<BundleList> b = _bundles.reader ();
4435 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
4436 if ((*i)->name() == name) {
4441 return boost::shared_ptr<Bundle> ();
4445 Session::tempo_map_changed (const PropertyChange&)
4449 playlists->update_after_tempo_map_change ();
4451 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
4457 Session::update_locations_after_tempo_map_change (const Locations::LocationList& loc)
4459 for (Locations::LocationList::const_iterator i = loc.begin(); i != loc.end(); ++i) {
4460 (*i)->recompute_frames_from_bbt ();
4464 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
4465 * the given count with the current block size.
4468 Session::ensure_buffers (ChanCount howmany)
4470 BufferManager::ensure_buffers (howmany, bounce_processing() ? bounce_chunk_size : 0);
4474 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
4476 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4477 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
4482 Session::next_insert_id ()
4484 /* this doesn't really loop forever. just think about it */
4487 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
4488 if (!insert_bitset[n]) {
4489 insert_bitset[n] = true;
4495 /* none available, so resize and try again */
4497 insert_bitset.resize (insert_bitset.size() + 16, false);
4502 Session::next_send_id ()
4504 /* this doesn't really loop forever. just think about it */
4507 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
4508 if (!send_bitset[n]) {
4509 send_bitset[n] = true;
4515 /* none available, so resize and try again */
4517 send_bitset.resize (send_bitset.size() + 16, false);
4522 Session::next_aux_send_id ()
4524 /* this doesn't really loop forever. just think about it */
4527 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < aux_send_bitset.size(); ++n) {
4528 if (!aux_send_bitset[n]) {
4529 aux_send_bitset[n] = true;
4535 /* none available, so resize and try again */
4537 aux_send_bitset.resize (aux_send_bitset.size() + 16, false);
4542 Session::next_return_id ()
4544 /* this doesn't really loop forever. just think about it */
4547 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
4548 if (!return_bitset[n]) {
4549 return_bitset[n] = true;
4555 /* none available, so resize and try again */
4557 return_bitset.resize (return_bitset.size() + 16, false);
4562 Session::mark_send_id (uint32_t id)
4564 if (id >= send_bitset.size()) {
4565 send_bitset.resize (id+16, false);
4567 if (send_bitset[id]) {
4568 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
4570 send_bitset[id] = true;
4574 Session::mark_aux_send_id (uint32_t id)
4576 if (id >= aux_send_bitset.size()) {
4577 aux_send_bitset.resize (id+16, false);
4579 if (aux_send_bitset[id]) {
4580 warning << string_compose (_("aux send ID %1 appears to be in use already"), id) << endmsg;
4582 aux_send_bitset[id] = true;
4586 Session::mark_return_id (uint32_t id)
4588 if (id >= return_bitset.size()) {
4589 return_bitset.resize (id+16, false);
4591 if (return_bitset[id]) {
4592 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
4594 return_bitset[id] = true;
4598 Session::mark_insert_id (uint32_t id)
4600 if (id >= insert_bitset.size()) {
4601 insert_bitset.resize (id+16, false);
4603 if (insert_bitset[id]) {
4604 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
4606 insert_bitset[id] = true;
4610 Session::unmark_send_id (uint32_t id)
4612 if (id < send_bitset.size()) {
4613 send_bitset[id] = false;
4618 Session::unmark_aux_send_id (uint32_t id)
4620 if (id < aux_send_bitset.size()) {
4621 aux_send_bitset[id] = false;
4626 Session::unmark_return_id (uint32_t id)
4628 if (id < return_bitset.size()) {
4629 return_bitset[id] = false;
4634 Session::unmark_insert_id (uint32_t id)
4636 if (id < insert_bitset.size()) {
4637 insert_bitset[id] = false;
4642 Session::reset_native_file_format ()
4644 boost::shared_ptr<RouteList> rl = routes.reader ();
4645 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
4646 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4648 /* don't save state as we do this, there's no point
4651 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
4652 tr->reset_write_sources (false);
4653 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
4659 Session::route_name_unique (string n) const
4661 boost::shared_ptr<RouteList> r = routes.reader ();
4663 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4664 if ((*i)->name() == n) {
4673 Session::route_name_internal (string n) const
4675 if (auditioner && auditioner->name() == n) {
4679 if (_click_io && _click_io->name() == n) {
4687 Session::freeze_all (InterThreadInfo& itt)
4689 boost::shared_ptr<RouteList> r = routes.reader ();
4691 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4693 boost::shared_ptr<Track> t;
4695 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4696 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4706 boost::shared_ptr<Region>
4707 Session::write_one_track (Track& track, framepos_t start, framepos_t end,
4708 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
4709 InterThreadInfo& itt,
4710 boost::shared_ptr<Processor> endpoint, bool include_endpoint,
4711 bool for_export, bool for_freeze)
4713 boost::shared_ptr<Region> result;
4714 boost::shared_ptr<Playlist> playlist;
4715 boost::shared_ptr<Source> source;
4716 ChanCount diskstream_channels (track.n_channels());
4717 framepos_t position;
4718 framecnt_t this_chunk;
4720 framepos_t latency_skip;
4722 framepos_t len = end - start;
4723 bool need_block_size_reset = false;
4724 ChanCount const max_proc = track.max_processor_streams ();
4725 string legal_playlist_name;
4726 string possible_path;
4729 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4730 end, start) << endmsg;
4734 diskstream_channels = track.bounce_get_output_streams (diskstream_channels, endpoint,
4735 include_endpoint, for_export, for_freeze);
4737 if (diskstream_channels.n(track.data_type()) < 1) {
4738 error << _("Cannot write a range with no data.") << endmsg;
4742 // block all process callback handling
4744 block_processing ();
4747 // synchronize with AudioEngine::process_callback()
4748 // make sure processing is not currently running
4749 // and processing_blocked() is honored before
4750 // acquiring thread buffers
4751 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
4754 _bounce_processing_active = true;
4756 /* call tree *MUST* hold route_lock */
4758 if ((playlist = track.playlist()) == 0) {
4762 legal_playlist_name = legalize_for_path (playlist->name());
4764 for (uint32_t chan_n = 0; chan_n < diskstream_channels.n(track.data_type()); ++chan_n) {
4766 string base_name = string_compose ("%1-%2-bounce", playlist->name(), chan_n);
4767 string path = ((track.data_type() == DataType::AUDIO)
4768 ? new_audio_source_path (legal_playlist_name, diskstream_channels.n_audio(), chan_n, false, true)
4769 : new_midi_source_path (legal_playlist_name));
4776 source = SourceFactory::createWritable (track.data_type(), *this, path, false, frame_rate());
4779 catch (failed_constructor& err) {
4780 error << string_compose (_("cannot create new file \"%1\" for %2"), path, track.name()) << endmsg;
4784 srcs.push_back (source);
4787 /* tell redirects that care that we are about to use a much larger
4788 * blocksize. this will flush all plugins too, so that they are ready
4789 * to be used for this process.
4792 need_block_size_reset = true;
4793 track.set_block_size (bounce_chunk_size);
4794 _engine.main_thread()->get_buffers ();
4798 latency_skip = track.bounce_get_latency (endpoint, include_endpoint, for_export, for_freeze);
4800 /* create a set of reasonably-sized buffers */
4801 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4802 buffers.ensure_buffers(*t, max_proc.get(*t), bounce_chunk_size);
4804 buffers.set_count (max_proc);
4806 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4807 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4808 boost::shared_ptr<MidiSource> ms;
4810 afs->prepare_for_peakfile_writes ();
4811 } else if ((ms = boost::dynamic_pointer_cast<MidiSource>(*src))) {
4812 Source::Lock lock(ms->mutex());
4813 ms->mark_streaming_write_started(lock);
4817 while (to_do && !itt.cancel) {
4819 this_chunk = min (to_do, bounce_chunk_size);
4821 if (track.export_stuff (buffers, start, this_chunk, endpoint, include_endpoint, for_export, for_freeze)) {
4825 start += this_chunk;
4826 to_do -= this_chunk;
4827 itt.progress = (float) (1.0 - ((double) to_do / len));
4829 if (latency_skip >= bounce_chunk_size) {
4830 latency_skip -= bounce_chunk_size;
4834 const framecnt_t current_chunk = this_chunk - latency_skip;
4837 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4838 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4839 boost::shared_ptr<MidiSource> ms;
4842 if (afs->write (buffers.get_audio(n).data(latency_skip), current_chunk) != current_chunk) {
4845 } else if ((ms = boost::dynamic_pointer_cast<MidiSource>(*src))) {
4846 Source::Lock lock(ms->mutex());
4848 const MidiBuffer& buf = buffers.get_midi(0);
4849 for (MidiBuffer::const_iterator i = buf.begin(); i != buf.end(); ++i) {
4850 Evoral::Event<framepos_t> ev = *i;
4851 ev.set_time(ev.time() - position);
4852 ms->append_event_frames(lock, ev, ms->timeline_position());
4859 /* post-roll, pick up delayed processor output */
4860 latency_skip = track.bounce_get_latency (endpoint, include_endpoint, for_export, for_freeze);
4862 while (latency_skip && !itt.cancel) {
4863 this_chunk = min (latency_skip, bounce_chunk_size);
4864 latency_skip -= this_chunk;
4866 buffers.silence (this_chunk, 0);
4867 track.bounce_process (buffers, start, this_chunk, endpoint, include_endpoint, for_export, for_freeze);
4870 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4871 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4874 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4886 xnow = localtime (&now);
4888 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4889 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4890 boost::shared_ptr<MidiSource> ms;
4893 afs->update_header (position, *xnow, now);
4894 afs->flush_header ();
4895 } else if ((ms = boost::dynamic_pointer_cast<MidiSource>(*src))) {
4896 Source::Lock lock(ms->mutex());
4897 ms->mark_streaming_write_completed(lock);
4901 /* construct a region to represent the bounced material */
4905 plist.add (Properties::start, 0);
4906 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
4907 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
4909 result = RegionFactory::create (srcs, plist);
4915 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4916 (*src)->mark_for_remove ();
4917 (*src)->drop_references ();
4921 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4922 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4925 afs->done_with_peakfile_writes ();
4929 _bounce_processing_active = false;
4931 if (need_block_size_reset) {
4932 _engine.main_thread()->drop_buffers ();
4933 track.set_block_size (get_block_size());
4936 unblock_processing ();
4942 Session::gain_automation_buffer() const
4944 return ProcessThread::gain_automation_buffer ();
4948 Session::trim_automation_buffer() const
4950 return ProcessThread::trim_automation_buffer ();
4954 Session::send_gain_automation_buffer() const
4956 return ProcessThread::send_gain_automation_buffer ();
4960 Session::pan_automation_buffer() const
4962 return ProcessThread::pan_automation_buffer ();
4966 Session::get_silent_buffers (ChanCount count)
4968 return ProcessThread::get_silent_buffers (count);
4972 Session::get_scratch_buffers (ChanCount count, bool silence)
4974 return ProcessThread::get_scratch_buffers (count, silence);
4978 Session::get_route_buffers (ChanCount count, bool silence)
4980 return ProcessThread::get_route_buffers (count, silence);
4985 Session::get_mix_buffers (ChanCount count)
4987 return ProcessThread::get_mix_buffers (count);
4991 Session::ntracks () const
4994 boost::shared_ptr<RouteList> r = routes.reader ();
4996 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4997 if (boost::dynamic_pointer_cast<Track> (*i)) {
5006 Session::nbusses () const
5009 boost::shared_ptr<RouteList> r = routes.reader ();
5011 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
5012 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
5021 Session::add_automation_list(AutomationList *al)
5023 automation_lists[al->id()] = al;
5026 /** @return true if there is at least one record-enabled track, otherwise false */
5028 Session::have_rec_enabled_track () const
5030 return g_atomic_int_get (const_cast<gint*>(&_have_rec_enabled_track)) == 1;
5034 Session::have_rec_disabled_track () const
5036 return g_atomic_int_get (const_cast<gint*>(&_have_rec_disabled_track)) == 1;
5039 /** Update the state of our rec-enabled tracks flag */
5041 Session::update_route_record_state ()
5043 boost::shared_ptr<RouteList> rl = routes.reader ();
5044 RouteList::iterator i = rl->begin();
5045 while (i != rl->end ()) {
5047 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
5048 if (tr && tr->record_enabled ()) {
5055 int const old = g_atomic_int_get (&_have_rec_enabled_track);
5057 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
5059 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
5060 RecordStateChanged (); /* EMIT SIGNAL */
5065 while (i != rl->end ()) {
5067 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
5068 if (tr && !tr->record_enabled ()) {
5075 g_atomic_int_set (&_have_rec_disabled_track, i != rl->end () ? 1 : 0);
5079 Session::listen_position_changed ()
5081 boost::shared_ptr<RouteList> r = routes.reader ();
5083 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5084 (*i)->listen_position_changed ();
5089 Session::solo_control_mode_changed ()
5091 /* cancel all solo or all listen when solo control mode changes */
5094 set_solo (get_routes(), false);
5095 } else if (listening()) {
5096 set_listen (get_routes(), false);
5100 /** Called when a property of one of our route groups changes */
5102 Session::route_group_property_changed (RouteGroup* rg)
5104 RouteGroupPropertyChanged (rg); /* EMIT SIGNAL */
5107 /** Called when a route is added to one of our route groups */
5109 Session::route_added_to_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
5111 RouteAddedToRouteGroup (rg, r);
5114 /** Called when a route is removed from one of our route groups */
5116 Session::route_removed_from_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
5118 update_route_record_state ();
5119 RouteRemovedFromRouteGroup (rg, r); /* EMIT SIGNAL */
5122 boost::shared_ptr<RouteList>
5123 Session::get_tracks () const
5125 boost::shared_ptr<RouteList> rl = routes.reader ();
5126 boost::shared_ptr<RouteList> tl (new RouteList);
5128 for (RouteList::const_iterator r = rl->begin(); r != rl->end(); ++r) {
5129 if (boost::dynamic_pointer_cast<Track> (*r)) {
5130 if (!(*r)->is_auditioner()) {
5138 boost::shared_ptr<RouteList>
5139 Session::get_routes_with_regions_at (framepos_t const p) const
5141 boost::shared_ptr<RouteList> r = routes.reader ();
5142 boost::shared_ptr<RouteList> rl (new RouteList);
5144 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5145 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
5150 boost::shared_ptr<Playlist> pl = tr->playlist ();
5155 if (pl->has_region_at (p)) {
5164 Session::goto_end ()
5166 if (_session_range_location) {
5167 request_locate (_session_range_location->end(), false);
5169 request_locate (0, false);
5174 Session::goto_start ()
5176 if (_session_range_location) {
5177 request_locate (_session_range_location->start(), false);
5179 request_locate (0, false);
5184 Session::current_start_frame () const
5186 return _session_range_location ? _session_range_location->start() : 0;
5190 Session::current_end_frame () const
5192 return _session_range_location ? _session_range_location->end() : 0;
5196 Session::add_session_range_location (framepos_t start, framepos_t end)
5198 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
5199 _locations->add (_session_range_location);
5203 Session::step_edit_status_change (bool yn)
5209 send = (_step_editors == 0);
5214 send = (_step_editors == 1);
5217 if (_step_editors > 0) {
5223 StepEditStatusChange (val);
5229 Session::start_time_changed (framepos_t old)
5231 /* Update the auto loop range to match the session range
5232 (unless the auto loop range has been changed by the user)
5235 Location* s = _locations->session_range_location ();
5240 Location* l = _locations->auto_loop_location ();
5242 if (l && l->start() == old) {
5243 l->set_start (s->start(), true);
5248 Session::end_time_changed (framepos_t old)
5250 /* Update the auto loop range to match the session range
5251 (unless the auto loop range has been changed by the user)
5254 Location* s = _locations->session_range_location ();
5259 Location* l = _locations->auto_loop_location ();
5261 if (l && l->end() == old) {
5262 l->set_end (s->end(), true);
5266 std::vector<std::string>
5267 Session::source_search_path (DataType type) const
5271 if (session_dirs.size() == 1) {
5273 case DataType::AUDIO:
5274 sp.push_back (_session_dir->sound_path());
5276 case DataType::MIDI:
5277 sp.push_back (_session_dir->midi_path());
5281 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
5282 SessionDirectory sdir (i->path);
5284 case DataType::AUDIO:
5285 sp.push_back (sdir.sound_path());
5287 case DataType::MIDI:
5288 sp.push_back (sdir.midi_path());
5294 if (type == DataType::AUDIO) {
5295 const string sound_path_2X = _session_dir->sound_path_2X();
5296 if (Glib::file_test (sound_path_2X, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
5297 if (find (sp.begin(), sp.end(), sound_path_2X) == sp.end()) {
5298 sp.push_back (sound_path_2X);
5303 // now check the explicit (possibly user-specified) search path
5306 case DataType::AUDIO:
5307 sp += Searchpath(config.get_audio_search_path ());
5309 case DataType::MIDI:
5310 sp += Searchpath(config.get_midi_search_path ());
5318 Session::ensure_search_path_includes (const string& path, DataType type)
5327 case DataType::AUDIO:
5328 sp += Searchpath(config.get_audio_search_path ());
5330 case DataType::MIDI:
5331 sp += Searchpath (config.get_midi_search_path ());
5335 for (vector<std::string>::iterator i = sp.begin(); i != sp.end(); ++i) {
5336 /* No need to add this new directory if it has the same inode as
5337 an existing one; checking inode rather than name prevents duplicated
5338 directories when we are using symlinks.
5340 On Windows, I think we could just do if (*i == path) here.
5342 if (PBD::equivalent_paths (*i, path)) {
5350 case DataType::AUDIO:
5351 config.set_audio_search_path (sp.to_string());
5353 case DataType::MIDI:
5354 config.set_midi_search_path (sp.to_string());
5360 Session::remove_dir_from_search_path (const string& dir, DataType type)
5365 case DataType::AUDIO:
5366 sp = Searchpath(config.get_audio_search_path ());
5368 case DataType::MIDI:
5369 sp = Searchpath (config.get_midi_search_path ());
5376 case DataType::AUDIO:
5377 config.set_audio_search_path (sp.to_string());
5379 case DataType::MIDI:
5380 config.set_midi_search_path (sp.to_string());
5386 boost::shared_ptr<Speakers>
5387 Session::get_speakers()
5393 Session::unknown_processors () const
5397 boost::shared_ptr<RouteList> r = routes.reader ();
5398 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5399 list<string> t = (*i)->unknown_processors ();
5400 copy (t.begin(), t.end(), back_inserter (p));
5410 Session::update_latency (bool playback)
5412 DEBUG_TRACE (DEBUG::Latency, string_compose ("JACK latency callback: %1\n", (playback ? "PLAYBACK" : "CAPTURE")));
5414 if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress) {
5418 boost::shared_ptr<RouteList> r = routes.reader ();
5419 framecnt_t max_latency = 0;
5422 /* reverse the list so that we work backwards from the last route to run to the first */
5423 RouteList* rl = routes.reader().get();
5424 r.reset (new RouteList (*rl));
5425 reverse (r->begin(), r->end());
5428 /* compute actual latency values for the given direction and store them all in per-port
5429 structures. this will also publish the same values (to JACK) so that computation of latency
5430 for routes can consistently use public latency values.
5433 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5434 max_latency = max (max_latency, (*i)->set_private_port_latencies (playback));
5437 /* because we latency compensate playback, our published playback latencies should
5438 be the same for all output ports - all material played back by ardour has
5439 the same latency, whether its caused by plugins or by latency compensation. since
5440 these may differ from the values computed above, reset all playback port latencies
5444 DEBUG_TRACE (DEBUG::Latency, string_compose ("Set public port latencies to %1\n", max_latency));
5446 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5447 (*i)->set_public_port_latencies (max_latency, playback);
5452 post_playback_latency ();
5456 post_capture_latency ();
5459 DEBUG_TRACE (DEBUG::Latency, "JACK latency callback: DONE\n");
5463 Session::post_playback_latency ()
5465 set_worst_playback_latency ();
5467 boost::shared_ptr<RouteList> r = routes.reader ();
5469 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5470 if (!(*i)->is_auditioner() && ((*i)->active())) {
5471 _worst_track_latency = max (_worst_track_latency, (*i)->update_signal_latency ());
5475 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5476 (*i)->set_latency_compensation (_worst_track_latency);
5481 Session::post_capture_latency ()
5483 set_worst_capture_latency ();
5485 /* reflect any changes in capture latencies into capture offsets
5488 boost::shared_ptr<RouteList> rl = routes.reader();
5489 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
5490 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
5492 tr->set_capture_offset ();
5498 Session::initialize_latencies ()
5501 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
5502 update_latency (false);
5503 update_latency (true);
5506 set_worst_io_latencies ();
5510 Session::set_worst_io_latencies ()
5512 set_worst_playback_latency ();
5513 set_worst_capture_latency ();
5517 Session::set_worst_playback_latency ()
5519 if (_state_of_the_state & (InitialConnecting|Deletion)) {
5523 _worst_output_latency = 0;
5525 if (!_engine.connected()) {
5529 boost::shared_ptr<RouteList> r = routes.reader ();
5531 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5532 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
5535 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst output latency: %1\n", _worst_output_latency));
5539 Session::set_worst_capture_latency ()
5541 if (_state_of_the_state & (InitialConnecting|Deletion)) {
5545 _worst_input_latency = 0;
5547 if (!_engine.connected()) {
5551 boost::shared_ptr<RouteList> r = routes.reader ();
5553 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5554 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
5557 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst input latency: %1\n", _worst_input_latency));
5561 Session::update_latency_compensation (bool force_whole_graph)
5563 bool some_track_latency_changed = false;
5565 if (_state_of_the_state & (InitialConnecting|Deletion)) {
5569 DEBUG_TRACE(DEBUG::Latency, "---------------------------- update latency compensation\n\n");
5571 _worst_track_latency = 0;
5573 boost::shared_ptr<RouteList> r = routes.reader ();
5575 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5576 if (!(*i)->is_auditioner() && ((*i)->active())) {
5578 if ((*i)->signal_latency () != (tl = (*i)->update_signal_latency ())) {
5579 some_track_latency_changed = true;
5581 _worst_track_latency = max (tl, _worst_track_latency);
5585 DEBUG_TRACE (DEBUG::Latency, string_compose ("worst signal processing latency: %1 (changed ? %2)\n", _worst_track_latency,
5586 (some_track_latency_changed ? "yes" : "no")));
5588 DEBUG_TRACE(DEBUG::Latency, "---------------------------- DONE update latency compensation\n\n");
5590 if (some_track_latency_changed || force_whole_graph) {
5591 _engine.update_latencies ();
5595 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5596 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
5600 tr->set_capture_offset ();
5605 Session::session_name_is_legal (const string& path)
5607 char illegal_chars[] = { '/', '\\', ':', ';', '\0' };
5609 for (int i = 0; illegal_chars[i]; ++i) {
5610 if (path.find (illegal_chars[i]) != string::npos) {
5611 return illegal_chars[i];
5619 Session::next_control_id () const
5623 /* the monitor bus remote ID is in a different
5624 * "namespace" than regular routes. its existence doesn't
5625 * affect normal (low) numbered routes.
5632 return nroutes() - subtract;
5636 Session::notify_remote_id_change ()
5638 if (deletion_in_progress()) {
5642 switch (Config->get_remote_model()) {
5644 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
5652 Session::sync_order_keys ()
5654 if (deletion_in_progress()) {
5658 /* tell everyone that something has happened to the sort keys
5659 and let them sync up with the change(s)
5660 this will give objects that manage the sort order keys the
5661 opportunity to keep them in sync if they wish to.
5664 DEBUG_TRACE (DEBUG::OrderKeys, "Sync Order Keys.\n");
5666 reassign_track_numbers();
5668 Route::SyncOrderKeys (); /* EMIT SIGNAL */
5670 DEBUG_TRACE (DEBUG::OrderKeys, "\tsync done\n");
5674 Session::operation_in_progress (GQuark op) const
5676 return (find (_current_trans_quarks.begin(), _current_trans_quarks.end(), op) != _current_trans_quarks.end());
5679 boost::shared_ptr<Port>
5680 Session::ltc_input_port () const
5682 return _ltc_input->nth (0);
5685 boost::shared_ptr<Port>
5686 Session::ltc_output_port () const
5688 return _ltc_output->nth (0);
5692 Session::reconnect_ltc_input ()
5696 string src = Config->get_ltc_source_port();
5698 _ltc_input->disconnect (this);
5700 if (src != _("None") && !src.empty()) {
5701 _ltc_input->nth (0)->connect (src);
5707 Session::reconnect_ltc_output ()
5712 string src = Config->get_ltc_sink_port();
5714 _ltc_output->disconnect (this);
5716 if (src != _("None") && !src.empty()) {
5717 _ltc_output->nth (0)->connect (src);