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/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/mix.h>
45 #include <ardour/declicker.h>
46 #include <ardour/meter.h>
47 #include <ardour/buffer_set.h>
51 using namespace ARDOUR;
55 uint32_t Route::order_key_cnt = 0;
58 Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg, DataType default_type)
59 : IO (sess, name, input_min, input_max, output_min, output_max, default_type),
61 _solo_control (*this, ToggleControllable::SoloControl),
62 _mute_control (*this, ToggleControllable::MuteControl)
67 Route::Route (Session& sess, const XMLNode& node)
69 _solo_control (*this, ToggleControllable::SoloControl),
70 _mute_control (*this, ToggleControllable::MuteControl)
79 redirect_max_outs.reset();
83 _phase_invert = false;
84 order_keys[N_("signal")] = order_key_cnt++;
87 _meter_point = MeterPostFader;
91 _have_internal_generator = false;
93 _pending_declick = true;
94 _remote_control_id = 0;
99 _mute_affects_pre_fader = Config->get_mute_affects_pre_fader();
100 _mute_affects_post_fader = Config->get_mute_affects_post_fader();
101 _mute_affects_control_outs = Config->get_mute_affects_control_outs();
102 _mute_affects_main_outs = Config->get_mute_affects_main_outs();
105 desired_solo_gain = 1.0;
107 desired_mute_gain = 1.0;
111 input_changed.connect (mem_fun (this, &Route::input_change_handler));
112 output_changed.connect (mem_fun (this, &Route::output_change_handler));
117 GoingAway (); /* EMIT SIGNAL */
118 clear_redirects (this);
121 delete _control_outs;
126 Route::set_remote_control_id (uint32_t id)
128 if (id != _remote_control_id) {
129 _remote_control_id = id;
130 RemoteControlIDChanged ();
135 Route::remote_control_id() const
137 return _remote_control_id;
141 Route::order_key (string name) const
143 OrderKeys::const_iterator i;
145 if ((i = order_keys.find (name)) == order_keys.end()) {
153 Route::set_order_key (string name, long n)
155 order_keys[name] = n;
156 _session.set_dirty ();
160 Route::inc_gain (gain_t fraction, void *src)
162 IO::inc_gain (fraction, src);
166 Route::set_gain (gain_t val, void *src)
168 if (src != 0 && _mix_group && src != _mix_group && _mix_group->is_active()) {
170 if (_mix_group->is_relative()) {
173 gain_t usable_gain = gain();
174 if (usable_gain < 0.000001f) {
175 usable_gain=0.000001f;
179 if (delta < 0.000001f) {
183 delta -= usable_gain;
185 if (delta == 0.0f) return;
187 gain_t factor = delta / usable_gain;
190 factor = _mix_group->get_max_factor(factor);
191 if (factor == 0.0f) {
196 factor = _mix_group->get_min_factor(factor);
197 if (factor == 0.0f) {
203 _mix_group->apply (&Route::inc_gain, factor, _mix_group);
207 _mix_group->apply (&Route::set_gain, val, _mix_group);
217 IO::set_gain (val, src);
220 /** Process this route for one (sub) cycle (process thread)
222 * @param bufs Scratch buffers to use for the signal path
223 * @param start_frame Initial transport frame
224 * @param end_frame Final transport frame
225 * @param nframes Number of frames to output (to ports)
226 * @param offset Output offset (of port buffers, for split cycles)
228 * Note that (end_frame - start_frame) may not be equal to nframes when the
229 * transport speed isn't 1.0 (eg varispeed).
232 Route::process_output_buffers (BufferSet& bufs,
233 jack_nframes_t start_frame, jack_nframes_t end_frame,
234 jack_nframes_t nframes, jack_nframes_t offset, bool with_redirects, int declick,
237 // This is definitely very audio-only for now
238 assert(_default_type == DataType::AUDIO);
240 RedirectList::iterator i;
241 bool post_fader_work = false;
242 bool mute_declick_applied = false;
244 vector<Sample*>::iterator bufiter;
248 bool no_monitor = (Config->get_use_hardware_monitoring() || !Config->get_use_sw_monitoring ());
249 gain_t* gab = _session.gain_automation_buffer();
251 declick = _pending_declick;
254 Glib::Mutex::Lock cm (control_outs_lock, Glib::TRY_LOCK);
264 Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK);
267 dmg = desired_mute_gain;
268 dsg = desired_solo_gain;
277 /* ----------------------------------------------------------------------------------------------------
278 GLOBAL DECLICK (for transport changes etc.)
279 -------------------------------------------------------------------------------------------------- */
282 Declicker::run (bufs, nframes, 0.0, 1.0, _phase_invert);
283 _pending_declick = 0;
284 } else if (declick < 0) {
285 Declicker::run (bufs, nframes, 1.0, 0.0, _phase_invert);
286 _pending_declick = 0;
289 /* no global declick */
291 if (solo_gain != dsg) {
292 Declicker::run (bufs, nframes, solo_gain, dsg, _phase_invert);
298 /* ----------------------------------------------------------------------------------------------------
299 INPUT METERING & MONITORING
300 -------------------------------------------------------------------------------------------------- */
302 if (meter && (_meter_point == MeterInput)) {
303 _meter->run(bufs, nframes);
306 if (!_soloed && _mute_affects_pre_fader && (mute_gain != dmg)) {
307 Declicker::run (bufs, nframes, mute_gain, dmg, _phase_invert);
309 mute_declick_applied = true;
312 if ((_meter_point == MeterInput) && co) {
314 solo_audible = dsg > 0;
315 mute_audible = dmg > 0;// || !_mute_affects_pre_fader;
317 if ( // muted by solo of another track
321 // muted by mute of this track
325 // rec-enabled but not s/w monitoring
327 // TODO: this is probably wrong
329 (no_monitor && record_enabled() && (!_session.get_auto_input() || _session.actively_recording()))
333 co->silence (nframes, offset);
337 co->deliver_output (bufs, nframes, offset);
342 /* ----------------------------------------------------------------------------------------------------
344 -------------------------------------------------------------------------------------------------- */
346 if (with_redirects) {
347 Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK);
349 if (mute_gain > 0 || !_mute_affects_pre_fader) {
350 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
351 switch ((*i)->placement()) {
353 (*i)->run (bufs, nframes, offset);
356 post_fader_work = true;
361 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
362 switch ((*i)->placement()) {
364 (*i)->silence (nframes, offset);
367 post_fader_work = true;
376 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_post_fader) {
377 Declicker::run (bufs, nframes, mute_gain, dmg, _phase_invert);
379 mute_declick_applied = true;
382 /* ----------------------------------------------------------------------------------------------------
383 PRE-FADER METERING & MONITORING
384 -------------------------------------------------------------------------------------------------- */
386 if (meter && (_meter_point == MeterPreFader)) {
387 _meter->run(bufs, nframes);
391 if ((_meter_point == MeterPreFader) && co) {
393 solo_audible = dsg > 0;
394 mute_audible = dmg > 0 || !_mute_affects_pre_fader;
396 if ( // muted by solo of another track
400 // muted by mute of this track
404 // rec-enabled but not s/w monitoring
406 (no_monitor && record_enabled() && (!_session.get_auto_input() || _session.actively_recording()))
410 co->silence (nframes, offset);
414 co->deliver_output (bufs, nframes, offset);
419 /* ----------------------------------------------------------------------------------------------------
421 -------------------------------------------------------------------------------------------------- */
423 /* if not recording or recording and requiring any monitor signal, then apply gain */
425 if ( // not recording
427 !(record_enabled() && _session.actively_recording()) ||
431 // h/w monitoring not in use
433 (!Config->get_use_hardware_monitoring() &&
435 // AND software monitoring required
437 Config->get_use_sw_monitoring())) {
439 if (apply_gain_automation) {
442 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
443 Sample* const sp = i->data(nframes);
445 for (jack_nframes_t nx = 0; nx < nframes; ++nx) {
450 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
451 Sample* const sp = i->data(nframes);
453 for (jack_nframes_t nx = 0; nx < nframes; ++nx) {
459 if (apply_gain_automation && _session.transport_rolling() && nframes > 0) {
460 _effective_gain = gab[nframes-1];
465 /* manual (scalar) gain */
469 Declicker::run (bufs, nframes, _gain, dg, _phase_invert);
472 } else if (_gain != 0 && (_phase_invert || _gain != 1.0)) {
474 /* no need to interpolate current gain value,
475 but its non-unity, so apply it. if the gain
476 is zero, do nothing because we'll ship silence
488 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
489 Sample* const sp = i->data(nframes);
490 apply_gain_to_buffer(sp,nframes,this_gain);
493 } else if (_gain == 0) {
494 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
502 /* actively recording, no monitoring required; leave buffers as-is to save CPU cycles */
506 /* ----------------------------------------------------------------------------------------------------
508 -------------------------------------------------------------------------------------------------- */
510 /* note that post_fader_work cannot be true unless with_redirects was also true, so don't test both */
512 if (post_fader_work) {
514 Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK);
516 if (mute_gain > 0 || !_mute_affects_post_fader) {
517 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
518 switch ((*i)->placement()) {
522 (*i)->run (bufs, nframes, offset);
527 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
528 switch ((*i)->placement()) {
532 (*i)->silence (nframes, offset);
540 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_control_outs) {
541 Declicker::run (bufs, nframes, mute_gain, dmg, _phase_invert);
543 mute_declick_applied = true;
546 /* ----------------------------------------------------------------------------------------------------
548 -------------------------------------------------------------------------------------------------- */
550 if ((_meter_point == MeterPostFader) && co) {
552 solo_audible = solo_gain > 0;
553 mute_audible = dmg > 0 || !_mute_affects_control_outs;
555 if ( // silent anyway
557 (_gain == 0 && !apply_gain_automation) ||
559 // muted by solo of another track
563 // muted by mute of this track
567 // recording but not s/w monitoring
569 (no_monitor && record_enabled() && (!_session.get_auto_input() || _session.actively_recording()))
573 co->silence (nframes, offset);
577 co->deliver_output_no_pan (bufs, nframes, offset);
581 /* ----------------------------------------------------------------------
583 ----------------------------------------------------------------------*/
585 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_main_outs) {
586 Declicker::run (bufs, nframes, mute_gain, dmg, _phase_invert);
588 mute_declick_applied = true;
591 /* ----------------------------------------------------------------------------------------------------
593 -------------------------------------------------------------------------------------------------- */
595 solo_audible = dsg > 0;
596 mute_audible = dmg > 0 || !_mute_affects_main_outs;
598 if (n_outputs().get(_default_type) == 0) {
602 } else if (no_monitor && record_enabled() && (!_session.get_auto_input() || _session.actively_recording())) {
604 IO::silence (nframes, offset);
608 if ( // silent anyway
610 (_gain == 0 && !apply_gain_automation) ||
612 // muted by solo of another track, but not using control outs for solo
614 (!solo_audible && (_session.solo_model() != Session::SoloBus)) ||
616 // muted by mute of this track
622 /* don't use Route::silence() here, because that causes
623 all outputs (sends, port inserts, etc. to be silent).
626 if (_meter_point == MeterPostFader) {
627 peak_meter().reset();
630 IO::silence (nframes, offset);
634 if (_session.transport_speed() > 1.5f || _session.transport_speed() < -1.5f) {
635 pan (bufs, nframes, offset, speed_quietning);
637 // cerr << _name << " panner state = " << _panner->automation_state() << endl;
638 if (!_panner->empty() &&
639 (_panner->automation_state() & Play ||
640 ((_panner->automation_state() & Touch) && !_panner->touching()))) {
641 pan_automated (bufs, start_frame, end_frame, nframes, offset);
643 pan (bufs, nframes, offset, 1.0);
650 /* ----------------------------------------------------------------------------------------------------
652 -------------------------------------------------------------------------------------------------- */
654 if (meter && (_meter_point == MeterPostFader)) {
655 // cerr << "meter post" << endl;
657 if ((_gain == 0 && !apply_gain_automation) || dmg == 0) {
660 _meter->run(output_buffers(), nframes, offset);
666 Route::n_process_buffers ()
668 return max (n_inputs(), redirect_max_outs);
672 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)
674 BufferSet& bufs = _session.get_scratch_buffers(n_process_buffers());
678 collect_input (bufs, nframes, offset);
680 #define meter_stream meter_first
683 _meter->run(bufs, nframes);
684 meter_stream = false;
689 process_output_buffers (bufs, start_frame, end_frame, nframes, offset, true, declick, meter_stream);
695 Route::set_phase_invert (bool yn, void *src)
697 if (_phase_invert != yn) {
700 // phase_invert_changed (src); /* EMIT SIGNAL */
704 Route::set_solo (bool yn, void *src)
710 if (_mix_group && src != _mix_group && _mix_group->is_active()) {
711 _mix_group->apply (&Route::set_solo, yn, _mix_group);
717 solo_changed (src); /* EMIT SIGNAL */
718 _solo_control.Changed (); /* EMIT SIGNAL */
723 Route::set_solo_mute (bool yn)
725 Glib::Mutex::Lock lm (declick_lock);
727 /* Called by Session in response to another Route being soloed.
730 desired_solo_gain = (yn?0.0:1.0);
734 Route::set_solo_safe (bool yn, void *src)
736 if (_solo_safe != yn) {
738 solo_safe_changed (src); /* EMIT SIGNAL */
743 Route::set_mute (bool yn, void *src)
746 if (_mix_group && src != _mix_group && _mix_group->is_active()) {
747 _mix_group->apply (&Route::set_mute, yn, _mix_group);
753 mute_changed (src); /* EMIT SIGNAL */
755 _mute_control.Changed (); /* EMIT SIGNAL */
757 Glib::Mutex::Lock lm (declick_lock);
758 desired_mute_gain = (yn?0.0f:1.0f);
763 Route::add_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
765 ChanCount old_rmo = redirect_max_outs;
767 if (!_session.engine().connected()) {
772 Glib::RWLock::WriterLock lm (redirect_lock);
774 boost::shared_ptr<PluginInsert> pi;
775 boost::shared_ptr<PortInsert> porti;
777 ChanCount potential_max_streams;
779 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(redirect)) != 0) {
782 if (pi->input_streams() == ChanCount::ZERO) {
783 /* generator plugin */
784 _have_internal_generator = true;
787 potential_max_streams = max(pi->input_streams(), pi->output_streams());
789 } else if ((porti = boost::dynamic_pointer_cast<PortInsert>(redirect)) != 0) {
791 /* force new port inserts to start out with an i/o configuration
792 that matches this route's i/o configuration.
794 the "inputs" for the port are supposed to match the output
797 the "outputs" of the route should match the inputs of this
798 route. XXX shouldn't they match the number of active signal
799 streams at the point of insertion?
803 porti->ensure_io (n_outputs ().get(DataType::AUDIO), n_inputs().get(DataType::AUDIO), false, this);
806 // Ensure peak vector sizes before the plugin is activated
807 _meter->setup(potential_max_streams);
809 _redirects.push_back (redirect);
811 if (_reset_plugin_counts (err_streams)) {
812 _redirects.pop_back ();
813 _reset_plugin_counts (0); // it worked before we tried to add it ...
817 redirect->activate ();
818 redirect->active_changed.connect (mem_fun (*this, &Route::redirect_active_proxy));
821 if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
826 redirects_changed (src); /* EMIT SIGNAL */
831 Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_streams)
833 ChanCount old_rmo = redirect_max_outs;
835 if (!_session.engine().connected()) {
840 Glib::RWLock::WriterLock lm (redirect_lock);
842 RedirectList::iterator existing_end = _redirects.end();
845 ChanCount potential_max_streams;
847 for (RedirectList::const_iterator i = others.begin(); i != others.end(); ++i) {
849 boost::shared_ptr<PluginInsert> pi;
851 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
854 ChanCount m = max(pi->input_streams(), pi->output_streams());
855 if (m > potential_max_streams)
856 potential_max_streams = m;
859 // Ensure peak vector sizes before the plugin is activated
860 _meter->setup(potential_max_streams);
862 _redirects.push_back (*i);
864 if (_reset_plugin_counts (err_streams)) {
866 _redirects.erase (existing_end, _redirects.end());
867 _reset_plugin_counts (0); // it worked before we tried to add it ...
872 (*i)->active_changed.connect (mem_fun (*this, &Route::redirect_active_proxy));
876 if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
880 redirects_changed (src); /* EMIT SIGNAL */
885 Route::clear_redirects (void *src)
887 ChanCount old_rmo = redirect_max_outs;
889 if (!_session.engine().connected()) {
894 Glib::RWLock::WriterLock lm (redirect_lock);
898 if (redirect_max_outs != old_rmo) {
902 redirect_max_outs.reset();
903 _have_internal_generator = false;
904 redirects_changed (src); /* EMIT SIGNAL */
908 Route::remove_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
910 ChanCount old_rmo = redirect_max_outs;
912 if (!_session.engine().connected()) {
916 redirect_max_outs.reset();
919 Glib::RWLock::WriterLock lm (redirect_lock);
920 RedirectList::iterator i;
921 bool removed = false;
923 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
924 if (*i == redirect) {
926 RedirectList::iterator tmp;
928 /* move along, see failure case for reset_plugin_counts()
929 where we may need to reinsert the redirect.
935 /* stop redirects that send signals to JACK ports
936 from causing noise as a result of no longer being
940 boost::shared_ptr<Send> send;
941 boost::shared_ptr<PortInsert> port_insert;
943 if ((send = boost::dynamic_pointer_cast<Send> (*i)) != 0) {
944 send->disconnect_inputs (this);
945 send->disconnect_outputs (this);
946 } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (*i)) != 0) {
947 port_insert->disconnect_inputs (this);
948 port_insert->disconnect_outputs (this);
951 _redirects.erase (i);
964 if (_reset_plugin_counts (err_streams)) {
965 /* get back to where we where */
966 _redirects.insert (i, redirect);
967 /* we know this will work, because it worked before :) */
968 _reset_plugin_counts (0);
974 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
975 boost::shared_ptr<PluginInsert> pi;
977 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
978 if (pi->is_generator()) {
984 _have_internal_generator = foo;
987 if (old_rmo != redirect_max_outs) {
991 redirects_changed (src); /* EMIT SIGNAL */
996 Route::reset_plugin_counts (uint32_t* lpc)
998 Glib::RWLock::WriterLock lm (redirect_lock);
999 return _reset_plugin_counts (lpc);
1004 Route::_reset_plugin_counts (uint32_t* err_streams)
1006 RedirectList::iterator r;
1009 map<Placement,list<InsertCount> > insert_map;
1010 jack_nframes_t initial_streams;
1012 redirect_max_outs.reset();
1016 /* divide inserts up by placement so we get the signal flow
1017 properly modelled. we need to do this because the _redirects
1018 list is not sorted by placement, and because other reasons may
1019 exist now or in the future for this separate treatment.
1022 for (r = _redirects.begin(); r != _redirects.end(); ++r) {
1024 boost::shared_ptr<Insert> insert;
1026 /* do this here in case we bomb out before we get to the end of
1030 redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs);
1032 if ((insert = boost::dynamic_pointer_cast<Insert>(*r)) != 0) {
1034 insert_map[insert->placement()].push_back (InsertCount (insert));
1036 /* reset plugin counts back to one for now so
1037 that we have a predictable, controlled
1038 state to try to configure.
1041 boost::shared_ptr<PluginInsert> pi;
1043 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(insert)) != 0) {
1047 } else if (boost::dynamic_pointer_cast<Send> (*r) != 0) {
1060 /* Now process each placement in order, checking to see if we
1061 can really do what has been requested.
1066 if (check_some_plugin_counts (insert_map[PreFader], n_inputs ().get(_default_type), err_streams)) {
1070 /* figure out the streams that will feed into PreFader */
1072 if (!insert_map[PreFader].empty()) {
1073 InsertCount& ic (insert_map[PreFader].back());
1074 initial_streams = ic.insert->compute_output_streams (ic.cnt);
1076 initial_streams = n_inputs ().get(_default_type);
1081 if (check_some_plugin_counts (insert_map[PostFader], initial_streams, err_streams)) {
1085 /* OK, everything can be set up correctly, so lets do it */
1087 apply_some_plugin_counts (insert_map[PreFader]);
1088 apply_some_plugin_counts (insert_map[PostFader]);
1090 /* recompute max outs of any redirect */
1094 redirect_max_outs.reset();
1095 RedirectList::iterator prev = _redirects.end();
1097 for (r = _redirects.begin(); r != _redirects.end(); prev = r, ++r) {
1098 boost::shared_ptr<Send> s;
1100 if ((s = boost::dynamic_pointer_cast<Send> (*r)) != 0) {
1101 if (r == _redirects.begin()) {
1102 s->expect_inputs (n_inputs());
1104 s->expect_inputs ((*prev)->output_streams());
1108 redirect_max_outs = max ((*r)->output_streams(), redirect_max_outs);
1117 Route::apply_some_plugin_counts (list<InsertCount>& iclist)
1119 list<InsertCount>::iterator i;
1121 for (i = iclist.begin(); i != iclist.end(); ++i) {
1123 if ((*i).insert->configure_io ((*i).cnt, (*i).in, (*i).out)) {
1126 /* make sure that however many we have, they are all active */
1127 (*i).insert->activate ();
1134 Route::check_some_plugin_counts (list<InsertCount>& iclist, int32_t required_inputs, uint32_t* err_streams)
1136 list<InsertCount>::iterator i;
1138 for (i = iclist.begin(); i != iclist.end(); ++i) {
1140 if (((*i).cnt = (*i).insert->can_support_input_configuration (required_inputs)) < 0) {
1142 *err_streams = required_inputs;
1147 (*i).in = required_inputs;
1148 (*i).out = (*i).insert->compute_output_streams ((*i).cnt);
1150 required_inputs = (*i).out;
1157 Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_streams)
1159 ChanCount old_rmo = redirect_max_outs;
1165 RedirectList to_be_deleted;
1168 Glib::RWLock::WriterLock lm (redirect_lock);
1169 RedirectList::iterator tmp;
1170 RedirectList the_copy;
1172 the_copy = _redirects;
1174 /* remove all relevant redirects */
1176 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ) {
1180 if ((*i)->placement() == placement) {
1181 to_be_deleted.push_back (*i);
1182 _redirects.erase (i);
1188 /* now copy the relevant ones from "other" */
1190 for (RedirectList::const_iterator i = other._redirects.begin(); i != other._redirects.end(); ++i) {
1191 if ((*i)->placement() == placement) {
1192 _redirects.push_back (Redirect::clone (*i));
1196 /* reset plugin stream handling */
1198 if (_reset_plugin_counts (err_streams)) {
1200 /* FAILED COPY ATTEMPT: we have to restore order */
1202 /* delete all cloned redirects */
1204 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ) {
1209 if ((*i)->placement() == placement) {
1210 _redirects.erase (i);
1216 /* restore the natural order */
1218 _redirects = the_copy;
1219 redirect_max_outs = old_rmo;
1221 /* we failed, even though things are OK again */
1227 /* SUCCESSFUL COPY ATTEMPT: delete the redirects we removed pre-copy */
1228 to_be_deleted.clear ();
1232 if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
1236 redirects_changed (this); /* EMIT SIGNAL */
1241 Route::all_redirects_flip ()
1243 Glib::RWLock::ReaderLock lm (redirect_lock);
1245 if (_redirects.empty()) {
1249 bool first_is_on = _redirects.front()->active();
1251 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1252 (*i)->set_active (!first_is_on, this);
1257 Route::all_redirects_active (bool state)
1259 Glib::RWLock::ReaderLock lm (redirect_lock);
1261 if (_redirects.empty()) {
1265 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1266 (*i)->set_active (state, this);
1270 struct RedirectSorter {
1271 bool operator() (boost::shared_ptr<const Redirect> a, boost::shared_ptr<const Redirect> b) {
1272 return a->sort_key() < b->sort_key();
1277 Route::sort_redirects (uint32_t* err_streams)
1280 RedirectSorter comparator;
1281 Glib::RWLock::WriterLock lm (redirect_lock);
1282 ChanCount old_rmo = redirect_max_outs;
1284 /* the sweet power of C++ ... */
1286 RedirectList as_it_was_before = _redirects;
1288 _redirects.sort (comparator);
1290 if (_reset_plugin_counts (err_streams)) {
1291 _redirects = as_it_was_before;
1292 redirect_max_outs = old_rmo;
1298 redirects_changed (this); /* EMIT SIGNAL */
1310 Route::get_template()
1312 return state(false);
1316 Route::state(bool full_state)
1318 XMLNode *node = new XMLNode("Route");
1320 RedirectList:: iterator i;
1324 snprintf (buf, sizeof (buf), "0x%x", _flags);
1325 node->add_property("flags", buf);
1328 node->add_property("default-type", _default_type.to_string());
1330 node->add_property("active", _active?"yes":"no");
1331 node->add_property("muted", _muted?"yes":"no");
1332 node->add_property("soloed", _soloed?"yes":"no");
1333 node->add_property("phase-invert", _phase_invert?"yes":"no");
1334 node->add_property("mute-affects-pre-fader", _mute_affects_pre_fader?"yes":"no");
1335 node->add_property("mute-affects-post-fader", _mute_affects_post_fader?"yes":"no");
1336 node->add_property("mute-affects-control-outs", _mute_affects_control_outs?"yes":"no");
1337 node->add_property("mute-affects-main-outs", _mute_affects_main_outs?"yes":"no");
1340 node->add_property("edit-group", _edit_group->name());
1343 node->add_property("mix-group", _mix_group->name());
1346 string order_string;
1347 OrderKeys::iterator x = order_keys.begin();
1349 while (x != order_keys.end()) {
1350 order_string += (*x).first;
1351 order_string += '=';
1352 snprintf (buf, sizeof(buf), "%ld", (*x).second);
1353 order_string += buf;
1357 if (x == order_keys.end()) {
1361 order_string += ':';
1363 node->add_property ("order-keys", order_string);
1365 node->add_child_nocopy (IO::state (full_state));
1367 if (_control_outs) {
1368 XMLNode* cnode = new XMLNode (X_("ControlOuts"));
1369 cnode->add_child_nocopy (_control_outs->state (full_state));
1370 node->add_child_nocopy (*cnode);
1373 if (_comment.length()) {
1374 XMLNode *cmt = node->add_child ("Comment");
1375 cmt->add_content (_comment);
1381 path = _session.snap_name();
1383 path += legalize_for_path (_name);
1384 path += ".automation";
1386 /* XXX we didn't ask for a state save, we asked for the current state.
1390 if (save_automation (path)) {
1391 error << _("Could not get state of route. Problem with save_automation") << endmsg;
1394 aevents = node->add_child ("Automation");
1395 aevents->add_property ("path", path);
1398 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
1399 node->add_child_nocopy((*i)->state (full_state));
1403 node->add_child_copy (*_extra_xml);
1410 Route::set_deferred_state ()
1413 XMLNodeConstIterator niter;
1415 if (!deferred_state) {
1419 nlist = deferred_state->children();
1421 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1422 add_redirect_from_xml (**niter);
1425 delete deferred_state;
1430 Route::add_redirect_from_xml (const XMLNode& node)
1432 const XMLProperty *prop;
1434 if (node.name() == "Send") {
1438 boost::shared_ptr<Send> send (new Send (_session, node));
1439 add_redirect (send, this);
1442 catch (failed_constructor &err) {
1443 error << _("Send construction failed") << endmsg;
1447 } else if (node.name() == "Insert") {
1450 if ((prop = node.property ("type")) != 0) {
1452 boost::shared_ptr<Insert> insert;
1454 if (prop->value() == "ladspa" || prop->value() == "Ladspa" || prop->value() == "vst") {
1456 insert.reset (new PluginInsert(_session, node));
1458 } else if (prop->value() == "port") {
1461 insert.reset (new PortInsert (_session, node));
1465 error << string_compose(_("unknown Insert type \"%1\"; ignored"), prop->value()) << endmsg;
1468 add_redirect (insert, this);
1471 error << _("Insert XML node has no type property") << endmsg;
1475 catch (failed_constructor &err) {
1476 warning << _("insert could not be created. Ignored.") << endmsg;
1483 Route::set_state (const XMLNode& node)
1486 XMLNodeConstIterator niter;
1488 XMLPropertyList plist;
1489 const XMLProperty *prop;
1491 if (node.name() != "Route"){
1492 error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
1496 if ((prop = node.property ("flags")) != 0) {
1498 sscanf (prop->value().c_str(), "0x%x", &x);
1504 if ((prop = node.property ("default-type")) != 0) {
1505 _default_type = DataType(prop->value());
1506 assert(_default_type != DataType::NIL);
1509 if ((prop = node.property ("phase-invert")) != 0) {
1510 set_phase_invert(prop->value()=="yes"?true:false, this);
1513 if ((prop = node.property ("active")) != 0) {
1514 set_active (prop->value() == "yes");
1517 if ((prop = node.property ("muted")) != 0) {
1518 bool yn = prop->value()=="yes"?true:false;
1520 /* force reset of mute status */
1524 mute_gain = desired_mute_gain;
1527 if ((prop = node.property ("soloed")) != 0) {
1528 bool yn = prop->value()=="yes"?true:false;
1530 /* force reset of solo status */
1533 set_solo (yn, this);
1534 solo_gain = desired_solo_gain;
1537 if ((prop = node.property ("mute-affects-pre-fader")) != 0) {
1538 _mute_affects_pre_fader = (prop->value()=="yes")?true:false;
1541 if ((prop = node.property ("mute-affects-post-fader")) != 0) {
1542 _mute_affects_post_fader = (prop->value()=="yes")?true:false;
1545 if ((prop = node.property ("mute-affects-control-outs")) != 0) {
1546 _mute_affects_control_outs = (prop->value()=="yes")?true:false;
1549 if ((prop = node.property ("mute-affects-main-outs")) != 0) {
1550 _mute_affects_main_outs = (prop->value()=="yes")?true:false;
1553 if ((prop = node.property ("edit-group")) != 0) {
1554 RouteGroup* edit_group = _session.edit_group_by_name(prop->value());
1555 if(edit_group == 0) {
1556 error << string_compose(_("Route %1: unknown edit group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
1558 set_edit_group(edit_group, this);
1562 if ((prop = node.property ("order-keys")) != 0) {
1566 string::size_type colon, equal;
1567 string remaining = prop->value();
1569 while (remaining.length()) {
1571 if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
1572 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1575 if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) {
1576 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1579 set_order_key (remaining.substr (0, equal), n);
1583 colon = remaining.find_first_of (':');
1585 if (colon != string::npos) {
1586 remaining = remaining.substr (colon+1);
1593 nlist = node.children();
1595 if (deferred_state) {
1596 delete deferred_state;
1599 deferred_state = new XMLNode("deferred state");
1601 /* set parent class properties before anything else */
1603 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1607 if (child->name() == IO::state_node_name) {
1609 IO::set_state (*child);
1614 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1618 if (child->name() == "Send") {
1621 if (!IO::ports_legal) {
1623 deferred_state->add_child_copy (*child);
1626 add_redirect_from_xml (*child);
1629 } else if (child->name() == "Insert") {
1631 if (!IO::ports_legal) {
1633 deferred_state->add_child_copy (*child);
1637 add_redirect_from_xml (*child);
1640 } else if (child->name() == "Automation") {
1642 XMLPropertyList plist;
1643 XMLPropertyConstIterator piter;
1646 plist = child->properties();
1647 for (piter = plist.begin(); piter != plist.end(); ++piter) {
1649 if (prop->name() == "path") {
1650 load_automation (prop->value());
1654 } else if (child->name() == "ControlOuts") {
1656 string coutname = _name;
1657 coutname += _("[control]");
1659 _control_outs = new IO (_session, coutname);
1660 _control_outs->set_state (**(child->children().begin()));
1662 } else if (child->name() == "Comment") {
1664 /* XXX this is a terrible API design in libxml++ */
1666 XMLNode *cmt = *(child->children().begin());
1667 _comment = cmt->content();
1669 } else if (child->name() == "extra") {
1670 _extra_xml = new XMLNode (*child);
1674 if ((prop = node.property ("mix-group")) != 0) {
1675 RouteGroup* mix_group = _session.mix_group_by_name(prop->value());
1676 if (mix_group == 0) {
1677 error << string_compose(_("Route %1: unknown mix group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
1679 set_mix_group(mix_group, this);
1687 Route::curve_reallocate ()
1689 // _gain_automation_curve.finish_resize ();
1690 // _pan_automation_curve.finish_resize ();
1694 Route::silence (jack_nframes_t nframes, jack_nframes_t offset)
1698 IO::silence (nframes, offset);
1700 if (_control_outs) {
1701 _control_outs->silence (nframes, offset);
1705 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
1708 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1709 boost::shared_ptr<PluginInsert> pi;
1710 if (!_active && (pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
1711 // skip plugins, they don't need anything when we're not active
1715 (*i)->silence (nframes, offset);
1718 if (nframes == _session.get_block_size() && offset == 0) {
1728 Route::set_control_outs (const vector<string>& ports)
1730 Glib::Mutex::Lock lm (control_outs_lock);
1731 vector<string>::const_iterator i;
1733 if (_control_outs) {
1734 delete _control_outs;
1738 if (ports.empty()) {
1742 string coutname = _name;
1743 coutname += _("[control]");
1745 _control_outs = new IO (_session, coutname);
1747 /* our control outs need as many outputs as we
1748 have outputs. we track the changes in ::output_change_handler().
1751 _control_outs->ensure_io (0, n_outputs().get(DataType::AUDIO), true, this);
1757 Route::set_edit_group (RouteGroup *eg, void *src)
1760 if (eg == _edit_group) {
1765 _edit_group->remove (this);
1768 if ((_edit_group = eg) != 0) {
1769 _edit_group->add (this);
1772 _session.set_dirty ();
1773 edit_group_changed (src); /* EMIT SIGNAL */
1777 Route::drop_edit_group (void *src)
1780 _session.set_dirty ();
1781 edit_group_changed (src); /* EMIT SIGNAL */
1785 Route::set_mix_group (RouteGroup *mg, void *src)
1788 if (mg == _mix_group) {
1793 _mix_group->remove (this);
1796 if ((_mix_group = mg) != 0) {
1797 _mix_group->add (this);
1800 _session.set_dirty ();
1801 mix_group_changed (src); /* EMIT SIGNAL */
1805 Route::drop_mix_group (void *src)
1808 _session.set_dirty ();
1809 mix_group_changed (src); /* EMIT SIGNAL */
1813 Route::set_comment (string cmt, void *src)
1816 comment_changed (src);
1817 _session.set_dirty ();
1821 Route::feeds (boost::shared_ptr<Route> other)
1826 uint32_t no = self.n_outputs().get_total();
1827 uint32_t ni = other->n_inputs ().get_total();
1829 for (i = 0; i < no; ++i) {
1830 for (j = 0; j < ni; ++j) {
1831 if (self.output(i)->connected_to (other->input(j)->name())) {
1837 /* check Redirects which may also interconnect Routes */
1839 for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); r++) {
1841 no = (*r)->n_outputs().get_total();
1843 for (i = 0; i < no; ++i) {
1844 for (j = 0; j < ni; ++j) {
1845 if ((*r)->output(i)->connected_to (other->input (j)->name())) {
1852 /* check for control room outputs which may also interconnect Routes */
1854 if (_control_outs) {
1856 no = _control_outs->n_outputs().get_total();
1858 for (i = 0; i < no; ++i) {
1859 for (j = 0; j < ni; ++j) {
1860 if (_control_outs->output(i)->connected_to (other->input (j)->name())) {
1871 Route::set_mute_config (mute_type t, bool onoff, void *src)
1875 _mute_affects_pre_fader = onoff;
1876 pre_fader_changed(src); /* EMIT SIGNAL */
1880 _mute_affects_post_fader = onoff;
1881 post_fader_changed(src); /* EMIT SIGNAL */
1885 _mute_affects_control_outs = onoff;
1886 control_outs_changed(src); /* EMIT SIGNAL */
1890 _mute_affects_main_outs = onoff;
1891 main_outs_changed(src); /* EMIT SIGNAL */
1897 Route::get_mute_config (mute_type t)
1903 onoff = _mute_affects_pre_fader;
1906 onoff = _mute_affects_post_fader;
1909 onoff = _mute_affects_control_outs;
1912 onoff = _mute_affects_main_outs;
1920 Route::set_active (bool yn)
1923 active_changed(); /* EMIT SIGNAL */
1927 Route::handle_transport_stopped (bool abort_ignored, bool did_locate, bool can_flush_redirects)
1929 jack_nframes_t now = _session.transport_frame();
1932 Glib::RWLock::ReaderLock lm (redirect_lock);
1935 automation_snapshot (now);
1938 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1940 if (Config->get_plugins_stop_with_transport() && can_flush_redirects) {
1941 (*i)->deactivate ();
1945 (*i)->transport_stopped (now);
1949 IO::transport_stopped (now);
1951 _roll_delay = _initial_delay;
1955 Route::get_memento() const
1957 void (Route::*pmf)(state_id_t) = &Route::set_state;
1958 return sigc::bind (mem_fun (*(const_cast<Route *>(this)), pmf), _current_state_id);
1962 Route::set_state (state_id_t id)
1968 Route::input_change_handler (IOChange change, void *ignored)
1970 if (change & ConfigurationChanged) {
1971 reset_plugin_counts (0);
1976 Route::output_change_handler (IOChange change, void *ignored)
1978 if (change & ConfigurationChanged) {
1979 if (_control_outs) {
1980 _control_outs->ensure_io (0, n_outputs().get(DataType::AUDIO), true, this);
1983 reset_plugin_counts (0);
1988 Route::pans_required () const
1990 if (n_outputs().get(DataType::AUDIO) < 2) {
1994 return max (n_inputs ().get(DataType::AUDIO), static_cast<size_t>(redirect_max_outs.get(DataType::AUDIO)));
1998 Route::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset,
1999 bool session_state_changing, bool can_record, bool rec_monitors_input)
2001 if (n_outputs().get_total() == 0) {
2005 if (session_state_changing || !_active) {
2006 silence (nframes, offset);
2010 apply_gain_automation = false;
2012 if (n_inputs().get_total()) {
2013 passthru (start_frame, end_frame, nframes, offset, 0, false);
2015 silence (nframes, offset);
2022 Route::check_initial_delay (jack_nframes_t nframes, jack_nframes_t& offset, jack_nframes_t& transport_frame)
2024 if (_roll_delay > nframes) {
2026 _roll_delay -= nframes;
2027 silence (nframes, offset);
2028 /* transport frame is not legal for caller to use */
2031 } else if (_roll_delay > 0) {
2033 nframes -= _roll_delay;
2035 silence (_roll_delay, offset);
2037 offset += _roll_delay;
2038 transport_frame += _roll_delay;
2047 Route::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset, int declick,
2048 bool can_record, bool rec_monitors_input)
2051 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
2053 // automation snapshot can also be called from the non-rt context
2054 // and it uses the redirect list, so we take the lock out here
2055 automation_snapshot (_session.transport_frame());
2059 if ((n_outputs().get_total() == 0 && _redirects.empty()) || n_inputs().get_total() == 0 || !_active) {
2060 silence (nframes, offset);
2064 jack_nframes_t unused = 0;
2066 if ((nframes = check_initial_delay (nframes, offset, unused)) == 0) {
2072 apply_gain_automation = false;
2075 Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK);
2077 if (am.locked() && _session.transport_rolling()) {
2079 if (gain_automation_playback()) {
2080 apply_gain_automation = _gain_automation_curve.rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes);
2085 passthru (start_frame, end_frame, nframes, offset, declick, false);
2091 Route::silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset,
2092 bool can_record, bool rec_monitors_input)
2094 silence (nframes, offset);
2099 Route::toggle_monitor_input ()
2101 for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
2102 i->request_monitor_input( ! i->monitoring_input());
2107 Route::has_external_redirects () const
2109 boost::shared_ptr<const PortInsert> pi;
2111 for (RedirectList::const_iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2112 if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*i)) != 0) {
2114 for (PortSet::const_iterator port = pi->outputs().begin();
2115 port != pi->outputs().end(); ++port) {
2117 string port_name = port->name();
2118 string client_name = port_name.substr (0, port_name.find(':'));
2120 /* only say "yes" if the redirect is actually in use */
2122 if (client_name != "ardour" && pi->active()) {
2133 Route::flush_redirects ()
2135 /* XXX shouldn't really try to take this lock, since
2136 this is called from the RT audio thread.
2139 Glib::RWLock::ReaderLock lm (redirect_lock);
2141 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2142 (*i)->deactivate ();
2148 Route::set_meter_point (MeterPoint p, void *src)
2150 if (_meter_point != p) {
2152 meter_change (src); /* EMIT SIGNAL */
2153 _session.set_dirty ();
2158 Route::update_total_latency ()
2162 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2163 if ((*i)->active ()) {
2164 _own_latency += (*i)->latency ();
2168 set_port_latency (_own_latency);
2170 /* this (virtual) function is used for pure Routes,
2171 not derived classes like AudioTrack. this means
2172 that the data processed here comes from an input
2173 port, not prerecorded material, and therefore we
2174 have to take into account any input latency.
2177 _own_latency += input_latency ();
2179 return _own_latency;
2183 Route::set_latency_delay (jack_nframes_t longest_session_latency)
2185 _initial_delay = longest_session_latency - _own_latency;
2187 if (_session.transport_stopped()) {
2188 _roll_delay = _initial_delay;
2193 Route::automation_snapshot (jack_nframes_t now)
2195 IO::automation_snapshot (now);
2197 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2198 (*i)->automation_snapshot (now);
2202 Route::ToggleControllable::ToggleControllable (Route& s, ToggleType tp)
2203 : route (s), type(tp)
2209 Route::ToggleControllable::set_value (float val)
2211 bool bval = ((val >= 0.5f) ? true: false);
2215 route.set_mute (bval, this);
2218 route.set_solo (bval, this);
2226 Route::ToggleControllable::get_value (void) const
2232 val = route.muted() ? 1.0f : 0.0f;
2235 val = route.soloed() ? 1.0f : 0.0f;
2245 Route::set_block_size (jack_nframes_t nframes)
2247 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2248 (*i)->set_block_size (nframes);
2253 Route::redirect_active_proxy (Redirect* ignored, void* ignored_src)
2255 _session.update_latency_compensation (false, false);
2259 Route::protect_automation ()
2261 switch (gain_automation_state()) {
2264 set_gain_automation_state (Off);
2270 switch (panner().automation_state ()) {
2273 panner().set_automation_state (Off);
2279 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2280 boost::shared_ptr<PluginInsert> pi;
2281 if ((pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
2282 pi->protect_automation ();
2288 Route::set_pending_declick (int declick)
2291 /* this call is not allowed to turn off a pending declick unless "force" is true */
2293 _pending_declick = declick;
2295 // cerr << _name << ": after setting to " << declick << " pending declick = " << _pending_declick << endl;
2297 _pending_declick = 0;