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.
25 #include <sigc++/bind.h>
26 #include <pbd/xml++.h>
28 #include <ardour/timestamps.h>
29 #include <ardour/audioengine.h>
30 #include <ardour/route.h>
31 #include <ardour/insert.h>
32 #include <ardour/send.h>
33 #include <ardour/session.h>
34 #include <ardour/utils.h>
35 #include <ardour/configuration.h>
36 #include <ardour/cycle_timer.h>
37 #include <ardour/route_group.h>
38 #include <ardour/port.h>
39 #include <ardour/ladspa_plugin.h>
40 #include <ardour/panner.h>
41 #include <ardour/dB.h>
42 #include <ardour/mix.h>
47 using namespace ARDOUR;
51 uint32_t Route::order_key_cnt = 0;
54 Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg, Buffer::Type default_type)
55 : IO (sess, name, input_min, input_max, output_min, output_max, default_type),
57 _solo_control (*this, ToggleControllable::SoloControl),
58 _mute_control (*this, ToggleControllable::MuteControl)
63 Route::Route (Session& sess, const XMLNode& node)
65 _solo_control (*this, ToggleControllable::SoloControl),
66 _mute_control (*this, ToggleControllable::MuteControl)
75 redirect_max_outs = 0;
79 _phase_invert = false;
80 order_keys[N_("signal")] = order_key_cnt++;
83 _meter_point = MeterPostFader;
87 _have_internal_generator = false;
89 _pending_declick = true;
90 _remote_control_id = 0;
95 _mute_affects_pre_fader = Config->get_mute_affects_pre_fader();
96 _mute_affects_post_fader = Config->get_mute_affects_post_fader();
97 _mute_affects_control_outs = Config->get_mute_affects_control_outs();
98 _mute_affects_main_outs = Config->get_mute_affects_main_outs();
101 desired_solo_gain = 1.0;
103 desired_mute_gain = 1.0;
107 input_changed.connect (mem_fun (this, &Route::input_change_handler));
108 output_changed.connect (mem_fun (this, &Route::output_change_handler));
113 GoingAway (); /* EMIT SIGNAL */
114 clear_redirects (this);
117 delete _control_outs;
122 Route::set_remote_control_id (uint32_t id)
124 if (id != _remote_control_id) {
125 _remote_control_id = id;
126 RemoteControlIDChanged ();
131 Route::remote_control_id() const
133 return _remote_control_id;
137 Route::order_key (string name) const
139 OrderKeys::const_iterator i;
141 if ((i = order_keys.find (name)) == order_keys.end()) {
149 Route::set_order_key (string name, long n)
151 order_keys[name] = n;
152 _session.set_dirty ();
156 Route::inc_gain (gain_t fraction, void *src)
158 IO::inc_gain (fraction, src);
162 Route::set_gain (gain_t val, void *src)
164 if (src != 0 && _mix_group && src != _mix_group && _mix_group->is_active()) {
166 if (_mix_group->is_relative()) {
169 gain_t usable_gain = gain();
170 if (usable_gain < 0.000001f) {
171 usable_gain=0.000001f;
175 if (delta < 0.000001f) {
179 delta -= usable_gain;
181 if (delta == 0.0f) return;
183 gain_t factor = delta / usable_gain;
186 factor = _mix_group->get_max_factor(factor);
187 if (factor == 0.0f) {
192 factor = _mix_group->get_min_factor(factor);
193 if (factor == 0.0f) {
199 _mix_group->apply (&Route::inc_gain, factor, _mix_group);
203 _mix_group->apply (&Route::set_gain, val, _mix_group);
213 IO::set_gain (val, src);
217 Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
218 jack_nframes_t start_frame, jack_nframes_t end_frame,
219 jack_nframes_t nframes, jack_nframes_t offset, bool with_redirects, int declick,
223 RedirectList::iterator i;
224 bool post_fader_work = false;
225 bool mute_declick_applied = false;
227 vector<Sample*>::iterator bufiter;
231 bool no_monitor = (Config->get_use_hardware_monitoring() || !Config->get_use_sw_monitoring ());
232 gain_t* gab = _session.gain_automation_buffer();
234 declick = _pending_declick;
237 Glib::Mutex::Lock cm (control_outs_lock, Glib::TRY_LOCK);
247 Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK);
250 dmg = desired_mute_gain;
251 dsg = desired_solo_gain;
260 /* ----------------------------------------------------------------------------------------------------
261 GLOBAL DECLICK (for transport changes etc.)
262 -------------------------------------------------------------------------------------------------- */
265 apply_declick (bufs, nbufs, nframes, 0.0, 1.0, _phase_invert);
266 _pending_declick = 0;
267 } else if (declick < 0) {
268 apply_declick (bufs, nbufs, nframes, 1.0, 0.0, _phase_invert);
269 _pending_declick = 0;
272 /* no global declick */
274 if (solo_gain != dsg) {
275 apply_declick (bufs, nbufs, nframes, solo_gain, dsg, _phase_invert);
281 /* ----------------------------------------------------------------------------------------------------
282 INPUT METERING & MONITORING
283 -------------------------------------------------------------------------------------------------- */
285 if (meter && (_meter_point == MeterInput)) {
286 for (n = 0; n < nbufs; ++n) {
287 _peak_power[n] = Session::compute_peak (bufs[n], nframes, _peak_power[n]);
291 if (!_soloed && _mute_affects_pre_fader && (mute_gain != dmg)) {
292 apply_declick (bufs, nbufs, nframes, mute_gain, dmg, _phase_invert);
294 mute_declick_applied = true;
297 if ((_meter_point == MeterInput) && co) {
299 solo_audible = dsg > 0;
300 mute_audible = dmg > 0;// || !_mute_affects_pre_fader;
302 if ( // muted by solo of another track
306 // muted by mute of this track
310 // rec-enabled but not s/w monitoring
312 // TODO: this is probably wrong
314 (no_monitor && record_enabled() && (!_session.get_auto_input() || _session.actively_recording()))
318 co->silence (nframes, offset);
322 co->deliver_output (bufs, nbufs, nframes, offset);
327 /* ----------------------------------------------------------------------------------------------------
329 -------------------------------------------------------------------------------------------------- */
331 if (with_redirects) {
332 Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK);
334 if (mute_gain > 0 || !_mute_affects_pre_fader) {
335 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
336 switch ((*i)->placement()) {
338 (*i)->run (bufs, nbufs, nframes, offset);
341 post_fader_work = true;
346 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
347 switch ((*i)->placement()) {
349 (*i)->silence (nframes, offset);
352 post_fader_work = true;
361 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_post_fader) {
362 apply_declick (bufs, nbufs, nframes, mute_gain, dmg, _phase_invert);
364 mute_declick_applied = true;
367 /* ----------------------------------------------------------------------------------------------------
368 PRE-FADER METERING & MONITORING
369 -------------------------------------------------------------------------------------------------- */
371 if (meter && (_meter_point == MeterPreFader)) {
372 for (n = 0; n < nbufs; ++n) {
373 _peak_power[n] = Session::compute_peak (bufs[n], nframes, _peak_power[n]);
378 if ((_meter_point == MeterPreFader) && co) {
380 solo_audible = dsg > 0;
381 mute_audible = dmg > 0 || !_mute_affects_pre_fader;
383 if ( // muted by solo of another track
387 // muted by mute of this track
391 // rec-enabled but not s/w monitoring
393 (no_monitor && record_enabled() && (!_session.get_auto_input() || _session.actively_recording()))
397 co->silence (nframes, offset);
401 co->deliver_output (bufs, nbufs, nframes, offset);
406 /* ----------------------------------------------------------------------------------------------------
408 -------------------------------------------------------------------------------------------------- */
410 /* if not recording or recording and requiring any monitor signal, then apply gain */
412 if ( // not recording
414 !(record_enabled() && _session.actively_recording()) ||
418 // h/w monitoring not in use
420 (!Config->get_use_hardware_monitoring() &&
422 // AND software monitoring required
424 Config->get_use_sw_monitoring())) {
426 if (apply_gain_automation) {
429 for (n = 0; n < nbufs; ++n) {
430 Sample *sp = bufs[n];
432 for (jack_nframes_t nx = 0; nx < nframes; ++nx) {
437 for (n = 0; n < nbufs; ++n) {
438 Sample *sp = bufs[n];
440 for (jack_nframes_t nx = 0; nx < nframes; ++nx) {
446 if (apply_gain_automation && _session.transport_rolling() && nframes > 0) {
447 _effective_gain = gab[nframes-1];
452 /* manual (scalar) gain */
456 apply_declick (bufs, nbufs, nframes, _gain, dg, _phase_invert);
459 } else if (_gain != 0 && (_phase_invert || _gain != 1.0)) {
461 /* no need to interpolate current gain value,
462 but its non-unity, so apply it. if the gain
463 is zero, do nothing because we'll ship silence
475 for (n = 0; n < nbufs; ++n) {
476 Sample *sp = bufs[n];
477 apply_gain_to_buffer(sp,nframes,this_gain);
480 } else if (_gain == 0) {
481 for (n = 0; n < nbufs; ++n) {
482 memset (bufs[n], 0, sizeof (Sample) * nframes);
489 /* actively recording, no monitoring required; leave buffers as-is to save CPU cycles */
493 /* ----------------------------------------------------------------------------------------------------
495 -------------------------------------------------------------------------------------------------- */
497 /* note that post_fader_work cannot be true unless with_redirects was also true, so don't test both */
499 if (post_fader_work) {
501 Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK);
503 if (mute_gain > 0 || !_mute_affects_post_fader) {
504 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
505 switch ((*i)->placement()) {
509 (*i)->run (bufs, nbufs, nframes, offset);
514 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
515 switch ((*i)->placement()) {
519 (*i)->silence (nframes, offset);
527 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_control_outs) {
528 apply_declick (bufs, nbufs, nframes, mute_gain, dmg, _phase_invert);
530 mute_declick_applied = true;
533 /* ----------------------------------------------------------------------------------------------------
535 -------------------------------------------------------------------------------------------------- */
537 if ((_meter_point == MeterPostFader) && co) {
539 solo_audible = solo_gain > 0;
540 mute_audible = dmg > 0 || !_mute_affects_control_outs;
542 if ( // silent anyway
544 (_gain == 0 && !apply_gain_automation) ||
546 // muted by solo of another track
550 // muted by mute of this track
554 // recording but not s/w monitoring
556 (no_monitor && record_enabled() && (!_session.get_auto_input() || _session.actively_recording()))
560 co->silence (nframes, offset);
564 co->deliver_output_no_pan (bufs, nbufs, nframes, offset);
568 /* ----------------------------------------------------------------------
570 ----------------------------------------------------------------------*/
572 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_main_outs) {
573 apply_declick (bufs, nbufs, nframes, mute_gain, dmg, _phase_invert);
575 mute_declick_applied = true;
578 /* ----------------------------------------------------------------------------------------------------
580 -------------------------------------------------------------------------------------------------- */
582 solo_audible = dsg > 0;
583 mute_audible = dmg > 0 || !_mute_affects_main_outs;
585 if (n_outputs() == 0) {
589 } else if (no_monitor && record_enabled() && (!_session.get_auto_input() || _session.actively_recording())) {
591 IO::silence (nframes, offset);
595 if ( // silent anyway
597 (_gain == 0 && !apply_gain_automation) ||
599 // muted by solo of another track, but not using control outs for solo
601 (!solo_audible && (_session.solo_model() != Session::SoloBus)) ||
603 // muted by mute of this track
609 /* don't use Route::silence() here, because that causes
610 all outputs (sends, port inserts, etc. to be silent).
613 if (_meter_point == MeterPostFader) {
614 reset_peak_meters ();
617 IO::silence (nframes, offset);
621 if (_session.transport_speed() > 1.5f || _session.transport_speed() < -1.5f) {
622 pan (bufs, nbufs, nframes, offset, speed_quietning);
624 // cerr << _name << " panner state = " << _panner->automation_state() << endl;
625 if (!_panner->empty() &&
626 (_panner->automation_state() & Play ||
627 ((_panner->automation_state() & Touch) && !_panner->touching()))) {
628 pan_automated (bufs, nbufs, start_frame, end_frame, nframes, offset);
630 pan (bufs, nbufs, nframes, offset, 1.0);
637 /* ----------------------------------------------------------------------------------------------------
639 -------------------------------------------------------------------------------------------------- */
641 if (meter && (_meter_point == MeterPostFader)) {
642 // cerr << "meter post" << endl;
644 if ((_gain == 0 && !apply_gain_automation) || dmg == 0) {
645 uint32_t no = n_outputs();
646 for (n = 0; n < no; ++n) {
650 uint32_t no = n_outputs();
651 for (n = 0; n < no; ++n) {
652 _peak_power[n] = Session::compute_peak (output(n)->get_buffer (nframes) + offset, nframes, _peak_power[n]);
659 Route::n_process_buffers ()
661 return max (n_inputs(), redirect_max_outs);
666 Route::passthru (jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset, int declick, bool meter_first)
668 vector<Sample*>& bufs = _session.get_passthru_buffers();
669 uint32_t limit = n_process_buffers ();
673 collect_input (bufs, limit, nframes, offset);
675 #define meter_stream meter_first
678 for (uint32_t n = 0; n < limit; ++n) {
679 _peak_power[n] = Session::compute_peak (bufs[n], nframes, _peak_power[n]);
681 meter_stream = false;
686 process_output_buffers (bufs, limit, start_frame, end_frame, nframes, offset, true, declick, meter_stream);
692 Route::set_phase_invert (bool yn, void *src)
694 if (_phase_invert != yn) {
697 // phase_invert_changed (src); /* EMIT SIGNAL */
701 Route::set_solo (bool yn, void *src)
707 if (_mix_group && src != _mix_group && _mix_group->is_active()) {
708 _mix_group->apply (&Route::set_solo, yn, _mix_group);
714 solo_changed (src); /* EMIT SIGNAL */
715 _solo_control.Changed (); /* EMIT SIGNAL */
720 Route::set_solo_mute (bool yn)
722 Glib::Mutex::Lock lm (declick_lock);
724 /* Called by Session in response to another Route being soloed.
727 desired_solo_gain = (yn?0.0:1.0);
731 Route::set_solo_safe (bool yn, void *src)
733 if (_solo_safe != yn) {
735 solo_safe_changed (src); /* EMIT SIGNAL */
740 Route::set_mute (bool yn, void *src)
743 if (_mix_group && src != _mix_group && _mix_group->is_active()) {
744 _mix_group->apply (&Route::set_mute, yn, _mix_group);
750 mute_changed (src); /* EMIT SIGNAL */
752 _mute_control.Changed (); /* EMIT SIGNAL */
754 Glib::Mutex::Lock lm (declick_lock);
755 desired_mute_gain = (yn?0.0f:1.0f);
760 Route::add_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
762 uint32_t old_rmo = redirect_max_outs;
764 if (!_session.engine().connected()) {
769 Glib::RWLock::WriterLock lm (redirect_lock);
771 boost::shared_ptr<PluginInsert> pi;
772 boost::shared_ptr<PortInsert> porti;
774 uint32_t potential_max_streams = 0;
776 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(redirect)) != 0) {
779 if (pi->input_streams() == 0) {
780 /* instrument plugin */
781 _have_internal_generator = true;
784 potential_max_streams = max(pi->input_streams(), pi->output_streams());
786 } else if ((porti = boost::dynamic_pointer_cast<PortInsert>(redirect)) != 0) {
788 /* force new port inserts to start out with an i/o configuration
789 that matches this route's i/o configuration.
791 the "inputs" for the port are supposed to match the output
794 the "outputs" of the route should match the inputs of this
795 route. XXX shouldn't they match the number of active signal
796 streams at the point of insertion?
800 porti->ensure_io (n_outputs (), n_inputs(), false, this);
803 // Ensure peak vector sizes before the plugin is activated
804 while (_peak_power.size() < potential_max_streams) {
805 _peak_power.push_back(0);
807 while (_visible_peak_power.size() < potential_max_streams) {
808 _visible_peak_power.push_back(0);
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 == 0) {
828 redirects_changed (src); /* EMIT SIGNAL */
833 Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_streams)
835 uint32_t 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 uint32_t potential_max_streams = 0;
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 uint32_t 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 while (_peak_power.size() < potential_max_streams) {
863 _peak_power.push_back(0);
865 while (_visible_peak_power.size() < potential_max_streams) {
866 _visible_peak_power.push_back(0);
869 _redirects.push_back (*i);
871 if (_reset_plugin_counts (err_streams)) {
873 _redirects.erase (existing_end, _redirects.end());
874 _reset_plugin_counts (0); // it worked before we tried to add it ...
879 (*i)->active_changed.connect (mem_fun (*this, &Route::redirect_active_proxy));
883 if (redirect_max_outs != old_rmo || old_rmo == 0) {
887 redirects_changed (src); /* EMIT SIGNAL */
892 Route::clear_redirects (void *src)
894 uint32_t old_rmo = redirect_max_outs;
896 if (!_session.engine().connected()) {
901 Glib::RWLock::WriterLock lm (redirect_lock);
905 if (redirect_max_outs != old_rmo) {
909 redirect_max_outs = 0;
910 _have_internal_generator = false;
911 redirects_changed (src); /* EMIT SIGNAL */
915 Route::remove_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
917 uint32_t old_rmo = redirect_max_outs;
919 if (!_session.engine().connected()) {
923 redirect_max_outs = 0;
926 Glib::RWLock::WriterLock lm (redirect_lock);
927 RedirectList::iterator i;
928 bool removed = false;
930 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
931 if (*i == redirect) {
933 RedirectList::iterator tmp;
935 /* move along, see failure case for reset_plugin_counts()
936 where we may need to reinsert the redirect.
942 /* stop redirects that send signals to JACK ports
943 from causing noise as a result of no longer being
947 boost::shared_ptr<Send> send;
948 boost::shared_ptr<PortInsert> port_insert;
950 if ((send = boost::dynamic_pointer_cast<Send> (*i)) != 0) {
951 send->disconnect_inputs (this);
952 send->disconnect_outputs (this);
953 } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (*i)) != 0) {
954 port_insert->disconnect_inputs (this);
955 port_insert->disconnect_outputs (this);
958 _redirects.erase (i);
971 if (_reset_plugin_counts (err_streams)) {
972 /* get back to where we where */
973 _redirects.insert (i, redirect);
974 /* we know this will work, because it worked before :) */
975 _reset_plugin_counts (0);
981 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
982 boost::shared_ptr<PluginInsert> pi;
984 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
985 if (pi->is_generator()) {
991 _have_internal_generator = foo;
994 if (old_rmo != redirect_max_outs) {
998 redirects_changed (src); /* EMIT SIGNAL */
1003 Route::reset_plugin_counts (uint32_t* lpc)
1005 Glib::RWLock::WriterLock lm (redirect_lock);
1006 return _reset_plugin_counts (lpc);
1011 Route::_reset_plugin_counts (uint32_t* err_streams)
1013 RedirectList::iterator r;
1016 map<Placement,list<InsertCount> > insert_map;
1017 jack_nframes_t initial_streams;
1019 redirect_max_outs = 0;
1023 /* divide inserts up by placement so we get the signal flow
1024 properly modelled. we need to do this because the _redirects
1025 list is not sorted by placement, and because other reasons may
1026 exist now or in the future for this separate treatment.
1029 for (r = _redirects.begin(); r != _redirects.end(); ++r) {
1031 boost::shared_ptr<Insert> insert;
1033 /* do this here in case we bomb out before we get to the end of
1037 redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs);
1039 if ((insert = boost::dynamic_pointer_cast<Insert>(*r)) != 0) {
1041 insert_map[insert->placement()].push_back (InsertCount (insert));
1043 /* reset plugin counts back to one for now so
1044 that we have a predictable, controlled
1045 state to try to configure.
1048 boost::shared_ptr<PluginInsert> pi;
1050 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(insert)) != 0) {
1054 } else if (boost::dynamic_pointer_cast<Send> (*r) != 0) {
1067 /* Now process each placement in order, checking to see if we
1068 can really do what has been requested.
1073 if (check_some_plugin_counts (insert_map[PreFader], n_inputs (), err_streams)) {
1077 /* figure out the streams that will feed into PreFader */
1079 if (!insert_map[PreFader].empty()) {
1080 InsertCount& ic (insert_map[PreFader].back());
1081 initial_streams = ic.insert->compute_output_streams (ic.cnt);
1083 initial_streams = n_inputs ();
1088 if (check_some_plugin_counts (insert_map[PostFader], initial_streams, err_streams)) {
1092 /* OK, everything can be set up correctly, so lets do it */
1094 apply_some_plugin_counts (insert_map[PreFader]);
1095 apply_some_plugin_counts (insert_map[PostFader]);
1097 /* recompute max outs of any redirect */
1101 redirect_max_outs = 0;
1102 RedirectList::iterator prev = _redirects.end();
1104 for (r = _redirects.begin(); r != _redirects.end(); prev = r, ++r) {
1105 boost::shared_ptr<Send> s;
1107 if ((s = boost::dynamic_pointer_cast<Send> (*r)) != 0) {
1108 if (r == _redirects.begin()) {
1109 s->expect_inputs (n_inputs());
1111 s->expect_inputs ((*prev)->output_streams());
1115 redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs);
1124 Route::apply_some_plugin_counts (list<InsertCount>& iclist)
1126 list<InsertCount>::iterator i;
1128 for (i = iclist.begin(); i != iclist.end(); ++i) {
1130 if ((*i).insert->configure_io ((*i).cnt, (*i).in, (*i).out)) {
1133 /* make sure that however many we have, they are all active */
1134 (*i).insert->activate ();
1141 Route::check_some_plugin_counts (list<InsertCount>& iclist, int32_t required_inputs, uint32_t* err_streams)
1143 list<InsertCount>::iterator i;
1145 for (i = iclist.begin(); i != iclist.end(); ++i) {
1147 if (((*i).cnt = (*i).insert->can_support_input_configuration (required_inputs)) < 0) {
1149 *err_streams = required_inputs;
1154 (*i).in = required_inputs;
1155 (*i).out = (*i).insert->compute_output_streams ((*i).cnt);
1157 required_inputs = (*i).out;
1164 Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_streams)
1166 uint32_t old_rmo = redirect_max_outs;
1172 RedirectList to_be_deleted;
1175 Glib::RWLock::WriterLock lm (redirect_lock);
1176 RedirectList::iterator tmp;
1177 RedirectList the_copy;
1179 the_copy = _redirects;
1181 /* remove all relevant redirects */
1183 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ) {
1187 if ((*i)->placement() == placement) {
1188 to_be_deleted.push_back (*i);
1189 _redirects.erase (i);
1195 /* now copy the relevant ones from "other" */
1197 for (RedirectList::const_iterator i = other._redirects.begin(); i != other._redirects.end(); ++i) {
1198 if ((*i)->placement() == placement) {
1199 _redirects.push_back (Redirect::clone (*i));
1203 /* reset plugin stream handling */
1205 if (_reset_plugin_counts (err_streams)) {
1207 /* FAILED COPY ATTEMPT: we have to restore order */
1209 /* delete all cloned redirects */
1211 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ) {
1216 if ((*i)->placement() == placement) {
1217 _redirects.erase (i);
1223 /* restore the natural order */
1225 _redirects = the_copy;
1226 redirect_max_outs = old_rmo;
1228 /* we failed, even though things are OK again */
1234 /* SUCCESSFUL COPY ATTEMPT: delete the redirects we removed pre-copy */
1235 to_be_deleted.clear ();
1239 if (redirect_max_outs != old_rmo || old_rmo == 0) {
1243 redirects_changed (this); /* EMIT SIGNAL */
1248 Route::all_redirects_flip ()
1250 Glib::RWLock::ReaderLock lm (redirect_lock);
1252 if (_redirects.empty()) {
1256 bool first_is_on = _redirects.front()->active();
1258 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1259 (*i)->set_active (!first_is_on, this);
1264 Route::all_redirects_active (bool state)
1266 Glib::RWLock::ReaderLock lm (redirect_lock);
1268 if (_redirects.empty()) {
1272 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1273 (*i)->set_active (state, this);
1277 struct RedirectSorter {
1278 bool operator() (boost::shared_ptr<const Redirect> a, boost::shared_ptr<const Redirect> b) {
1279 return a->sort_key() < b->sort_key();
1284 Route::sort_redirects (uint32_t* err_streams)
1287 RedirectSorter comparator;
1288 Glib::RWLock::WriterLock lm (redirect_lock);
1289 uint32_t old_rmo = redirect_max_outs;
1291 /* the sweet power of C++ ... */
1293 RedirectList as_it_was_before = _redirects;
1295 _redirects.sort (comparator);
1297 if (_reset_plugin_counts (err_streams)) {
1298 _redirects = as_it_was_before;
1299 redirect_max_outs = old_rmo;
1305 redirects_changed (this); /* EMIT SIGNAL */
1317 Route::get_template()
1319 return state(false);
1323 Route::state(bool full_state)
1325 XMLNode *node = new XMLNode("Route");
1327 RedirectList:: iterator i;
1331 snprintf (buf, sizeof (buf), "0x%x", _flags);
1332 node->add_property("flags", buf);
1335 // FIXME: assumes there's only audio and MIDI types
1336 node->add_property("default-type", Buffer::type_to_string(_default_type));
1338 node->add_property("active", _active?"yes":"no");
1339 node->add_property("muted", _muted?"yes":"no");
1340 node->add_property("soloed", _soloed?"yes":"no");
1341 node->add_property("phase-invert", _phase_invert?"yes":"no");
1342 node->add_property("mute-affects-pre-fader", _mute_affects_pre_fader?"yes":"no");
1343 node->add_property("mute-affects-post-fader", _mute_affects_post_fader?"yes":"no");
1344 node->add_property("mute-affects-control-outs", _mute_affects_control_outs?"yes":"no");
1345 node->add_property("mute-affects-main-outs", _mute_affects_main_outs?"yes":"no");
1348 node->add_property("edit-group", _edit_group->name());
1351 node->add_property("mix-group", _mix_group->name());
1354 string order_string;
1355 OrderKeys::iterator x = order_keys.begin();
1357 while (x != order_keys.end()) {
1358 order_string += (*x).first;
1359 order_string += '=';
1360 snprintf (buf, sizeof(buf), "%ld", (*x).second);
1361 order_string += buf;
1365 if (x == order_keys.end()) {
1369 order_string += ':';
1371 node->add_property ("order-keys", order_string);
1373 node->add_child_nocopy (IO::state (full_state));
1375 if (_control_outs) {
1376 XMLNode* cnode = new XMLNode (X_("ControlOuts"));
1377 cnode->add_child_nocopy (_control_outs->state (full_state));
1378 node->add_child_nocopy (*cnode);
1381 if (_comment.length()) {
1382 XMLNode *cmt = node->add_child ("Comment");
1383 cmt->add_content (_comment);
1389 path = _session.snap_name();
1391 path += legalize_for_path (_name);
1392 path += ".automation";
1394 /* XXX we didn't ask for a state save, we asked for the current state.
1398 if (save_automation (path)) {
1399 error << _("Could not get state of route. Problem with save_automation") << endmsg;
1402 aevents = node->add_child ("Automation");
1403 aevents->add_property ("path", path);
1406 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
1407 node->add_child_nocopy((*i)->state (full_state));
1411 node->add_child_copy (*_extra_xml);
1418 Route::set_deferred_state ()
1421 XMLNodeConstIterator niter;
1423 if (!deferred_state) {
1427 nlist = deferred_state->children();
1429 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1430 add_redirect_from_xml (**niter);
1433 delete deferred_state;
1438 Route::add_redirect_from_xml (const XMLNode& node)
1440 const XMLProperty *prop;
1442 if (node.name() == "Send") {
1446 boost::shared_ptr<Send> send (new Send (_session, node));
1447 add_redirect (send, this);
1450 catch (failed_constructor &err) {
1451 error << _("Send construction failed") << endmsg;
1455 } else if (node.name() == "Insert") {
1458 if ((prop = node.property ("type")) != 0) {
1460 boost::shared_ptr<Insert> insert;
1462 if (prop->value() == "ladspa" || prop->value() == "Ladspa" || prop->value() == "vst") {
1464 insert.reset (new PluginInsert(_session, node));
1466 } else if (prop->value() == "port") {
1469 insert.reset (new PortInsert (_session, node));
1473 error << string_compose(_("unknown Insert type \"%1\"; ignored"), prop->value()) << endmsg;
1476 add_redirect (insert, this);
1479 error << _("Insert XML node has no type property") << endmsg;
1483 catch (failed_constructor &err) {
1484 warning << _("insert could not be created. Ignored.") << endmsg;
1491 Route::set_state (const XMLNode& node)
1494 XMLNodeConstIterator niter;
1496 XMLPropertyList plist;
1497 const XMLProperty *prop;
1499 if (node.name() != "Route"){
1500 error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
1504 if ((prop = node.property ("flags")) != 0) {
1506 sscanf (prop->value().c_str(), "0x%x", &x);
1512 if ((prop = node.property ("default-type")) != 0) {
1513 _default_type = Buffer::type_from_string(prop->value());
1514 assert(_default_type != Buffer::NIL);
1517 if ((prop = node.property ("phase-invert")) != 0) {
1518 set_phase_invert(prop->value()=="yes"?true:false, this);
1521 if ((prop = node.property ("active")) != 0) {
1522 set_active (prop->value() == "yes");
1525 if ((prop = node.property ("muted")) != 0) {
1526 bool yn = prop->value()=="yes"?true:false;
1528 /* force reset of mute status */
1532 mute_gain = desired_mute_gain;
1535 if ((prop = node.property ("soloed")) != 0) {
1536 bool yn = prop->value()=="yes"?true:false;
1538 /* force reset of solo status */
1541 set_solo (yn, this);
1542 solo_gain = desired_solo_gain;
1545 if ((prop = node.property ("mute-affects-pre-fader")) != 0) {
1546 _mute_affects_pre_fader = (prop->value()=="yes")?true:false;
1549 if ((prop = node.property ("mute-affects-post-fader")) != 0) {
1550 _mute_affects_post_fader = (prop->value()=="yes")?true:false;
1553 if ((prop = node.property ("mute-affects-control-outs")) != 0) {
1554 _mute_affects_control_outs = (prop->value()=="yes")?true:false;
1557 if ((prop = node.property ("mute-affects-main-outs")) != 0) {
1558 _mute_affects_main_outs = (prop->value()=="yes")?true:false;
1561 if ((prop = node.property ("edit-group")) != 0) {
1562 RouteGroup* edit_group = _session.edit_group_by_name(prop->value());
1563 if(edit_group == 0) {
1564 error << string_compose(_("Route %1: unknown edit group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
1566 set_edit_group(edit_group, this);
1570 if ((prop = node.property ("order-keys")) != 0) {
1574 string::size_type colon, equal;
1575 string remaining = prop->value();
1577 while (remaining.length()) {
1579 if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
1580 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1583 if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) {
1584 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1587 set_order_key (remaining.substr (0, equal), n);
1591 colon = remaining.find_first_of (':');
1593 if (colon != string::npos) {
1594 remaining = remaining.substr (colon+1);
1601 nlist = node.children();
1603 if (deferred_state) {
1604 delete deferred_state;
1607 deferred_state = new XMLNode("deferred state");
1609 /* set parent class properties before anything else */
1611 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1615 if (child->name() == IO::state_node_name) {
1617 IO::set_state (*child);
1622 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1626 if (child->name() == "Send") {
1629 if (!IO::ports_legal) {
1631 deferred_state->add_child_copy (*child);
1634 add_redirect_from_xml (*child);
1637 } else if (child->name() == "Insert") {
1639 if (!IO::ports_legal) {
1641 deferred_state->add_child_copy (*child);
1645 add_redirect_from_xml (*child);
1648 } else if (child->name() == "Automation") {
1650 XMLPropertyList plist;
1651 XMLPropertyConstIterator piter;
1654 plist = child->properties();
1655 for (piter = plist.begin(); piter != plist.end(); ++piter) {
1657 if (prop->name() == "path") {
1658 load_automation (prop->value());
1662 } else if (child->name() == "ControlOuts") {
1664 string coutname = _name;
1665 coutname += _("[control]");
1667 _control_outs = new IO (_session, coutname);
1668 _control_outs->set_state (**(child->children().begin()));
1670 } else if (child->name() == "Comment") {
1672 /* XXX this is a terrible API design in libxml++ */
1674 XMLNode *cmt = *(child->children().begin());
1675 _comment = cmt->content();
1677 } else if (child->name() == "extra") {
1678 _extra_xml = new XMLNode (*child);
1682 if ((prop = node.property ("mix-group")) != 0) {
1683 RouteGroup* mix_group = _session.mix_group_by_name(prop->value());
1684 if (mix_group == 0) {
1685 error << string_compose(_("Route %1: unknown mix group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
1687 set_mix_group(mix_group, this);
1695 Route::curve_reallocate ()
1697 // _gain_automation_curve.finish_resize ();
1698 // _pan_automation_curve.finish_resize ();
1702 Route::silence (jack_nframes_t nframes, jack_nframes_t offset)
1706 // reset_peak_meters ();
1708 IO::silence (nframes, offset);
1710 if (_control_outs) {
1711 _control_outs->silence (nframes, offset);
1715 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
1718 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1719 boost::shared_ptr<PluginInsert> pi;
1720 if (!_active && (pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
1721 // skip plugins, they don't need anything when we're not active
1725 (*i)->silence (nframes, offset);
1728 if (nframes == _session.get_block_size() && offset == 0) {
1738 Route::set_control_outs (const vector<string>& ports)
1740 Glib::Mutex::Lock lm (control_outs_lock);
1741 vector<string>::const_iterator i;
1743 if (_control_outs) {
1744 delete _control_outs;
1748 if (ports.empty()) {
1752 string coutname = _name;
1753 coutname += _("[control]");
1755 _control_outs = new IO (_session, coutname);
1757 /* our control outs need as many outputs as we
1758 have outputs. we track the changes in ::output_change_handler().
1761 _control_outs->ensure_io (0, n_outputs(), true, this);
1767 Route::set_edit_group (RouteGroup *eg, void *src)
1770 if (eg == _edit_group) {
1775 _edit_group->remove (this);
1778 if ((_edit_group = eg) != 0) {
1779 _edit_group->add (this);
1782 _session.set_dirty ();
1783 edit_group_changed (src); /* EMIT SIGNAL */
1787 Route::drop_edit_group (void *src)
1790 _session.set_dirty ();
1791 edit_group_changed (src); /* EMIT SIGNAL */
1795 Route::set_mix_group (RouteGroup *mg, void *src)
1798 if (mg == _mix_group) {
1803 _mix_group->remove (this);
1806 if ((_mix_group = mg) != 0) {
1807 _mix_group->add (this);
1810 _session.set_dirty ();
1811 mix_group_changed (src); /* EMIT SIGNAL */
1815 Route::drop_mix_group (void *src)
1818 _session.set_dirty ();
1819 mix_group_changed (src); /* EMIT SIGNAL */
1823 Route::set_comment (string cmt, void *src)
1826 comment_changed (src);
1827 _session.set_dirty ();
1831 Route::feeds (boost::shared_ptr<Route> other)
1836 uint32_t no = self.n_outputs();
1837 uint32_t ni = other->n_inputs ();
1839 for (i = 0; i < no; ++i) {
1840 for (j = 0; j < ni; ++j) {
1841 if (self.output(i)->connected_to (other->input(j)->name())) {
1847 /* check Redirects which may also interconnect Routes */
1849 for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); r++) {
1851 no = (*r)->n_outputs();
1853 for (i = 0; i < no; ++i) {
1854 for (j = 0; j < ni; ++j) {
1855 if ((*r)->output(i)->connected_to (other->input (j)->name())) {
1862 /* check for control room outputs which may also interconnect Routes */
1864 if (_control_outs) {
1866 no = _control_outs->n_outputs();
1868 for (i = 0; i < no; ++i) {
1869 for (j = 0; j < ni; ++j) {
1870 if (_control_outs->output(i)->connected_to (other->input (j)->name())) {
1881 Route::set_mute_config (mute_type t, bool onoff, void *src)
1885 _mute_affects_pre_fader = onoff;
1886 pre_fader_changed(src); /* EMIT SIGNAL */
1890 _mute_affects_post_fader = onoff;
1891 post_fader_changed(src); /* EMIT SIGNAL */
1895 _mute_affects_control_outs = onoff;
1896 control_outs_changed(src); /* EMIT SIGNAL */
1900 _mute_affects_main_outs = onoff;
1901 main_outs_changed(src); /* EMIT SIGNAL */
1907 Route::get_mute_config (mute_type t)
1913 onoff = _mute_affects_pre_fader;
1916 onoff = _mute_affects_post_fader;
1919 onoff = _mute_affects_control_outs;
1922 onoff = _mute_affects_main_outs;
1930 Route::set_active (bool yn)
1933 active_changed(); /* EMIT SIGNAL */
1937 Route::handle_transport_stopped (bool abort_ignored, bool did_locate, bool can_flush_redirects)
1939 jack_nframes_t now = _session.transport_frame();
1942 Glib::RWLock::ReaderLock lm (redirect_lock);
1945 automation_snapshot (now);
1948 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1950 if (Config->get_plugins_stop_with_transport() && can_flush_redirects) {
1951 (*i)->deactivate ();
1955 (*i)->transport_stopped (now);
1959 IO::transport_stopped (now);
1961 _roll_delay = _initial_delay;
1965 Route::get_memento() const
1967 void (Route::*pmf)(state_id_t) = &Route::set_state;
1968 return sigc::bind (mem_fun (*(const_cast<Route *>(this)), pmf), _current_state_id);
1972 Route::set_state (state_id_t id)
1978 Route::input_change_handler (IOChange change, void *ignored)
1980 if (change & ConfigurationChanged) {
1981 reset_plugin_counts (0);
1986 Route::output_change_handler (IOChange change, void *ignored)
1988 if (change & ConfigurationChanged) {
1989 if (_control_outs) {
1990 _control_outs->ensure_io (0, n_outputs(), true, this);
1993 reset_plugin_counts (0);
1998 Route::pans_required () const
2000 if (n_outputs() < 2) {
2004 return max (n_inputs (), redirect_max_outs);
2008 Route::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset,
2009 bool session_state_changing, bool can_record, bool rec_monitors_input)
2011 if (n_outputs() == 0) {
2015 if (session_state_changing || !_active) {
2016 silence (nframes, offset);
2020 apply_gain_automation = false;
2023 passthru (start_frame, end_frame, nframes, offset, 0, false);
2025 silence (nframes, offset);
2032 Route::check_initial_delay (jack_nframes_t nframes, jack_nframes_t& offset, jack_nframes_t& transport_frame)
2034 if (_roll_delay > nframes) {
2036 _roll_delay -= nframes;
2037 silence (nframes, offset);
2038 /* transport frame is not legal for caller to use */
2041 } else if (_roll_delay > 0) {
2043 nframes -= _roll_delay;
2045 silence (_roll_delay, offset);
2047 offset += _roll_delay;
2048 transport_frame += _roll_delay;
2057 Route::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset, int declick,
2058 bool can_record, bool rec_monitors_input)
2061 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
2063 // automation snapshot can also be called from the non-rt context
2064 // and it uses the redirect list, so we take the lock out here
2065 automation_snapshot (_session.transport_frame());
2069 if ((n_outputs() == 0 && _redirects.empty()) || n_inputs() == 0 || !_active) {
2070 silence (nframes, offset);
2074 jack_nframes_t unused = 0;
2076 if ((nframes = check_initial_delay (nframes, offset, unused)) == 0) {
2082 apply_gain_automation = false;
2085 Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK);
2087 if (am.locked() && _session.transport_rolling()) {
2089 jack_nframes_t start_frame = end_frame - nframes;
2091 if (gain_automation_playback()) {
2092 apply_gain_automation = _gain_automation_curve.rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes);
2097 passthru (start_frame, end_frame, nframes, offset, declick, false);
2103 Route::silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset,
2104 bool can_record, bool rec_monitors_input)
2106 silence (nframes, offset);
2111 Route::toggle_monitor_input ()
2113 for (vector<Port*>::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
2114 (*i)->request_monitor_input(!(*i)->monitoring_input());
2119 Route::has_external_redirects () const
2121 boost::shared_ptr<const PortInsert> pi;
2123 for (RedirectList::const_iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2124 if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*i)) != 0) {
2126 uint32_t no = pi->n_outputs();
2128 for (uint32_t n = 0; n < no; ++n) {
2130 string port_name = pi->output(n)->name();
2131 string client_name = port_name.substr (0, port_name.find(':'));
2133 /* only say "yes" if the redirect is actually in use */
2135 if (client_name != "ardour" && pi->active()) {
2146 Route::flush_redirects ()
2148 /* XXX shouldn't really try to take this lock, since
2149 this is called from the RT audio thread.
2152 Glib::RWLock::ReaderLock lm (redirect_lock);
2154 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2155 (*i)->deactivate ();
2161 Route::set_meter_point (MeterPoint p, void *src)
2163 if (_meter_point != p) {
2165 meter_change (src); /* EMIT SIGNAL */
2166 _session.set_dirty ();
2171 Route::update_total_latency ()
2175 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2176 if ((*i)->active ()) {
2177 _own_latency += (*i)->latency ();
2181 set_port_latency (_own_latency);
2183 /* this (virtual) function is used for pure Routes,
2184 not derived classes like AudioTrack. this means
2185 that the data processed here comes from an input
2186 port, not prerecorded material, and therefore we
2187 have to take into account any input latency.
2190 _own_latency += input_latency ();
2192 return _own_latency;
2196 Route::set_latency_delay (jack_nframes_t longest_session_latency)
2198 _initial_delay = longest_session_latency - _own_latency;
2200 if (_session.transport_stopped()) {
2201 _roll_delay = _initial_delay;
2206 Route::automation_snapshot (jack_nframes_t now)
2208 IO::automation_snapshot (now);
2210 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2211 (*i)->automation_snapshot (now);
2215 Route::ToggleControllable::ToggleControllable (Route& s, ToggleType tp)
2216 : route (s), type(tp)
2222 Route::ToggleControllable::set_value (float val)
2224 bool bval = ((val >= 0.5f) ? true: false);
2228 route.set_mute (bval, this);
2231 route.set_solo (bval, this);
2239 Route::ToggleControllable::get_value (void) const
2245 val = route.muted() ? 1.0f : 0.0f;
2248 val = route.soloed() ? 1.0f : 0.0f;
2258 Route::set_block_size (jack_nframes_t nframes)
2260 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2261 (*i)->set_block_size (nframes);
2266 Route::redirect_active_proxy (Redirect* ignored, void* ignored_src)
2268 _session.update_latency_compensation (false, false);
2272 Route::protect_automation ()
2274 switch (gain_automation_state()) {
2277 set_gain_automation_state (Off);
2283 switch (panner().automation_state ()) {
2286 panner().set_automation_state (Off);
2292 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2293 boost::shared_ptr<PluginInsert> pi;
2294 if ((pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
2295 pi->protect_automation ();
2301 Route::set_pending_declick (int declick)
2304 /* this call is not allowed to turn off a pending declick unless "force" is true */
2306 _pending_declick = declick;
2308 // cerr << _name << ": after setting to " << declick << " pending declick = " << _pending_declick << endl;
2310 _pending_declick = 0;