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/buffer.h>
30 #include <ardour/audioengine.h>
31 #include <ardour/route.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/ladspa_plugin.h>
41 #include <ardour/panner.h>
42 #include <ardour/dB.h>
43 #include <ardour/mix.h>
48 using namespace ARDOUR;
52 uint32_t Route::order_key_cnt = 0;
55 Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg, DataType default_type)
56 : IO (sess, name, input_min, input_max, output_min, output_max, default_type),
58 _solo_control (*this, ToggleControllable::SoloControl),
59 _mute_control (*this, ToggleControllable::MuteControl)
64 Route::Route (Session& sess, const XMLNode& node)
66 _solo_control (*this, ToggleControllable::SoloControl),
67 _mute_control (*this, ToggleControllable::MuteControl)
76 redirect_max_outs = 0;
80 _phase_invert = false;
81 order_keys[N_("signal")] = order_key_cnt++;
84 _meter_point = MeterPostFader;
88 _have_internal_generator = false;
90 _pending_declick = true;
91 _remote_control_id = 0;
96 _mute_affects_pre_fader = Config->get_mute_affects_pre_fader();
97 _mute_affects_post_fader = Config->get_mute_affects_post_fader();
98 _mute_affects_control_outs = Config->get_mute_affects_control_outs();
99 _mute_affects_main_outs = Config->get_mute_affects_main_outs();
102 desired_solo_gain = 1.0;
104 desired_mute_gain = 1.0;
108 input_changed.connect (mem_fun (this, &Route::input_change_handler));
109 output_changed.connect (mem_fun (this, &Route::output_change_handler));
114 cerr << "deleting route " << _name << endl;
116 clear_redirects (this);
119 delete _control_outs;
124 Route::set_remote_control_id (uint32_t id)
126 if (id != _remote_control_id) {
127 _remote_control_id = id;
128 RemoteControlIDChanged ();
133 Route::remote_control_id() const
135 return _remote_control_id;
139 Route::order_key (string name) const
141 OrderKeys::const_iterator i;
143 if ((i = order_keys.find (name)) == order_keys.end()) {
151 Route::set_order_key (string name, long n)
153 order_keys[name] = n;
154 _session.set_dirty ();
158 Route::inc_gain (gain_t fraction, void *src)
160 IO::inc_gain (fraction, src);
164 Route::set_gain (gain_t val, void *src)
166 if (src != 0 && _mix_group && src != _mix_group && _mix_group->is_active()) {
168 if (_mix_group->is_relative()) {
171 gain_t usable_gain = gain();
172 if (usable_gain < 0.000001f) {
173 usable_gain=0.000001f;
177 if (delta < 0.000001f) {
181 delta -= usable_gain;
183 if (delta == 0.0f) return;
185 gain_t factor = delta / usable_gain;
188 factor = _mix_group->get_max_factor(factor);
189 if (factor == 0.0f) {
194 factor = _mix_group->get_min_factor(factor);
195 if (factor == 0.0f) {
201 _mix_group->apply (&Route::inc_gain, factor, _mix_group);
205 _mix_group->apply (&Route::set_gain, val, _mix_group);
215 IO::set_gain (val, src);
219 Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
220 jack_nframes_t start_frame, jack_nframes_t end_frame,
221 jack_nframes_t nframes, jack_nframes_t offset, bool with_redirects, int declick,
225 RedirectList::iterator i;
226 bool post_fader_work = false;
227 bool mute_declick_applied = false;
229 vector<Sample*>::iterator bufiter;
233 bool no_monitor = (Config->get_use_hardware_monitoring() || !Config->get_use_sw_monitoring ());
234 gain_t* gab = _session.gain_automation_buffer();
236 declick = _pending_declick;
239 Glib::Mutex::Lock cm (control_outs_lock, Glib::TRY_LOCK);
249 Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK);
252 dmg = desired_mute_gain;
253 dsg = desired_solo_gain;
262 /* ----------------------------------------------------------------------------------------------------
263 GLOBAL DECLICK (for transport changes etc.)
264 -------------------------------------------------------------------------------------------------- */
267 apply_declick (bufs, nbufs, nframes, 0.0, 1.0, _phase_invert);
268 _pending_declick = 0;
269 } else if (declick < 0) {
270 apply_declick (bufs, nbufs, nframes, 1.0, 0.0, _phase_invert);
271 _pending_declick = 0;
274 /* no global declick */
276 if (solo_gain != dsg) {
277 apply_declick (bufs, nbufs, nframes, solo_gain, dsg, _phase_invert);
283 /* ----------------------------------------------------------------------------------------------------
284 INPUT METERING & MONITORING
285 -------------------------------------------------------------------------------------------------- */
287 if (meter && (_meter_point == MeterInput)) {
288 for (n = 0; n < nbufs; ++n) {
289 _peak_power[n] = Session::compute_peak (bufs[n], nframes, _peak_power[n]);
293 if (!_soloed && _mute_affects_pre_fader && (mute_gain != dmg)) {
294 apply_declick (bufs, nbufs, nframes, mute_gain, dmg, _phase_invert);
296 mute_declick_applied = true;
299 if ((_meter_point == MeterInput) && co) {
301 solo_audible = dsg > 0;
302 mute_audible = dmg > 0;// || !_mute_affects_pre_fader;
304 if ( // muted by solo of another track
308 // muted by mute of this track
312 // rec-enabled but not s/w monitoring
314 // TODO: this is probably wrong
316 (no_monitor && record_enabled() && (!_session.get_auto_input() || _session.actively_recording()))
320 co->silence (nframes, offset);
324 co->deliver_output (bufs, nbufs, nframes, offset);
329 /* ----------------------------------------------------------------------------------------------------
331 -------------------------------------------------------------------------------------------------- */
333 if (with_redirects) {
334 Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK);
336 if (mute_gain > 0 || !_mute_affects_pre_fader) {
337 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
338 switch ((*i)->placement()) {
340 (*i)->run (bufs, nbufs, nframes, offset);
343 post_fader_work = true;
348 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
349 switch ((*i)->placement()) {
351 (*i)->silence (nframes, offset);
354 post_fader_work = true;
363 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_post_fader) {
364 apply_declick (bufs, nbufs, nframes, mute_gain, dmg, _phase_invert);
366 mute_declick_applied = true;
369 /* ----------------------------------------------------------------------------------------------------
370 PRE-FADER METERING & MONITORING
371 -------------------------------------------------------------------------------------------------- */
373 if (meter && (_meter_point == MeterPreFader)) {
374 for (n = 0; n < nbufs; ++n) {
375 _peak_power[n] = Session::compute_peak (bufs[n], nframes, _peak_power[n]);
380 if ((_meter_point == MeterPreFader) && co) {
382 solo_audible = dsg > 0;
383 mute_audible = dmg > 0 || !_mute_affects_pre_fader;
385 if ( // muted by solo of another track
389 // muted by mute of this track
393 // rec-enabled but not s/w monitoring
395 (no_monitor && record_enabled() && (!_session.get_auto_input() || _session.actively_recording()))
399 co->silence (nframes, offset);
403 co->deliver_output (bufs, nbufs, nframes, offset);
408 /* ----------------------------------------------------------------------------------------------------
410 -------------------------------------------------------------------------------------------------- */
412 /* if not recording or recording and requiring any monitor signal, then apply gain */
414 if ( // not recording
416 !(record_enabled() && _session.actively_recording()) ||
420 // h/w monitoring not in use
422 (!Config->get_use_hardware_monitoring() &&
424 // AND software monitoring required
426 Config->get_use_sw_monitoring())) {
428 if (apply_gain_automation) {
431 for (n = 0; n < nbufs; ++n) {
432 Sample *sp = bufs[n];
434 for (jack_nframes_t nx = 0; nx < nframes; ++nx) {
439 for (n = 0; n < nbufs; ++n) {
440 Sample *sp = bufs[n];
442 for (jack_nframes_t nx = 0; nx < nframes; ++nx) {
448 if (apply_gain_automation && _session.transport_rolling() && nframes > 0) {
449 _effective_gain = gab[nframes-1];
454 /* manual (scalar) gain */
458 apply_declick (bufs, nbufs, nframes, _gain, dg, _phase_invert);
461 } else if (_gain != 0 && (_phase_invert || _gain != 1.0)) {
463 /* no need to interpolate current gain value,
464 but its non-unity, so apply it. if the gain
465 is zero, do nothing because we'll ship silence
477 for (n = 0; n < nbufs; ++n) {
478 Sample *sp = bufs[n];
479 apply_gain_to_buffer(sp,nframes,this_gain);
482 } else if (_gain == 0) {
483 for (n = 0; n < nbufs; ++n) {
484 memset (bufs[n], 0, sizeof (Sample) * nframes);
491 /* actively recording, no monitoring required; leave buffers as-is to save CPU cycles */
495 /* ----------------------------------------------------------------------------------------------------
497 -------------------------------------------------------------------------------------------------- */
499 /* note that post_fader_work cannot be true unless with_redirects was also true, so don't test both */
501 if (post_fader_work) {
503 Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK);
505 if (mute_gain > 0 || !_mute_affects_post_fader) {
506 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
507 switch ((*i)->placement()) {
511 (*i)->run (bufs, nbufs, nframes, offset);
516 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
517 switch ((*i)->placement()) {
521 (*i)->silence (nframes, offset);
529 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_control_outs) {
530 apply_declick (bufs, nbufs, nframes, mute_gain, dmg, _phase_invert);
532 mute_declick_applied = true;
535 /* ----------------------------------------------------------------------------------------------------
537 -------------------------------------------------------------------------------------------------- */
539 if ((_meter_point == MeterPostFader) && co) {
541 solo_audible = solo_gain > 0;
542 mute_audible = dmg > 0 || !_mute_affects_control_outs;
544 if ( // silent anyway
546 (_gain == 0 && !apply_gain_automation) ||
548 // muted by solo of another track
552 // muted by mute of this track
556 // recording but not s/w monitoring
558 (no_monitor && record_enabled() && (!_session.get_auto_input() || _session.actively_recording()))
562 co->silence (nframes, offset);
566 co->deliver_output_no_pan (bufs, nbufs, nframes, offset);
570 /* ----------------------------------------------------------------------
572 ----------------------------------------------------------------------*/
574 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_main_outs) {
575 apply_declick (bufs, nbufs, nframes, mute_gain, dmg, _phase_invert);
577 mute_declick_applied = true;
580 /* ----------------------------------------------------------------------------------------------------
582 -------------------------------------------------------------------------------------------------- */
584 solo_audible = dsg > 0;
585 mute_audible = dmg > 0 || !_mute_affects_main_outs;
587 if (n_outputs() == 0) {
591 } else if (no_monitor && record_enabled() && (!_session.get_auto_input() || _session.actively_recording())) {
593 IO::silence (nframes, offset);
597 if ( // silent anyway
599 (_gain == 0 && !apply_gain_automation) ||
601 // muted by solo of another track, but not using control outs for solo
603 (!solo_audible && (_session.solo_model() != Session::SoloBus)) ||
605 // muted by mute of this track
611 /* don't use Route::silence() here, because that causes
612 all outputs (sends, port inserts, etc. to be silent).
615 if (_meter_point == MeterPostFader) {
616 reset_peak_meters ();
619 IO::silence (nframes, offset);
623 if (_session.transport_speed() > 1.5f || _session.transport_speed() < -1.5f) {
624 pan (bufs, nbufs, nframes, offset, speed_quietning);
626 // cerr << _name << " panner state = " << _panner->automation_state() << endl;
627 if (!_panner->empty() &&
628 (_panner->automation_state() & Play ||
629 ((_panner->automation_state() & Touch) && !_panner->touching()))) {
630 pan_automated (bufs, nbufs, start_frame, end_frame, nframes, offset);
632 pan (bufs, nbufs, nframes, offset, 1.0);
639 /* ----------------------------------------------------------------------------------------------------
641 -------------------------------------------------------------------------------------------------- */
643 if (meter && (_meter_point == MeterPostFader)) {
644 // cerr << "meter post" << endl;
646 if ((_gain == 0 && !apply_gain_automation) || dmg == 0) {
647 uint32_t no = n_outputs();
648 for (n = 0; n < no; ++n) {
652 uint32_t no = n_outputs();
653 for (n = 0; n < no; ++n) {
654 _peak_power[n] = Session::compute_peak (output(n)->get_buffer (nframes) + offset, nframes, _peak_power[n]);
661 Route::n_process_buffers ()
663 return max (n_inputs(), redirect_max_outs);
668 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)
670 vector<Sample*>& bufs = _session.get_passthru_buffers();
671 uint32_t limit = n_process_buffers ();
675 collect_input (bufs, limit, nframes, offset);
677 #define meter_stream meter_first
680 for (uint32_t n = 0; n < limit; ++n) {
681 _peak_power[n] = Session::compute_peak (bufs[n], nframes, _peak_power[n]);
683 meter_stream = false;
688 process_output_buffers (bufs, limit, start_frame, end_frame, nframes, offset, true, declick, meter_stream);
694 Route::set_phase_invert (bool yn, void *src)
696 if (_phase_invert != yn) {
699 // phase_invert_changed (src); /* EMIT SIGNAL */
703 Route::set_solo (bool yn, void *src)
709 if (_mix_group && src != _mix_group && _mix_group->is_active()) {
710 _mix_group->apply (&Route::set_solo, yn, _mix_group);
716 solo_changed (src); /* EMIT SIGNAL */
717 _solo_control.Changed (); /* EMIT SIGNAL */
722 Route::set_solo_mute (bool yn)
724 Glib::Mutex::Lock lm (declick_lock);
726 /* Called by Session in response to another Route being soloed.
729 desired_solo_gain = (yn?0.0:1.0);
733 Route::set_solo_safe (bool yn, void *src)
735 if (_solo_safe != yn) {
737 solo_safe_changed (src); /* EMIT SIGNAL */
742 Route::set_mute (bool yn, void *src)
745 if (_mix_group && src != _mix_group && _mix_group->is_active()) {
746 _mix_group->apply (&Route::set_mute, yn, _mix_group);
752 mute_changed (src); /* EMIT SIGNAL */
754 _mute_control.Changed (); /* EMIT SIGNAL */
756 Glib::Mutex::Lock lm (declick_lock);
757 desired_mute_gain = (yn?0.0f:1.0f);
762 Route::add_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
764 uint32_t old_rmo = redirect_max_outs;
766 if (!_session.engine().connected()) {
771 Glib::RWLock::WriterLock lm (redirect_lock);
773 boost::shared_ptr<PluginInsert> pi;
774 boost::shared_ptr<PortInsert> porti;
776 uint32_t potential_max_streams = 0;
778 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(redirect)) != 0) {
781 if (pi->input_streams() == 0) {
782 /* instrument plugin */
783 _have_internal_generator = true;
786 potential_max_streams = max(pi->input_streams(), pi->output_streams());
788 } else if ((porti = boost::dynamic_pointer_cast<PortInsert>(redirect)) != 0) {
790 /* force new port inserts to start out with an i/o configuration
791 that matches this route's i/o configuration.
793 the "inputs" for the port are supposed to match the output
796 the "outputs" of the route should match the inputs of this
797 route. XXX shouldn't they match the number of active signal
798 streams at the point of insertion?
802 porti->ensure_io (n_outputs (), n_inputs(), false, this);
805 // Ensure peak vector sizes before the plugin is activated
806 while (_peak_power.size() < potential_max_streams) {
807 _peak_power.push_back(0);
809 while (_visible_peak_power.size() < potential_max_streams) {
810 _visible_peak_power.push_back(0);
813 _redirects.push_back (redirect);
815 if (_reset_plugin_counts (err_streams)) {
816 _redirects.pop_back ();
817 _reset_plugin_counts (0); // it worked before we tried to add it ...
821 redirect->activate ();
822 redirect->active_changed.connect (mem_fun (*this, &Route::redirect_active_proxy));
825 if (redirect_max_outs != old_rmo || old_rmo == 0) {
830 redirects_changed (src); /* EMIT SIGNAL */
835 Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_streams)
837 uint32_t old_rmo = redirect_max_outs;
839 if (!_session.engine().connected()) {
844 Glib::RWLock::WriterLock lm (redirect_lock);
846 RedirectList::iterator existing_end = _redirects.end();
849 uint32_t potential_max_streams = 0;
851 for (RedirectList::const_iterator i = others.begin(); i != others.end(); ++i) {
853 boost::shared_ptr<PluginInsert> pi;
855 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
858 uint32_t m = max(pi->input_streams(), pi->output_streams());
859 if (m > potential_max_streams)
860 potential_max_streams = m;
863 // Ensure peak vector sizes before the plugin is activated
864 while (_peak_power.size() < potential_max_streams) {
865 _peak_power.push_back(0);
867 while (_visible_peak_power.size() < potential_max_streams) {
868 _visible_peak_power.push_back(0);
871 _redirects.push_back (*i);
873 if (_reset_plugin_counts (err_streams)) {
875 _redirects.erase (existing_end, _redirects.end());
876 _reset_plugin_counts (0); // it worked before we tried to add it ...
881 (*i)->active_changed.connect (mem_fun (*this, &Route::redirect_active_proxy));
885 if (redirect_max_outs != old_rmo || old_rmo == 0) {
889 redirects_changed (src); /* EMIT SIGNAL */
894 Route::clear_redirects (void *src)
896 uint32_t old_rmo = redirect_max_outs;
898 if (!_session.engine().connected()) {
903 Glib::RWLock::WriterLock lm (redirect_lock);
907 if (redirect_max_outs != old_rmo) {
911 redirect_max_outs = 0;
912 _have_internal_generator = false;
913 redirects_changed (src); /* EMIT SIGNAL */
917 Route::remove_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
919 uint32_t old_rmo = redirect_max_outs;
921 if (!_session.engine().connected()) {
925 redirect_max_outs = 0;
928 Glib::RWLock::WriterLock lm (redirect_lock);
929 RedirectList::iterator i;
930 bool removed = false;
932 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
933 if (*i == redirect) {
935 RedirectList::iterator tmp;
937 /* move along, see failure case for reset_plugin_counts()
938 where we may need to reinsert the redirect.
944 /* stop redirects that send signals to JACK ports
945 from causing noise as a result of no longer being
949 boost::shared_ptr<Send> send;
950 boost::shared_ptr<PortInsert> port_insert;
952 if ((send = boost::dynamic_pointer_cast<Send> (*i)) != 0) {
953 send->disconnect_inputs (this);
954 send->disconnect_outputs (this);
955 } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (*i)) != 0) {
956 port_insert->disconnect_inputs (this);
957 port_insert->disconnect_outputs (this);
960 _redirects.erase (i);
973 if (_reset_plugin_counts (err_streams)) {
974 /* get back to where we where */
975 _redirects.insert (i, redirect);
976 /* we know this will work, because it worked before :) */
977 _reset_plugin_counts (0);
983 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
984 boost::shared_ptr<PluginInsert> pi;
986 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
987 if (pi->is_generator()) {
993 _have_internal_generator = foo;
996 if (old_rmo != redirect_max_outs) {
1000 redirects_changed (src); /* EMIT SIGNAL */
1005 Route::reset_plugin_counts (uint32_t* lpc)
1007 Glib::RWLock::WriterLock lm (redirect_lock);
1008 return _reset_plugin_counts (lpc);
1013 Route::_reset_plugin_counts (uint32_t* err_streams)
1015 RedirectList::iterator r;
1018 map<Placement,list<InsertCount> > insert_map;
1019 jack_nframes_t initial_streams;
1021 redirect_max_outs = 0;
1025 /* divide inserts up by placement so we get the signal flow
1026 properly modelled. we need to do this because the _redirects
1027 list is not sorted by placement, and because other reasons may
1028 exist now or in the future for this separate treatment.
1031 for (r = _redirects.begin(); r != _redirects.end(); ++r) {
1033 boost::shared_ptr<Insert> insert;
1035 /* do this here in case we bomb out before we get to the end of
1039 redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs);
1041 if ((insert = boost::dynamic_pointer_cast<Insert>(*r)) != 0) {
1043 insert_map[insert->placement()].push_back (InsertCount (insert));
1045 /* reset plugin counts back to one for now so
1046 that we have a predictable, controlled
1047 state to try to configure.
1050 boost::shared_ptr<PluginInsert> pi;
1052 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(insert)) != 0) {
1056 } else if (boost::dynamic_pointer_cast<Send> (*r) != 0) {
1069 /* Now process each placement in order, checking to see if we
1070 can really do what has been requested.
1075 if (check_some_plugin_counts (insert_map[PreFader], n_inputs (), err_streams)) {
1079 /* figure out the streams that will feed into PreFader */
1081 if (!insert_map[PreFader].empty()) {
1082 InsertCount& ic (insert_map[PreFader].back());
1083 initial_streams = ic.insert->compute_output_streams (ic.cnt);
1085 initial_streams = n_inputs ();
1090 if (check_some_plugin_counts (insert_map[PostFader], initial_streams, err_streams)) {
1094 /* OK, everything can be set up correctly, so lets do it */
1096 apply_some_plugin_counts (insert_map[PreFader]);
1097 apply_some_plugin_counts (insert_map[PostFader]);
1099 /* recompute max outs of any redirect */
1103 redirect_max_outs = 0;
1104 RedirectList::iterator prev = _redirects.end();
1106 for (r = _redirects.begin(); r != _redirects.end(); prev = r, ++r) {
1107 boost::shared_ptr<Send> s;
1109 if ((s = boost::dynamic_pointer_cast<Send> (*r)) != 0) {
1110 if (r == _redirects.begin()) {
1111 s->expect_inputs (n_inputs());
1113 s->expect_inputs ((*prev)->output_streams());
1117 redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs);
1126 Route::apply_some_plugin_counts (list<InsertCount>& iclist)
1128 list<InsertCount>::iterator i;
1130 for (i = iclist.begin(); i != iclist.end(); ++i) {
1132 if ((*i).insert->configure_io ((*i).cnt, (*i).in, (*i).out)) {
1135 /* make sure that however many we have, they are all active */
1136 (*i).insert->activate ();
1143 Route::check_some_plugin_counts (list<InsertCount>& iclist, int32_t required_inputs, uint32_t* err_streams)
1145 list<InsertCount>::iterator i;
1147 for (i = iclist.begin(); i != iclist.end(); ++i) {
1149 if (((*i).cnt = (*i).insert->can_support_input_configuration (required_inputs)) < 0) {
1151 *err_streams = required_inputs;
1156 (*i).in = required_inputs;
1157 (*i).out = (*i).insert->compute_output_streams ((*i).cnt);
1159 required_inputs = (*i).out;
1166 Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_streams)
1168 uint32_t old_rmo = redirect_max_outs;
1174 RedirectList to_be_deleted;
1177 Glib::RWLock::WriterLock lm (redirect_lock);
1178 RedirectList::iterator tmp;
1179 RedirectList the_copy;
1181 the_copy = _redirects;
1183 /* remove all relevant redirects */
1185 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ) {
1189 if ((*i)->placement() == placement) {
1190 to_be_deleted.push_back (*i);
1191 _redirects.erase (i);
1197 /* now copy the relevant ones from "other" */
1199 for (RedirectList::const_iterator i = other._redirects.begin(); i != other._redirects.end(); ++i) {
1200 if ((*i)->placement() == placement) {
1201 _redirects.push_back (Redirect::clone (*i));
1205 /* reset plugin stream handling */
1207 if (_reset_plugin_counts (err_streams)) {
1209 /* FAILED COPY ATTEMPT: we have to restore order */
1211 /* delete all cloned redirects */
1213 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ) {
1218 if ((*i)->placement() == placement) {
1219 _redirects.erase (i);
1225 /* restore the natural order */
1227 _redirects = the_copy;
1228 redirect_max_outs = old_rmo;
1230 /* we failed, even though things are OK again */
1236 /* SUCCESSFUL COPY ATTEMPT: delete the redirects we removed pre-copy */
1237 to_be_deleted.clear ();
1241 if (redirect_max_outs != old_rmo || old_rmo == 0) {
1245 redirects_changed (this); /* EMIT SIGNAL */
1250 Route::all_redirects_flip ()
1252 Glib::RWLock::ReaderLock lm (redirect_lock);
1254 if (_redirects.empty()) {
1258 bool first_is_on = _redirects.front()->active();
1260 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1261 (*i)->set_active (!first_is_on, this);
1266 Route::all_redirects_active (bool state)
1268 Glib::RWLock::ReaderLock lm (redirect_lock);
1270 if (_redirects.empty()) {
1274 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1275 (*i)->set_active (state, this);
1279 struct RedirectSorter {
1280 bool operator() (boost::shared_ptr<const Redirect> a, boost::shared_ptr<const Redirect> b) {
1281 return a->sort_key() < b->sort_key();
1286 Route::sort_redirects (uint32_t* err_streams)
1289 RedirectSorter comparator;
1290 Glib::RWLock::WriterLock lm (redirect_lock);
1291 uint32_t old_rmo = redirect_max_outs;
1293 /* the sweet power of C++ ... */
1295 RedirectList as_it_was_before = _redirects;
1297 _redirects.sort (comparator);
1299 if (_reset_plugin_counts (err_streams)) {
1300 _redirects = as_it_was_before;
1301 redirect_max_outs = old_rmo;
1307 redirects_changed (this); /* EMIT SIGNAL */
1319 Route::get_template()
1321 return state(false);
1325 Route::state(bool full_state)
1327 XMLNode *node = new XMLNode("Route");
1329 RedirectList:: iterator i;
1333 snprintf (buf, sizeof (buf), "0x%x", _flags);
1334 node->add_property("flags", buf);
1337 node->add_property("default-type", _default_type.to_string());
1339 node->add_property("active", _active?"yes":"no");
1340 node->add_property("muted", _muted?"yes":"no");
1341 node->add_property("soloed", _soloed?"yes":"no");
1342 node->add_property("phase-invert", _phase_invert?"yes":"no");
1343 node->add_property("mute-affects-pre-fader", _mute_affects_pre_fader?"yes":"no");
1344 node->add_property("mute-affects-post-fader", _mute_affects_post_fader?"yes":"no");
1345 node->add_property("mute-affects-control-outs", _mute_affects_control_outs?"yes":"no");
1346 node->add_property("mute-affects-main-outs", _mute_affects_main_outs?"yes":"no");
1349 node->add_property("edit-group", _edit_group->name());
1352 node->add_property("mix-group", _mix_group->name());
1355 string order_string;
1356 OrderKeys::iterator x = order_keys.begin();
1358 while (x != order_keys.end()) {
1359 order_string += (*x).first;
1360 order_string += '=';
1361 snprintf (buf, sizeof(buf), "%ld", (*x).second);
1362 order_string += buf;
1366 if (x == order_keys.end()) {
1370 order_string += ':';
1372 node->add_property ("order-keys", order_string);
1374 node->add_child_nocopy (IO::state (full_state));
1376 if (_control_outs) {
1377 XMLNode* cnode = new XMLNode (X_("ControlOuts"));
1378 cnode->add_child_nocopy (_control_outs->state (full_state));
1379 node->add_child_nocopy (*cnode);
1382 if (_comment.length()) {
1383 XMLNode *cmt = node->add_child ("Comment");
1384 cmt->add_content (_comment);
1390 path = _session.snap_name();
1392 path += legalize_for_path (_name);
1393 path += ".automation";
1395 /* XXX we didn't ask for a state save, we asked for the current state.
1399 if (save_automation (path)) {
1400 error << _("Could not get state of route. Problem with save_automation") << endmsg;
1403 aevents = node->add_child ("Automation");
1404 aevents->add_property ("path", path);
1407 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
1408 node->add_child_nocopy((*i)->state (full_state));
1412 node->add_child_copy (*_extra_xml);
1419 Route::set_deferred_state ()
1422 XMLNodeConstIterator niter;
1424 if (!deferred_state) {
1428 nlist = deferred_state->children();
1430 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1431 add_redirect_from_xml (**niter);
1434 delete deferred_state;
1439 Route::add_redirect_from_xml (const XMLNode& node)
1441 const XMLProperty *prop;
1443 if (node.name() == "Send") {
1447 boost::shared_ptr<Send> send (new Send (_session, node));
1448 add_redirect (send, this);
1451 catch (failed_constructor &err) {
1452 error << _("Send construction failed") << endmsg;
1456 } else if (node.name() == "Insert") {
1459 if ((prop = node.property ("type")) != 0) {
1461 boost::shared_ptr<Insert> insert;
1463 if (prop->value() == "ladspa" || prop->value() == "Ladspa" || prop->value() == "vst") {
1465 insert.reset (new PluginInsert(_session, node));
1467 } else if (prop->value() == "port") {
1470 insert.reset (new PortInsert (_session, node));
1474 error << string_compose(_("unknown Insert type \"%1\"; ignored"), prop->value()) << endmsg;
1477 add_redirect (insert, this);
1480 error << _("Insert XML node has no type property") << endmsg;
1484 catch (failed_constructor &err) {
1485 warning << _("insert could not be created. Ignored.") << endmsg;
1492 Route::set_state (const XMLNode& node)
1495 XMLNodeConstIterator niter;
1497 XMLPropertyList plist;
1498 const XMLProperty *prop;
1500 if (node.name() != "Route"){
1501 error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
1505 if ((prop = node.property ("flags")) != 0) {
1507 sscanf (prop->value().c_str(), "0x%x", &x);
1513 if ((prop = node.property ("default-type")) != 0) {
1514 _default_type = DataType(prop->value());
1515 assert(_default_type != DataType::NIL);
1518 if ((prop = node.property ("phase-invert")) != 0) {
1519 set_phase_invert(prop->value()=="yes"?true:false, this);
1522 if ((prop = node.property ("active")) != 0) {
1523 set_active (prop->value() == "yes");
1526 if ((prop = node.property ("muted")) != 0) {
1527 bool yn = prop->value()=="yes"?true:false;
1529 /* force reset of mute status */
1533 mute_gain = desired_mute_gain;
1536 if ((prop = node.property ("soloed")) != 0) {
1537 bool yn = prop->value()=="yes"?true:false;
1539 /* force reset of solo status */
1542 set_solo (yn, this);
1543 solo_gain = desired_solo_gain;
1546 if ((prop = node.property ("mute-affects-pre-fader")) != 0) {
1547 _mute_affects_pre_fader = (prop->value()=="yes")?true:false;
1550 if ((prop = node.property ("mute-affects-post-fader")) != 0) {
1551 _mute_affects_post_fader = (prop->value()=="yes")?true:false;
1554 if ((prop = node.property ("mute-affects-control-outs")) != 0) {
1555 _mute_affects_control_outs = (prop->value()=="yes")?true:false;
1558 if ((prop = node.property ("mute-affects-main-outs")) != 0) {
1559 _mute_affects_main_outs = (prop->value()=="yes")?true:false;
1562 if ((prop = node.property ("edit-group")) != 0) {
1563 RouteGroup* edit_group = _session.edit_group_by_name(prop->value());
1564 if(edit_group == 0) {
1565 error << string_compose(_("Route %1: unknown edit group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
1567 set_edit_group(edit_group, this);
1571 if ((prop = node.property ("order-keys")) != 0) {
1575 string::size_type colon, equal;
1576 string remaining = prop->value();
1578 while (remaining.length()) {
1580 if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
1581 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1584 if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) {
1585 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1588 set_order_key (remaining.substr (0, equal), n);
1592 colon = remaining.find_first_of (':');
1594 if (colon != string::npos) {
1595 remaining = remaining.substr (colon+1);
1602 nlist = node.children();
1604 if (deferred_state) {
1605 delete deferred_state;
1608 deferred_state = new XMLNode("deferred state");
1610 /* set parent class properties before anything else */
1612 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1616 if (child->name() == IO::state_node_name) {
1618 IO::set_state (*child);
1623 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1627 if (child->name() == "Send") {
1630 if (!IO::ports_legal) {
1632 deferred_state->add_child_copy (*child);
1635 add_redirect_from_xml (*child);
1638 } else if (child->name() == "Insert") {
1640 if (!IO::ports_legal) {
1642 deferred_state->add_child_copy (*child);
1646 add_redirect_from_xml (*child);
1649 } else if (child->name() == "Automation") {
1651 XMLPropertyList plist;
1652 XMLPropertyConstIterator piter;
1655 plist = child->properties();
1656 for (piter = plist.begin(); piter != plist.end(); ++piter) {
1658 if (prop->name() == "path") {
1659 load_automation (prop->value());
1663 } else if (child->name() == "ControlOuts") {
1665 string coutname = _name;
1666 coutname += _("[control]");
1668 _control_outs = new IO (_session, coutname);
1669 _control_outs->set_state (**(child->children().begin()));
1671 } else if (child->name() == "Comment") {
1673 /* XXX this is a terrible API design in libxml++ */
1675 XMLNode *cmt = *(child->children().begin());
1676 _comment = cmt->content();
1678 } else if (child->name() == "extra") {
1679 _extra_xml = new XMLNode (*child);
1683 if ((prop = node.property ("mix-group")) != 0) {
1684 RouteGroup* mix_group = _session.mix_group_by_name(prop->value());
1685 if (mix_group == 0) {
1686 error << string_compose(_("Route %1: unknown mix group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
1688 set_mix_group(mix_group, this);
1696 Route::curve_reallocate ()
1698 // _gain_automation_curve.finish_resize ();
1699 // _pan_automation_curve.finish_resize ();
1703 Route::silence (jack_nframes_t nframes, jack_nframes_t offset)
1707 // reset_peak_meters ();
1709 IO::silence (nframes, offset);
1711 if (_control_outs) {
1712 _control_outs->silence (nframes, offset);
1716 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
1719 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1720 boost::shared_ptr<PluginInsert> pi;
1721 if (!_active && (pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
1722 // skip plugins, they don't need anything when we're not active
1726 (*i)->silence (nframes, offset);
1729 if (nframes == _session.get_block_size() && offset == 0) {
1739 Route::set_control_outs (const vector<string>& ports)
1741 Glib::Mutex::Lock lm (control_outs_lock);
1742 vector<string>::const_iterator i;
1744 if (_control_outs) {
1745 delete _control_outs;
1749 if (ports.empty()) {
1753 string coutname = _name;
1754 coutname += _("[control]");
1756 _control_outs = new IO (_session, coutname);
1758 /* our control outs need as many outputs as we
1759 have outputs. we track the changes in ::output_change_handler().
1762 _control_outs->ensure_io (0, n_outputs(), true, this);
1768 Route::set_edit_group (RouteGroup *eg, void *src)
1771 if (eg == _edit_group) {
1776 _edit_group->remove (this);
1779 if ((_edit_group = eg) != 0) {
1780 _edit_group->add (this);
1783 _session.set_dirty ();
1784 edit_group_changed (src); /* EMIT SIGNAL */
1788 Route::drop_edit_group (void *src)
1791 _session.set_dirty ();
1792 edit_group_changed (src); /* EMIT SIGNAL */
1796 Route::set_mix_group (RouteGroup *mg, void *src)
1799 if (mg == _mix_group) {
1804 _mix_group->remove (this);
1807 if ((_mix_group = mg) != 0) {
1808 _mix_group->add (this);
1811 _session.set_dirty ();
1812 mix_group_changed (src); /* EMIT SIGNAL */
1816 Route::drop_mix_group (void *src)
1819 _session.set_dirty ();
1820 mix_group_changed (src); /* EMIT SIGNAL */
1824 Route::set_comment (string cmt, void *src)
1827 comment_changed (src);
1828 _session.set_dirty ();
1832 Route::feeds (boost::shared_ptr<Route> other)
1837 uint32_t no = self.n_outputs();
1838 uint32_t ni = other->n_inputs ();
1840 for (i = 0; i < no; ++i) {
1841 for (j = 0; j < ni; ++j) {
1842 if (self.output(i)->connected_to (other->input(j)->name())) {
1848 /* check Redirects which may also interconnect Routes */
1850 for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); r++) {
1852 no = (*r)->n_outputs();
1854 for (i = 0; i < no; ++i) {
1855 for (j = 0; j < ni; ++j) {
1856 if ((*r)->output(i)->connected_to (other->input (j)->name())) {
1863 /* check for control room outputs which may also interconnect Routes */
1865 if (_control_outs) {
1867 no = _control_outs->n_outputs();
1869 for (i = 0; i < no; ++i) {
1870 for (j = 0; j < ni; ++j) {
1871 if (_control_outs->output(i)->connected_to (other->input (j)->name())) {
1882 Route::set_mute_config (mute_type t, bool onoff, void *src)
1886 _mute_affects_pre_fader = onoff;
1887 pre_fader_changed(src); /* EMIT SIGNAL */
1891 _mute_affects_post_fader = onoff;
1892 post_fader_changed(src); /* EMIT SIGNAL */
1896 _mute_affects_control_outs = onoff;
1897 control_outs_changed(src); /* EMIT SIGNAL */
1901 _mute_affects_main_outs = onoff;
1902 main_outs_changed(src); /* EMIT SIGNAL */
1908 Route::get_mute_config (mute_type t)
1914 onoff = _mute_affects_pre_fader;
1917 onoff = _mute_affects_post_fader;
1920 onoff = _mute_affects_control_outs;
1923 onoff = _mute_affects_main_outs;
1931 Route::set_active (bool yn)
1934 active_changed(); /* EMIT SIGNAL */
1938 Route::handle_transport_stopped (bool abort_ignored, bool did_locate, bool can_flush_redirects)
1940 jack_nframes_t now = _session.transport_frame();
1943 Glib::RWLock::ReaderLock lm (redirect_lock);
1946 automation_snapshot (now);
1949 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1951 if (Config->get_plugins_stop_with_transport() && can_flush_redirects) {
1952 (*i)->deactivate ();
1956 (*i)->transport_stopped (now);
1960 IO::transport_stopped (now);
1962 _roll_delay = _initial_delay;
1966 Route::get_memento() const
1968 void (Route::*pmf)(state_id_t) = &Route::set_state;
1969 return sigc::bind (mem_fun (*(const_cast<Route *>(this)), pmf), _current_state_id);
1973 Route::set_state (state_id_t id)
1979 Route::input_change_handler (IOChange change, void *ignored)
1981 if (change & ConfigurationChanged) {
1982 reset_plugin_counts (0);
1987 Route::output_change_handler (IOChange change, void *ignored)
1989 if (change & ConfigurationChanged) {
1990 if (_control_outs) {
1991 _control_outs->ensure_io (0, n_outputs(), true, this);
1994 reset_plugin_counts (0);
1999 Route::pans_required () const
2001 if (n_outputs() < 2) {
2005 return max (n_inputs (), redirect_max_outs);
2009 Route::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset,
2010 bool session_state_changing, bool can_record, bool rec_monitors_input)
2012 if (n_outputs() == 0) {
2016 if (session_state_changing || !_active) {
2017 silence (nframes, offset);
2021 apply_gain_automation = false;
2024 passthru (start_frame, end_frame, nframes, offset, 0, false);
2026 silence (nframes, offset);
2033 Route::check_initial_delay (jack_nframes_t nframes, jack_nframes_t& offset, jack_nframes_t& transport_frame)
2035 if (_roll_delay > nframes) {
2037 _roll_delay -= nframes;
2038 silence (nframes, offset);
2039 /* transport frame is not legal for caller to use */
2042 } else if (_roll_delay > 0) {
2044 nframes -= _roll_delay;
2046 silence (_roll_delay, offset);
2048 offset += _roll_delay;
2049 transport_frame += _roll_delay;
2058 Route::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset, int declick,
2059 bool can_record, bool rec_monitors_input)
2062 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
2064 // automation snapshot can also be called from the non-rt context
2065 // and it uses the redirect list, so we take the lock out here
2066 automation_snapshot (_session.transport_frame());
2070 if ((n_outputs() == 0 && _redirects.empty()) || n_inputs() == 0 || !_active) {
2071 silence (nframes, offset);
2075 jack_nframes_t unused = 0;
2077 if ((nframes = check_initial_delay (nframes, offset, unused)) == 0) {
2083 apply_gain_automation = false;
2086 Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK);
2088 if (am.locked() && _session.transport_rolling()) {
2090 jack_nframes_t start_frame = end_frame - nframes;
2092 if (gain_automation_playback()) {
2093 apply_gain_automation = _gain_automation_curve.rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes);
2098 passthru (start_frame, end_frame, nframes, offset, declick, false);
2104 Route::silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset,
2105 bool can_record, bool rec_monitors_input)
2107 silence (nframes, offset);
2112 Route::toggle_monitor_input ()
2114 for (vector<Port*>::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
2115 (*i)->request_monitor_input(!(*i)->monitoring_input());
2120 Route::has_external_redirects () const
2122 boost::shared_ptr<const PortInsert> pi;
2124 for (RedirectList::const_iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2125 if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*i)) != 0) {
2127 uint32_t no = pi->n_outputs();
2129 for (uint32_t n = 0; n < no; ++n) {
2131 string port_name = pi->output(n)->name();
2132 string client_name = port_name.substr (0, port_name.find(':'));
2134 /* only say "yes" if the redirect is actually in use */
2136 if (client_name != "ardour" && pi->active()) {
2147 Route::flush_redirects ()
2149 /* XXX shouldn't really try to take this lock, since
2150 this is called from the RT audio thread.
2153 Glib::RWLock::ReaderLock lm (redirect_lock);
2155 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2156 (*i)->deactivate ();
2162 Route::set_meter_point (MeterPoint p, void *src)
2164 if (_meter_point != p) {
2166 meter_change (src); /* EMIT SIGNAL */
2167 _session.set_dirty ();
2172 Route::update_total_latency ()
2176 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2177 if ((*i)->active ()) {
2178 _own_latency += (*i)->latency ();
2182 set_port_latency (_own_latency);
2184 /* this (virtual) function is used for pure Routes,
2185 not derived classes like AudioTrack. this means
2186 that the data processed here comes from an input
2187 port, not prerecorded material, and therefore we
2188 have to take into account any input latency.
2191 _own_latency += input_latency ();
2193 return _own_latency;
2197 Route::set_latency_delay (jack_nframes_t longest_session_latency)
2199 _initial_delay = longest_session_latency - _own_latency;
2201 if (_session.transport_stopped()) {
2202 _roll_delay = _initial_delay;
2207 Route::automation_snapshot (jack_nframes_t now)
2209 IO::automation_snapshot (now);
2211 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2212 (*i)->automation_snapshot (now);
2216 Route::ToggleControllable::ToggleControllable (Route& s, ToggleType tp)
2217 : route (s), type(tp)
2223 Route::ToggleControllable::set_value (float val)
2225 bool bval = ((val >= 0.5f) ? true: false);
2229 route.set_mute (bval, this);
2232 route.set_solo (bval, this);
2240 Route::ToggleControllable::get_value (void) const
2246 val = route.muted() ? 1.0f : 0.0f;
2249 val = route.soloed() ? 1.0f : 0.0f;
2259 Route::set_block_size (jack_nframes_t nframes)
2261 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2262 (*i)->set_block_size (nframes);
2267 Route::redirect_active_proxy (Redirect* ignored, void* ignored_src)
2269 _session.update_latency_compensation (false, false);
2273 Route::protect_automation ()
2275 switch (gain_automation_state()) {
2278 set_gain_automation_state (Off);
2284 switch (panner().automation_state ()) {
2287 panner().set_automation_state (Off);
2293 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2294 boost::shared_ptr<PluginInsert> pi;
2295 if ((pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
2296 pi->protect_automation ();
2302 Route::set_pending_declick (int declick)
2305 /* this call is not allowed to turn off a pending declick unless "force" is true */
2307 _pending_declick = declick;
2309 // cerr << _name << ": after setting to " << declick << " pending declick = " << _pending_declick << endl;
2311 _pending_declick = 0;