2 Copyright (C) 2000 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.
24 #include <sigc++/bind.h>
25 #include <pbd/xml++.h>
26 #include <pbd/enumwriter.h>
28 #include <ardour/timestamps.h>
29 #include <ardour/audioengine.h>
30 #include <ardour/route.h>
31 #include <ardour/buffer.h>
32 #include <ardour/insert.h>
33 #include <ardour/send.h>
34 #include <ardour/session.h>
35 #include <ardour/utils.h>
36 #include <ardour/configuration.h>
37 #include <ardour/cycle_timer.h>
38 #include <ardour/route_group.h>
39 #include <ardour/port.h>
40 #include <ardour/audio_port.h>
41 #include <ardour/ladspa_plugin.h>
42 #include <ardour/panner.h>
43 #include <ardour/dB.h>
44 #include <ardour/amp.h>
45 #include <ardour/meter.h>
46 #include <ardour/buffer_set.h>
50 using namespace ARDOUR;
53 uint32_t Route::order_key_cnt = 0;
56 Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg, DataType default_type)
57 : IO (sess, name, input_min, input_max, output_min, output_max, default_type),
59 _solo_control (X_("solo"), *this, ToggleControllable::SoloControl),
60 _mute_control (X_("mute"), *this, ToggleControllable::MuteControl)
65 Route::Route (Session& sess, const XMLNode& node, DataType default_type)
66 : IO (sess, *node.child ("IO"), default_type),
67 _solo_control (X_("solo"), *this, ToggleControllable::SoloControl),
68 _mute_control (X_("mute"), *this, ToggleControllable::MuteControl)
71 _set_state (node, false);
77 redirect_max_outs.reset();
81 _phase_invert = false;
82 order_keys[strdup (N_("signal"))] = order_key_cnt++;
85 _meter_point = MeterPostFader;
89 _have_internal_generator = false;
91 _pending_declick = true;
92 _remote_control_id = 0;
97 _mute_affects_pre_fader = Config->get_mute_affects_pre_fader();
98 _mute_affects_post_fader = Config->get_mute_affects_post_fader();
99 _mute_affects_control_outs = Config->get_mute_affects_control_outs();
100 _mute_affects_main_outs = Config->get_mute_affects_main_outs();
103 desired_solo_gain = 1.0;
105 desired_mute_gain = 1.0;
109 input_changed.connect (mem_fun (this, &Route::input_change_handler));
110 output_changed.connect (mem_fun (this, &Route::output_change_handler));
115 clear_redirects (PreFader, this);
116 clear_redirects (PostFader, this);
118 for (OrderKeys::iterator i = order_keys.begin(); i != order_keys.end(); ++i) {
119 free ((void*)(i->first));
123 delete _control_outs;
128 Route::set_remote_control_id (uint32_t id)
130 if (id != _remote_control_id) {
131 _remote_control_id = id;
132 RemoteControlIDChanged ();
137 Route::remote_control_id() const
139 return _remote_control_id;
143 Route::order_key (const char* name) const
145 OrderKeys::const_iterator i;
147 for (i = order_keys.begin(); i != order_keys.end(); ++i) {
148 if (!strcmp (name, i->first)) {
157 Route::set_order_key (const char* name, long n)
159 order_keys[strdup(name)] = n;
160 _session.set_dirty ();
164 Route::inc_gain (gain_t fraction, void *src)
166 IO::inc_gain (fraction, src);
170 Route::set_gain (gain_t val, void *src)
172 if (src != 0 && _mix_group && src != _mix_group && _mix_group->is_active()) {
174 if (_mix_group->is_relative()) {
177 gain_t usable_gain = gain();
178 if (usable_gain < 0.000001f) {
179 usable_gain=0.000001f;
183 if (delta < 0.000001f) {
187 delta -= usable_gain;
189 if (delta == 0.0f) return;
191 gain_t factor = delta / usable_gain;
194 factor = _mix_group->get_max_factor(factor);
195 if (factor == 0.0f) {
200 factor = _mix_group->get_min_factor(factor);
201 if (factor == 0.0f) {
207 _mix_group->apply (&Route::inc_gain, factor, _mix_group);
211 _mix_group->apply (&Route::set_gain, val, _mix_group);
221 IO::set_gain (val, src);
224 /** Process this route for one (sub) cycle (process thread)
226 * @param bufs Scratch buffers to use for the signal path
227 * @param start_frame Initial transport frame
228 * @param end_frame Final transport frame
229 * @param nframes Number of frames to output (to ports)
230 * @param offset Output offset (of port buffers, for split cycles)
232 * Note that (end_frame - start_frame) may not be equal to nframes when the
233 * transport speed isn't 1.0 (eg varispeed).
236 Route::process_output_buffers (BufferSet& bufs,
237 nframes_t start_frame, nframes_t end_frame,
238 nframes_t nframes, nframes_t offset, bool with_redirects, int declick,
241 // This is definitely very audio-only for now
242 assert(_default_type == DataType::AUDIO);
244 RedirectList::iterator i;
245 bool post_fader_work = false;
246 bool mute_declick_applied = false;
252 gain_t* gab = _session.gain_automation_buffer();
254 switch (Config->get_monitoring_model()) {
255 case HardwareMonitoring:
256 case ExternalMonitoring:
263 declick = _pending_declick;
266 Glib::Mutex::Lock cm (control_outs_lock, Glib::TRY_LOCK);
276 Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK);
279 dmg = desired_mute_gain;
280 dsg = desired_solo_gain;
289 /* ----------------------------------------------------------------------------------------------------
290 GLOBAL DECLICK (for transport changes etc.)
291 -------------------------------------------------------------------------------------------------- */
294 Amp::run (bufs, nframes, 0.0, 1.0, false);
295 _pending_declick = 0;
296 } else if (declick < 0) {
297 Amp::run (bufs, nframes, 1.0, 0.0, false);
298 _pending_declick = 0;
301 /* no global declick */
303 if (solo_gain != dsg) {
304 Amp::run (bufs, nframes, solo_gain, dsg, false);
310 /* ----------------------------------------------------------------------------------------------------
311 INPUT METERING & MONITORING
312 -------------------------------------------------------------------------------------------------- */
314 if (meter && (_meter_point == MeterInput)) {
315 _meter->run(bufs, nframes);
318 if (!_soloed && _mute_affects_pre_fader && (mute_gain != dmg)) {
319 Amp::run (bufs, nframes, mute_gain, dmg, false);
321 mute_declick_applied = true;
324 if ((_meter_point == MeterInput) && co) {
326 solo_audible = dsg > 0;
327 mute_audible = dmg > 0;// || !_mute_affects_pre_fader;
329 if ( // muted by solo of another track
333 // muted by mute of this track
337 // rec-enabled but not s/w monitoring
339 // TODO: this is probably wrong
341 (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording()))
345 co->silence (nframes, offset);
349 co->deliver_output (bufs, start_frame, end_frame, nframes, offset);
354 /* ---------------------------------------------------------------------------------------------------
356 -------------------------------------------------------------------------------------------------- */
358 /* FIXME: Somewhere in these loops is where bufs.count() should go from n_inputs() to redirect_max_outs()
359 * (if they differ). Something explicit needs to be done here to make sure the list of redirects will
360 * give us what we need (possibly by inserting transparent 'translators' into the list to make it work) */
362 if (with_redirects) {
363 Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK);
365 if (mute_gain > 0 || !_mute_affects_pre_fader) {
366 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
367 switch ((*i)->placement()) {
369 (*i)->run (bufs, start_frame, end_frame, nframes, offset);
372 post_fader_work = true;
377 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
378 switch ((*i)->placement()) {
380 (*i)->silence (nframes, offset);
383 post_fader_work = true;
391 // FIXME: for now, just hope the redirects list did what it was supposed to
392 bufs.set_count(n_process_buffers());
395 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_post_fader) {
396 Amp::run (bufs, nframes, mute_gain, dmg, false);
398 mute_declick_applied = true;
401 /* ----------------------------------------------------------------------------------------------------
402 PRE-FADER METERING & MONITORING
403 -------------------------------------------------------------------------------------------------- */
405 if (meter && (_meter_point == MeterPreFader)) {
406 _meter->run(bufs, nframes);
410 if ((_meter_point == MeterPreFader) && co) {
412 solo_audible = dsg > 0;
413 mute_audible = dmg > 0 || !_mute_affects_pre_fader;
415 if ( // muted by solo of another track
419 // muted by mute of this track
423 // rec-enabled but not s/w monitoring
425 (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording()))
429 co->silence (nframes, offset);
433 co->deliver_output (bufs, start_frame, end_frame, nframes, offset);
437 /* ----------------------------------------------------------------------------------------------------
439 -------------------------------------------------------------------------------------------------- */
441 /* if not recording or recording and requiring any monitor signal, then apply gain */
443 if ( // not recording
445 !(record_enabled() && _session.actively_recording()) ||
449 // h/w monitoring not in use
451 (!Config->get_monitoring_model() == HardwareMonitoring &&
453 // AND software monitoring required
455 Config->get_monitoring_model() == SoftwareMonitoring)) {
457 if (apply_gain_automation) {
460 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
461 Sample* const sp = i->data();
463 for (nframes_t nx = 0; nx < nframes; ++nx) {
468 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
469 Sample* const sp = i->data();
471 for (nframes_t nx = 0; nx < nframes; ++nx) {
477 if (apply_gain_automation && _session.transport_rolling() && nframes > 0) {
478 _effective_gain = gab[nframes-1];
483 /* manual (scalar) gain */
487 Amp::run (bufs, nframes, _gain, dg, _phase_invert);
490 } else if (_gain != 0 && (_phase_invert || _gain != 1.0)) {
492 /* no need to interpolate current gain value,
493 but its non-unity, so apply it. if the gain
494 is zero, do nothing because we'll ship silence
506 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
507 Sample* const sp = i->data();
508 apply_gain_to_buffer(sp,nframes,this_gain);
511 } else if (_gain == 0) {
512 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
520 /* actively recording, no monitoring required; leave buffers as-is to save CPU cycles */
524 /* ----------------------------------------------------------------------------------------------------
526 -------------------------------------------------------------------------------------------------- */
528 /* note that post_fader_work cannot be true unless with_redirects was also true, so don't test both */
530 if (post_fader_work) {
532 Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK);
534 if (mute_gain > 0 || !_mute_affects_post_fader) {
535 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
536 switch ((*i)->placement()) {
540 (*i)->run (bufs, start_frame, end_frame, nframes, offset);
545 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
546 switch ((*i)->placement()) {
550 (*i)->silence (nframes, offset);
558 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_control_outs) {
559 Amp::run (bufs, nframes, mute_gain, dmg, false);
561 mute_declick_applied = true;
564 /* ----------------------------------------------------------------------------------------------------
566 -------------------------------------------------------------------------------------------------- */
568 if ((_meter_point == MeterPostFader) && co) {
570 solo_audible = solo_gain > 0;
571 mute_audible = dmg > 0 || !_mute_affects_control_outs;
573 if ( // silent anyway
575 (_gain == 0 && !apply_gain_automation) ||
577 // muted by solo of another track
581 // muted by mute of this track
585 // recording but not s/w monitoring
587 (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording()))
591 co->silence (nframes, offset);
595 co->deliver_output (bufs, start_frame, end_frame, nframes, offset);
599 /* ----------------------------------------------------------------------
601 ----------------------------------------------------------------------*/
603 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_main_outs) {
604 Amp::run (bufs, nframes, mute_gain, dmg, false);
606 mute_declick_applied = true;
609 /* ----------------------------------------------------------------------------------------------------
611 -------------------------------------------------------------------------------------------------- */
613 solo_audible = dsg > 0;
614 mute_audible = dmg > 0 || !_mute_affects_main_outs;
616 if (n_outputs().get(_default_type) == 0) {
620 } else if (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording())) {
622 IO::silence (nframes, offset);
626 if ( // silent anyway
628 (_gain == 0 && !apply_gain_automation) ||
630 // muted by solo of another track, but not using control outs for solo
632 (!solo_audible && (Config->get_solo_model() != SoloBus)) ||
634 // muted by mute of this track
640 /* don't use Route::silence() here, because that causes
641 all outputs (sends, port inserts, etc. to be silent).
644 if (_meter_point == MeterPostFader) {
645 peak_meter().reset();
648 IO::silence (nframes, offset);
652 deliver_output(bufs, start_frame, end_frame, nframes, offset);
658 /* ----------------------------------------------------------------------------------------------------
660 -------------------------------------------------------------------------------------------------- */
662 if (meter && (_meter_point == MeterPostFader)) {
663 if ((_gain == 0 && !apply_gain_automation) || dmg == 0) {
666 _meter->run(output_buffers(), nframes, offset);
672 Route::n_process_buffers ()
674 return max (n_inputs(), redirect_max_outs);
678 Route::passthru (nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset, int declick, bool meter_first)
680 BufferSet& bufs = _session.get_scratch_buffers(n_process_buffers());
684 collect_input (bufs, nframes, offset);
686 #define meter_stream meter_first
689 _meter->run(bufs, nframes);
690 meter_stream = false;
695 process_output_buffers (bufs, start_frame, end_frame, nframes, offset, true, declick, meter_stream);
701 Route::passthru_silence (nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset, int declick, bool meter)
703 process_output_buffers (_session.get_silent_buffers (n_process_buffers()), start_frame, end_frame, nframes, offset, true, declick, meter);
707 Route::set_solo (bool yn, void *src)
713 if (_mix_group && src != _mix_group && _mix_group->is_active()) {
714 _mix_group->apply (&Route::set_solo, yn, _mix_group);
720 solo_changed (src); /* EMIT SIGNAL */
721 _solo_control.Changed (); /* EMIT SIGNAL */
726 Route::set_solo_mute (bool yn)
728 Glib::Mutex::Lock lm (declick_lock);
730 /* Called by Session in response to another Route being soloed.
733 desired_solo_gain = (yn?0.0:1.0);
737 Route::set_solo_safe (bool yn, void *src)
739 if (_solo_safe != yn) {
741 solo_safe_changed (src); /* EMIT SIGNAL */
746 Route::set_mute (bool yn, void *src)
749 if (_mix_group && src != _mix_group && _mix_group->is_active()) {
750 _mix_group->apply (&Route::set_mute, yn, _mix_group);
756 mute_changed (src); /* EMIT SIGNAL */
758 _mute_control.Changed (); /* EMIT SIGNAL */
760 Glib::Mutex::Lock lm (declick_lock);
761 desired_mute_gain = (yn?0.0f:1.0f);
766 Route::add_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
768 ChanCount old_rmo = redirect_max_outs;
770 if (!_session.engine().connected()) {
775 Glib::RWLock::WriterLock lm (redirect_lock);
777 boost::shared_ptr<PluginInsert> pi;
778 boost::shared_ptr<PortInsert> porti;
780 redirect->set_default_type(_default_type);
782 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(redirect)) != 0) {
785 if (pi->input_streams() == ChanCount::ZERO) {
786 /* generator plugin */
787 _have_internal_generator = true;
790 } else if ((porti = boost::dynamic_pointer_cast<PortInsert>(redirect)) != 0) {
792 /* force new port inserts to start out with an i/o configuration
793 that matches this route's i/o configuration.
795 the "inputs" for the port are supposed to match the output
798 the "outputs" of the route should match the inputs of this
799 route. XXX shouldn't they match the number of active signal
800 streams at the point of insertion?
802 // FIXME: (yes, they should)
804 porti->ensure_io (n_outputs (), n_inputs(), false, this);
807 // Ensure peak vector sizes before the plugin is activated
808 ChanCount potential_max_streams = max(redirect->input_streams(), redirect->output_streams());
809 _meter->setup(potential_max_streams);
811 _redirects.push_back (redirect);
813 if (_reset_plugin_counts (err_streams)) {
814 _redirects.pop_back ();
815 _reset_plugin_counts (0); // it worked before we tried to add it ...
819 redirect->activate ();
820 redirect->active_changed.connect (mem_fun (*this, &Route::redirect_active_proxy));
823 if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
828 redirects_changed (src); /* EMIT SIGNAL */
833 Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_streams)
835 ChanCount old_rmo = redirect_max_outs;
837 if (!_session.engine().connected()) {
842 Glib::RWLock::WriterLock lm (redirect_lock);
844 RedirectList::iterator existing_end = _redirects.end();
847 ChanCount potential_max_streams;
849 for (RedirectList::const_iterator i = others.begin(); i != others.end(); ++i) {
851 boost::shared_ptr<PluginInsert> pi;
853 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
856 ChanCount m = max(pi->input_streams(), pi->output_streams());
857 if (m > potential_max_streams)
858 potential_max_streams = m;
861 // Ensure peak vector sizes before the plugin is activated
862 _meter->setup(potential_max_streams);
864 _redirects.push_back (*i);
866 if (_reset_plugin_counts (err_streams)) {
868 _redirects.erase (existing_end, _redirects.end());
869 _reset_plugin_counts (0); // it worked before we tried to add it ...
874 (*i)->active_changed.connect (mem_fun (*this, &Route::redirect_active_proxy));
878 if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
882 redirects_changed (src); /* EMIT SIGNAL */
886 /** Remove redirects with a given placement.
887 * @param p Placement of redirects to remove.
890 Route::clear_redirects (Placement p, void *src)
892 const ChanCount old_rmo = redirect_max_outs;
894 if (!_session.engine().connected()) {
899 Glib::RWLock::WriterLock lm (redirect_lock);
900 RedirectList new_list;
902 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
903 if ((*i)->placement() == p) {
904 /* it's the placement we want to get rid of */
905 (*i)->drop_references ();
907 /* it's a different placement, so keep it */
908 new_list.push_back (*i);
912 _redirects = new_list;
915 /* FIXME: can't see how this test can ever fire */
916 if (redirect_max_outs != old_rmo) {
920 redirect_max_outs.reset();
921 _have_internal_generator = false;
922 redirects_changed (src); /* EMIT SIGNAL */
926 Route::remove_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
928 ChanCount old_rmo = redirect_max_outs;
930 if (!_session.engine().connected()) {
934 redirect_max_outs.reset();
937 Glib::RWLock::WriterLock lm (redirect_lock);
938 RedirectList::iterator i;
939 bool removed = false;
941 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
942 if (*i == redirect) {
944 RedirectList::iterator tmp;
946 /* move along, see failure case for reset_plugin_counts()
947 where we may need to reinsert the redirect.
953 /* stop redirects that send signals to JACK ports
954 from causing noise as a result of no longer being
958 boost::shared_ptr<Send> send;
959 boost::shared_ptr<PortInsert> port_insert;
961 if ((send = boost::dynamic_pointer_cast<Send> (*i)) != 0) {
962 send->disconnect_inputs (this);
963 send->disconnect_outputs (this);
964 } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (*i)) != 0) {
965 port_insert->disconnect_inputs (this);
966 port_insert->disconnect_outputs (this);
969 _redirects.erase (i);
982 if (_reset_plugin_counts (err_streams)) {
983 /* get back to where we where */
984 _redirects.insert (i, redirect);
985 /* we know this will work, because it worked before :) */
986 _reset_plugin_counts (0);
992 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
993 boost::shared_ptr<PluginInsert> pi;
995 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
996 if (pi->is_generator()) {
1002 _have_internal_generator = foo;
1005 if (old_rmo != redirect_max_outs) {
1009 redirect->drop_references ();
1011 redirects_changed (src); /* EMIT SIGNAL */
1016 Route::reset_plugin_counts (uint32_t* lpc)
1018 Glib::RWLock::WriterLock lm (redirect_lock);
1019 return _reset_plugin_counts (lpc);
1024 Route::_reset_plugin_counts (uint32_t* err_streams)
1026 RedirectList::iterator r;
1029 map<Placement,list<InsertCount> > insert_map;
1030 nframes_t initial_streams;
1032 redirect_max_outs.reset();
1036 /* divide inserts up by placement so we get the signal flow
1037 properly modelled. we need to do this because the _redirects
1038 list is not sorted by placement, and because other reasons may
1039 exist now or in the future for this separate treatment.
1042 for (r = _redirects.begin(); r != _redirects.end(); ++r) {
1044 boost::shared_ptr<Insert> insert;
1046 /* do this here in case we bomb out before we get to the end of
1050 redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs);
1052 if ((insert = boost::dynamic_pointer_cast<Insert>(*r)) != 0) {
1054 insert_map[insert->placement()].push_back (InsertCount (insert));
1056 /* reset plugin counts back to one for now so
1057 that we have a predictable, controlled
1058 state to try to configure.
1061 boost::shared_ptr<PluginInsert> pi;
1063 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(insert)) != 0) {
1067 } else if (boost::dynamic_pointer_cast<Send> (*r) != 0) {
1080 /* Now process each placement in order, checking to see if we
1081 can really do what has been requested.
1086 if (check_some_plugin_counts (insert_map[PreFader], n_inputs ().get(_default_type), err_streams)) {
1090 /* figure out the streams that will feed into PreFader */
1092 if (!insert_map[PreFader].empty()) {
1093 InsertCount& ic (insert_map[PreFader].back());
1094 initial_streams = ic.insert->compute_output_streams (ic.cnt);
1096 initial_streams = n_inputs ().get(_default_type);
1101 if (check_some_plugin_counts (insert_map[PostFader], initial_streams, err_streams)) {
1105 /* OK, everything can be set up correctly, so lets do it */
1107 apply_some_plugin_counts (insert_map[PreFader]);
1108 apply_some_plugin_counts (insert_map[PostFader]);
1110 /* recompute max outs of any redirect */
1114 redirect_max_outs.reset();
1115 RedirectList::iterator prev = _redirects.end();
1117 for (r = _redirects.begin(); r != _redirects.end(); prev = r, ++r) {
1118 boost::shared_ptr<Send> s;
1120 if ((s = boost::dynamic_pointer_cast<Send> (*r)) != 0) {
1121 if (r == _redirects.begin()) {
1122 s->expect_inputs (n_inputs());
1124 s->expect_inputs ((*prev)->output_streams());
1129 /* don't pay any attention to send output configuration, since it doesn't
1133 redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs);
1144 Route::apply_some_plugin_counts (list<InsertCount>& iclist)
1146 list<InsertCount>::iterator i;
1148 for (i = iclist.begin(); i != iclist.end(); ++i) {
1150 if ((*i).insert->configure_io ((*i).cnt, (*i).in, (*i).out)) {
1153 /* make sure that however many we have, they are all active */
1154 (*i).insert->activate ();
1161 Route::check_some_plugin_counts (list<InsertCount>& iclist, int32_t required_inputs, uint32_t* err_streams)
1163 list<InsertCount>::iterator i;
1165 for (i = iclist.begin(); i != iclist.end(); ++i) {
1167 if (((*i).cnt = (*i).insert->can_support_input_configuration (required_inputs)) < 0) {
1169 *err_streams = required_inputs;
1174 (*i).in = required_inputs;
1175 (*i).out = (*i).insert->compute_output_streams ((*i).cnt);
1177 required_inputs = (*i).out;
1184 Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_streams)
1186 ChanCount old_rmo = redirect_max_outs;
1192 RedirectList to_be_deleted;
1195 Glib::RWLock::WriterLock lm (redirect_lock);
1196 RedirectList::iterator tmp;
1197 RedirectList the_copy;
1199 the_copy = _redirects;
1201 /* remove all relevant redirects */
1203 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ) {
1207 if ((*i)->placement() == placement) {
1208 to_be_deleted.push_back (*i);
1209 _redirects.erase (i);
1215 /* now copy the relevant ones from "other" */
1217 for (RedirectList::const_iterator i = other._redirects.begin(); i != other._redirects.end(); ++i) {
1218 if ((*i)->placement() == placement) {
1219 _redirects.push_back (Redirect::clone (*i));
1223 /* reset plugin stream handling */
1225 if (_reset_plugin_counts (err_streams)) {
1227 /* FAILED COPY ATTEMPT: we have to restore order */
1229 /* delete all cloned redirects */
1231 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ) {
1236 if ((*i)->placement() == placement) {
1237 _redirects.erase (i);
1243 /* restore the natural order */
1245 _redirects = the_copy;
1246 redirect_max_outs = old_rmo;
1248 /* we failed, even though things are OK again */
1254 /* SUCCESSFUL COPY ATTEMPT: delete the redirects we removed pre-copy */
1255 to_be_deleted.clear ();
1259 if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
1263 redirects_changed (this); /* EMIT SIGNAL */
1268 Route::all_redirects_flip ()
1270 Glib::RWLock::ReaderLock lm (redirect_lock);
1272 if (_redirects.empty()) {
1276 bool first_is_on = _redirects.front()->active();
1278 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1279 (*i)->set_active (!first_is_on, this);
1283 /** Set all redirects with a given placement to a given active state.
1284 * @param p Placement of redirects to change.
1285 * @param state New active state for those redirects.
1288 Route::all_redirects_active (Placement p, bool state)
1290 Glib::RWLock::ReaderLock lm (redirect_lock);
1292 if (_redirects.empty()) {
1296 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1297 if ((*i)->placement() == p) {
1298 (*i)->set_active (state, this);
1303 struct RedirectSorter {
1304 bool operator() (boost::shared_ptr<const Redirect> a, boost::shared_ptr<const Redirect> b) {
1305 return a->sort_key() < b->sort_key();
1310 Route::sort_redirects (uint32_t* err_streams)
1313 RedirectSorter comparator;
1314 Glib::RWLock::WriterLock lm (redirect_lock);
1315 ChanCount old_rmo = redirect_max_outs;
1317 /* the sweet power of C++ ... */
1319 RedirectList as_it_was_before = _redirects;
1321 _redirects.sort (comparator);
1323 if (_reset_plugin_counts (err_streams)) {
1324 _redirects = as_it_was_before;
1325 redirect_max_outs = old_rmo;
1331 redirects_changed (this); /* EMIT SIGNAL */
1343 Route::get_template()
1345 return state(false);
1349 Route::state(bool full_state)
1351 XMLNode *node = new XMLNode("Route");
1352 RedirectList:: iterator i;
1356 node->add_property("flags", enum_2_string (_flags));
1359 node->add_property("default-type", _default_type.to_string());
1361 node->add_property("active", _active?"yes":"no");
1362 node->add_property("muted", _muted?"yes":"no");
1363 node->add_property("soloed", _soloed?"yes":"no");
1364 node->add_property("phase-invert", _phase_invert?"yes":"no");
1365 node->add_property("mute-affects-pre-fader", _mute_affects_pre_fader?"yes":"no");
1366 node->add_property("mute-affects-post-fader", _mute_affects_post_fader?"yes":"no");
1367 node->add_property("mute-affects-control-outs", _mute_affects_control_outs?"yes":"no");
1368 node->add_property("mute-affects-main-outs", _mute_affects_main_outs?"yes":"no");
1371 node->add_property("edit-group", _edit_group->name());
1374 node->add_property("mix-group", _mix_group->name());
1377 string order_string;
1378 OrderKeys::iterator x = order_keys.begin();
1380 while (x != order_keys.end()) {
1381 order_string += string ((*x).first);
1382 order_string += '=';
1383 snprintf (buf, sizeof(buf), "%ld", (*x).second);
1384 order_string += buf;
1388 if (x == order_keys.end()) {
1392 order_string += ':';
1394 node->add_property ("order-keys", order_string);
1396 node->add_child_nocopy (IO::state (full_state));
1397 node->add_child_nocopy (_solo_control.get_state ());
1398 node->add_child_nocopy (_mute_control.get_state ());
1400 XMLNode* remote_control_node = new XMLNode (X_("remote_control"));
1401 snprintf (buf, sizeof (buf), "%d", _remote_control_id);
1402 remote_control_node->add_property (X_("id"), buf);
1403 node->add_child_nocopy (*remote_control_node);
1405 if (_control_outs) {
1406 XMLNode* cnode = new XMLNode (X_("ControlOuts"));
1407 cnode->add_child_nocopy (_control_outs->state (full_state));
1408 node->add_child_nocopy (*cnode);
1411 if (_comment.length()) {
1412 XMLNode *cmt = node->add_child ("Comment");
1413 cmt->add_content (_comment);
1416 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
1417 node->add_child_nocopy((*i)->state (full_state));
1421 node->add_child_copy (*_extra_xml);
1428 Route::set_deferred_state ()
1431 XMLNodeConstIterator niter;
1433 if (!deferred_state) {
1437 nlist = deferred_state->children();
1439 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1440 add_redirect_from_xml (**niter);
1443 delete deferred_state;
1448 Route::add_redirect_from_xml (const XMLNode& node)
1450 const XMLProperty *prop;
1452 if (node.name() == "Send") {
1456 boost::shared_ptr<Send> send (new Send (_session, node));
1457 add_redirect (send, this);
1460 catch (failed_constructor &err) {
1461 error << _("Send construction failed") << endmsg;
1465 } else if (node.name() == "Insert") {
1468 if ((prop = node.property ("type")) != 0) {
1470 boost::shared_ptr<Insert> insert;
1472 if (prop->value() == "ladspa" || prop->value() == "Ladspa" || prop->value() == "vst") {
1474 insert.reset (new PluginInsert(_session, node));
1476 } else if (prop->value() == "port") {
1479 insert.reset (new PortInsert (_session, node));
1483 error << string_compose(_("unknown Insert type \"%1\"; ignored"), prop->value()) << endmsg;
1486 add_redirect (insert, this);
1489 error << _("Insert XML node has no type property") << endmsg;
1493 catch (failed_constructor &err) {
1494 warning << _("insert could not be created. Ignored.") << endmsg;
1501 Route::set_state (const XMLNode& node)
1503 return _set_state (node, true);
1507 Route::_set_state (const XMLNode& node, bool call_base)
1510 XMLNodeConstIterator niter;
1512 XMLPropertyList plist;
1513 const XMLProperty *prop;
1515 if (node.name() != "Route"){
1516 error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
1520 if ((prop = node.property (X_("flags"))) != 0) {
1521 _flags = Flag (string_2_enum (prop->value(), _flags));
1526 if ((prop = node.property (X_("default-type"))) != 0) {
1527 _default_type = DataType(prop->value());
1528 assert(_default_type != DataType::NIL);
1531 if ((prop = node.property (X_("phase-invert"))) != 0) {
1532 set_phase_invert(prop->value()=="yes"?true:false, this);
1535 if ((prop = node.property (X_("active"))) != 0) {
1536 set_active (prop->value() == "yes");
1539 if ((prop = node.property (X_("muted"))) != 0) {
1540 bool yn = prop->value()=="yes"?true:false;
1542 /* force reset of mute status */
1546 mute_gain = desired_mute_gain;
1549 if ((prop = node.property (X_("soloed"))) != 0) {
1550 bool yn = prop->value()=="yes"?true:false;
1552 /* force reset of solo status */
1555 set_solo (yn, this);
1556 solo_gain = desired_solo_gain;
1559 if ((prop = node.property (X_("mute-affects-pre-fader"))) != 0) {
1560 _mute_affects_pre_fader = (prop->value()=="yes")?true:false;
1563 if ((prop = node.property (X_("mute-affects-post-fader"))) != 0) {
1564 _mute_affects_post_fader = (prop->value()=="yes")?true:false;
1567 if ((prop = node.property (X_("mute-affects-control-outs"))) != 0) {
1568 _mute_affects_control_outs = (prop->value()=="yes")?true:false;
1571 if ((prop = node.property (X_("mute-affects-main-outs"))) != 0) {
1572 _mute_affects_main_outs = (prop->value()=="yes")?true:false;
1575 if ((prop = node.property (X_("edit-group"))) != 0) {
1576 RouteGroup* edit_group = _session.edit_group_by_name(prop->value());
1577 if(edit_group == 0) {
1578 error << string_compose(_("Route %1: unknown edit group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
1580 set_edit_group(edit_group, this);
1584 if ((prop = node.property (X_("order-keys"))) != 0) {
1588 string::size_type colon, equal;
1589 string remaining = prop->value();
1591 while (remaining.length()) {
1593 if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
1594 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1597 if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) {
1598 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1601 set_order_key (remaining.substr (0, equal).c_str(), n);
1605 colon = remaining.find_first_of (':');
1607 if (colon != string::npos) {
1608 remaining = remaining.substr (colon+1);
1615 nlist = node.children();
1617 if (deferred_state) {
1618 delete deferred_state;
1621 deferred_state = new XMLNode(X_("deferred state"));
1623 /* set parent class properties before anything else */
1625 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1629 if (child->name() == IO::state_node_name && call_base) {
1631 IO::set_state (*child);
1636 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1640 if (child->name() == X_("Send")) {
1643 if (!IO::ports_legal) {
1645 deferred_state->add_child_copy (*child);
1648 add_redirect_from_xml (*child);
1651 } else if (child->name() == X_("Insert")) {
1653 if (!IO::ports_legal) {
1655 deferred_state->add_child_copy (*child);
1659 add_redirect_from_xml (*child);
1662 } else if (child->name() == X_("Automation")) {
1664 if ((prop = child->property (X_("path"))) != 0) {
1665 load_automation (prop->value());
1668 } else if (child->name() == X_("ControlOuts")) {
1670 string coutname = _name;
1671 coutname += _("[control]");
1673 _control_outs = new IO (_session, coutname);
1674 _control_outs->set_state (**(child->children().begin()));
1676 } else if (child->name() == X_("Comment")) {
1678 /* XXX this is a terrible API design in libxml++ */
1680 XMLNode *cmt = *(child->children().begin());
1681 _comment = cmt->content();
1683 } else if (child->name() == X_("extra")) {
1685 _extra_xml = new XMLNode (*child);
1687 } else if (child->name() == X_("controllable") && (prop = child->property("name")) != 0) {
1689 if (prop->value() == "solo") {
1690 _solo_control.set_state (*child);
1691 _session.add_controllable (&_solo_control);
1693 else if (prop->value() == "mute") {
1694 _mute_control.set_state (*child);
1695 _session.add_controllable (&_mute_control);
1698 else if (child->name() == X_("remote_control")) {
1699 if ((prop = child->property (X_("id"))) != 0) {
1701 sscanf (prop->value().c_str(), "%d", &x);
1702 set_remote_control_id (x);
1707 if ((prop = node.property (X_("mix-group"))) != 0) {
1708 RouteGroup* mix_group = _session.mix_group_by_name(prop->value());
1709 if (mix_group == 0) {
1710 error << string_compose(_("Route %1: unknown mix group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
1712 set_mix_group(mix_group, this);
1720 Route::curve_reallocate ()
1722 // _gain_automation_curve.finish_resize ();
1723 // _pan_automation_curve.finish_resize ();
1727 Route::silence (nframes_t nframes, nframes_t offset)
1731 IO::silence (nframes, offset);
1733 if (_control_outs) {
1734 _control_outs->silence (nframes, offset);
1738 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
1741 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1742 boost::shared_ptr<PluginInsert> pi;
1743 if (!_active && (pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
1744 // skip plugins, they don't need anything when we're not active
1748 (*i)->silence (nframes, offset);
1751 if (nframes == _session.get_block_size() && offset == 0) {
1761 Route::set_control_outs (const vector<string>& ports)
1763 Glib::Mutex::Lock lm (control_outs_lock);
1764 vector<string>::const_iterator i;
1767 if (_control_outs) {
1768 delete _control_outs;
1772 if (control() || master()) {
1773 /* no control outs for these two special busses */
1777 if (ports.empty()) {
1781 string coutname = _name;
1782 coutname += _("[control]");
1784 _control_outs = new IO (_session, coutname);
1786 /* our control outs need as many outputs as we
1787 have audio outputs. we track the changes in ::output_change_handler().
1790 // XXX its stupid that we have to get this value twice
1792 limit = n_outputs().get(DataType::AUDIO);
1794 if (_control_outs->ensure_io (ChanCount::ZERO, ChanCount (DataType::AUDIO, n_outputs().get (DataType::AUDIO)), true, this)) {
1798 /* now connect to the named ports */
1800 for (size_t n = 0; n < limit; ++n) {
1801 if (_control_outs->connect_output (_control_outs->output (n), ports[n], this)) {
1802 error << string_compose (_("could not connect %1 to %2"), _control_outs->output(n)->name(), ports[n]) << endmsg;
1811 Route::set_edit_group (RouteGroup *eg, void *src)
1814 if (eg == _edit_group) {
1819 _edit_group->remove (this);
1822 if ((_edit_group = eg) != 0) {
1823 _edit_group->add (this);
1826 _session.set_dirty ();
1827 edit_group_changed (src); /* EMIT SIGNAL */
1831 Route::drop_edit_group (void *src)
1834 _session.set_dirty ();
1835 edit_group_changed (src); /* EMIT SIGNAL */
1839 Route::set_mix_group (RouteGroup *mg, void *src)
1842 if (mg == _mix_group) {
1847 _mix_group->remove (this);
1850 if ((_mix_group = mg) != 0) {
1851 _mix_group->add (this);
1854 _session.set_dirty ();
1855 mix_group_changed (src); /* EMIT SIGNAL */
1859 Route::drop_mix_group (void *src)
1862 _session.set_dirty ();
1863 mix_group_changed (src); /* EMIT SIGNAL */
1867 Route::set_comment (string cmt, void *src)
1870 comment_changed (src);
1871 _session.set_dirty ();
1875 Route::feeds (boost::shared_ptr<Route> other)
1880 uint32_t no = self.n_outputs().get_total();
1881 uint32_t ni = other->n_inputs ().get_total();
1883 for (i = 0; i < no; ++i) {
1884 for (j = 0; j < ni; ++j) {
1885 if (self.output(i)->connected_to (other->input(j)->name())) {
1891 /* check Redirects which may also interconnect Routes */
1893 for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); r++) {
1895 no = (*r)->n_outputs().get_total();
1897 for (i = 0; i < no; ++i) {
1898 for (j = 0; j < ni; ++j) {
1899 if ((*r)->output(i)->connected_to (other->input (j)->name())) {
1906 /* check for control room outputs which may also interconnect Routes */
1908 if (_control_outs) {
1910 no = _control_outs->n_outputs().get_total();
1912 for (i = 0; i < no; ++i) {
1913 for (j = 0; j < ni; ++j) {
1914 if (_control_outs->output(i)->connected_to (other->input (j)->name())) {
1925 Route::set_mute_config (mute_type t, bool onoff, void *src)
1929 _mute_affects_pre_fader = onoff;
1930 pre_fader_changed(src); /* EMIT SIGNAL */
1934 _mute_affects_post_fader = onoff;
1935 post_fader_changed(src); /* EMIT SIGNAL */
1939 _mute_affects_control_outs = onoff;
1940 control_outs_changed(src); /* EMIT SIGNAL */
1944 _mute_affects_main_outs = onoff;
1945 main_outs_changed(src); /* EMIT SIGNAL */
1951 Route::get_mute_config (mute_type t)
1957 onoff = _mute_affects_pre_fader;
1960 onoff = _mute_affects_post_fader;
1963 onoff = _mute_affects_control_outs;
1966 onoff = _mute_affects_main_outs;
1974 Route::set_active (bool yn)
1977 active_changed(); /* EMIT SIGNAL */
1981 Route::handle_transport_stopped (bool abort_ignored, bool did_locate, bool can_flush_redirects)
1983 nframes_t now = _session.transport_frame();
1986 Glib::RWLock::ReaderLock lm (redirect_lock);
1989 automation_snapshot (now);
1992 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1994 if (Config->get_plugins_stop_with_transport() && can_flush_redirects) {
1995 (*i)->deactivate ();
1999 (*i)->transport_stopped (now);
2003 IO::transport_stopped (now);
2005 _roll_delay = _initial_delay;
2009 Route::input_change_handler (IOChange change, void *ignored)
2011 if (change & ConfigurationChanged) {
2012 reset_plugin_counts (0);
2017 Route::output_change_handler (IOChange change, void *ignored)
2019 if (change & ConfigurationChanged) {
2020 if (_control_outs) {
2021 _control_outs->ensure_io (ChanCount::ZERO, ChanCount(DataType::AUDIO, n_outputs().get(DataType::AUDIO)), true, this);
2024 reset_plugin_counts (0);
2029 Route::pans_required () const
2031 if (n_outputs().get(DataType::AUDIO) < 2) {
2035 return max (n_inputs ().get(DataType::AUDIO), static_cast<size_t>(redirect_max_outs.get(DataType::AUDIO)));
2039 Route::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset,
2040 bool session_state_changing, bool can_record, bool rec_monitors_input)
2042 if (n_outputs().get_total() == 0) {
2046 if (session_state_changing || !_active) {
2047 silence (nframes, offset);
2051 apply_gain_automation = false;
2053 if (n_inputs().get_total()) {
2054 passthru (start_frame, end_frame, nframes, offset, 0, false);
2056 silence (nframes, offset);
2063 Route::check_initial_delay (nframes_t nframes, nframes_t& offset, nframes_t& transport_frame)
2065 if (_roll_delay > nframes) {
2067 _roll_delay -= nframes;
2068 silence (nframes, offset);
2069 /* transport frame is not legal for caller to use */
2072 } else if (_roll_delay > 0) {
2074 nframes -= _roll_delay;
2076 silence (_roll_delay, offset);
2078 offset += _roll_delay;
2079 transport_frame += _roll_delay;
2088 Route::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, int declick,
2089 bool can_record, bool rec_monitors_input)
2092 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
2094 // automation snapshot can also be called from the non-rt context
2095 // and it uses the redirect list, so we take the lock out here
2096 automation_snapshot (_session.transport_frame());
2100 if ((n_outputs().get_total() == 0 && _redirects.empty()) || n_inputs().get_total() == 0 || !_active) {
2101 silence (nframes, offset);
2105 nframes_t unused = 0;
2107 if ((nframes = check_initial_delay (nframes, offset, unused)) == 0) {
2113 apply_gain_automation = false;
2116 Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK);
2118 if (am.locked() && _session.transport_rolling()) {
2120 if (gain_automation_playback()) {
2121 apply_gain_automation = _gain_automation_curve.rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes);
2126 passthru (start_frame, end_frame, nframes, offset, declick, false);
2132 Route::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset,
2133 bool can_record, bool rec_monitors_input)
2135 silence (nframes, offset);
2140 Route::toggle_monitor_input ()
2142 for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
2143 i->ensure_monitor_input( ! i->monitoring_input());
2148 Route::has_external_redirects () const
2150 boost::shared_ptr<const PortInsert> pi;
2152 for (RedirectList::const_iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2153 if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*i)) != 0) {
2155 for (PortSet::const_iterator port = pi->outputs().begin();
2156 port != pi->outputs().end(); ++port) {
2158 string port_name = port->name();
2159 string client_name = port_name.substr (0, port_name.find(':'));
2161 /* only say "yes" if the redirect is actually in use */
2163 if (client_name != "ardour" && pi->active()) {
2174 Route::flush_redirects ()
2176 /* XXX shouldn't really try to take this lock, since
2177 this is called from the RT audio thread.
2180 Glib::RWLock::ReaderLock lm (redirect_lock);
2182 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2183 (*i)->deactivate ();
2189 Route::set_meter_point (MeterPoint p, void *src)
2191 if (_meter_point != p) {
2193 meter_change (src); /* EMIT SIGNAL */
2194 _session.set_dirty ();
2199 Route::update_total_latency ()
2203 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2204 if ((*i)->active ()) {
2205 _own_latency += (*i)->latency ();
2209 set_port_latency (_own_latency);
2211 /* this (virtual) function is used for pure Routes,
2212 not derived classes like AudioTrack. this means
2213 that the data processed here comes from an input
2214 port, not prerecorded material, and therefore we
2215 have to take into account any input latency.
2218 _own_latency += input_latency ();
2220 return _own_latency;
2224 Route::set_latency_delay (nframes_t longest_session_latency)
2226 _initial_delay = longest_session_latency - _own_latency;
2228 if (_session.transport_stopped()) {
2229 _roll_delay = _initial_delay;
2234 Route::automation_snapshot (nframes_t now)
2236 IO::automation_snapshot (now);
2238 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2239 (*i)->automation_snapshot (now);
2243 Route::ToggleControllable::ToggleControllable (std::string name, Route& s, ToggleType tp)
2244 : Controllable (name), route (s), type(tp)
2250 Route::ToggleControllable::set_value (float val)
2252 bool bval = ((val >= 0.5f) ? true: false);
2256 route.set_mute (bval, this);
2259 route.set_solo (bval, this);
2267 Route::ToggleControllable::get_value (void) const
2273 val = route.muted() ? 1.0f : 0.0f;
2276 val = route.soloed() ? 1.0f : 0.0f;
2286 Route::set_block_size (nframes_t nframes)
2288 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2289 (*i)->set_block_size (nframes);
2294 Route::redirect_active_proxy (Redirect* ignored, void* ignored_src)
2296 _session.update_latency_compensation (false, false);
2300 Route::protect_automation ()
2302 switch (gain_automation_state()) {
2304 set_gain_automation_state (Off);
2306 set_gain_automation_state (Play);
2312 switch (panner().automation_state ()) {
2314 panner().set_automation_state (Off);
2317 panner().set_automation_state (Play);
2323 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2324 boost::shared_ptr<PluginInsert> pi;
2325 if ((pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
2326 pi->protect_automation ();
2332 Route::set_pending_declick (int declick)
2335 /* this call is not allowed to turn off a pending declick unless "force" is true */
2337 _pending_declick = declick;
2339 // cerr << _name << ": after setting to " << declick << " pending declick = " << _pending_declick << endl;
2341 _pending_declick = 0;