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>
27 #include <pbd/enumwriter.h>
29 #include <ardour/timestamps.h>
30 #include <ardour/audioengine.h>
31 #include <ardour/route.h>
32 #include <ardour/buffer.h>
33 #include <ardour/insert.h>
34 #include <ardour/send.h>
35 #include <ardour/session.h>
36 #include <ardour/utils.h>
37 #include <ardour/configuration.h>
38 #include <ardour/cycle_timer.h>
39 #include <ardour/route_group.h>
40 #include <ardour/port.h>
41 #include <ardour/audio_port.h>
42 #include <ardour/ladspa_plugin.h>
43 #include <ardour/panner.h>
44 #include <ardour/dB.h>
45 #include <ardour/mix.h>
46 #include <ardour/amp.h>
47 #include <ardour/meter.h>
48 #include <ardour/buffer_set.h>
52 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 (X_("solo"), *this, ToggleControllable::SoloControl),
62 _mute_control (X_("mute"), *this, ToggleControllable::MuteControl)
67 Route::Route (Session& sess, const XMLNode& node, DataType default_type)
68 : IO (sess, *node.child ("IO"), default_type),
69 _solo_control (X_("solo"), *this, ToggleControllable::SoloControl),
70 _mute_control (X_("mute"), *this, ToggleControllable::MuteControl)
73 _set_state (node, false);
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 clear_redirects (this);
120 delete _control_outs;
125 Route::set_remote_control_id (uint32_t id)
127 if (id != _remote_control_id) {
128 _remote_control_id = id;
129 RemoteControlIDChanged ();
134 Route::remote_control_id() const
136 return _remote_control_id;
140 Route::order_key (string name) const
142 OrderKeys::const_iterator i;
144 if ((i = order_keys.find (name)) == order_keys.end()) {
152 Route::set_order_key (string name, long n)
154 order_keys[name] = n;
155 _session.set_dirty ();
159 Route::inc_gain (gain_t fraction, void *src)
161 IO::inc_gain (fraction, src);
165 Route::set_gain (gain_t val, void *src)
167 if (src != 0 && _mix_group && src != _mix_group && _mix_group->is_active()) {
169 if (_mix_group->is_relative()) {
172 gain_t usable_gain = gain();
173 if (usable_gain < 0.000001f) {
174 usable_gain=0.000001f;
178 if (delta < 0.000001f) {
182 delta -= usable_gain;
184 if (delta == 0.0f) return;
186 gain_t factor = delta / usable_gain;
189 factor = _mix_group->get_max_factor(factor);
190 if (factor == 0.0f) {
195 factor = _mix_group->get_min_factor(factor);
196 if (factor == 0.0f) {
202 _mix_group->apply (&Route::inc_gain, factor, _mix_group);
206 _mix_group->apply (&Route::set_gain, val, _mix_group);
216 IO::set_gain (val, src);
219 /** Process this route for one (sub) cycle (process thread)
221 * @param bufs Scratch buffers to use for the signal path
222 * @param start_frame Initial transport frame
223 * @param end_frame Final transport frame
224 * @param nframes Number of frames to output (to ports)
225 * @param offset Output offset (of port buffers, for split cycles)
227 * Note that (end_frame - start_frame) may not be equal to nframes when the
228 * transport speed isn't 1.0 (eg varispeed).
231 Route::process_output_buffers (BufferSet& bufs,
232 nframes_t start_frame, nframes_t end_frame,
233 nframes_t nframes, nframes_t offset, bool with_redirects, int declick,
236 // This is definitely very audio-only for now
237 assert(_default_type == DataType::AUDIO);
239 RedirectList::iterator i;
240 bool post_fader_work = false;
241 bool mute_declick_applied = false;
247 gain_t* gab = _session.gain_automation_buffer();
249 switch (Config->get_monitoring_model()) {
250 case HardwareMonitoring:
251 case ExternalMonitoring:
258 declick = _pending_declick;
261 Glib::Mutex::Lock cm (control_outs_lock, Glib::TRY_LOCK);
271 Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK);
274 dmg = desired_mute_gain;
275 dsg = desired_solo_gain;
284 /* ----------------------------------------------------------------------------------------------------
285 GLOBAL DECLICK (for transport changes etc.)
286 -------------------------------------------------------------------------------------------------- */
289 Amp::run (bufs, nframes, 0.0, 1.0, false);
290 _pending_declick = 0;
291 } else if (declick < 0) {
292 Amp::run (bufs, nframes, 1.0, 0.0, false);
293 _pending_declick = 0;
296 /* no global declick */
298 if (solo_gain != dsg) {
299 Amp::run (bufs, nframes, solo_gain, dsg, false);
305 /* ----------------------------------------------------------------------------------------------------
306 INPUT METERING & MONITORING
307 -------------------------------------------------------------------------------------------------- */
309 if (meter && (_meter_point == MeterInput)) {
310 _meter->run(bufs, nframes);
313 if (!_soloed && _mute_affects_pre_fader && (mute_gain != dmg)) {
314 Amp::run (bufs, nframes, mute_gain, dmg, false);
316 mute_declick_applied = true;
319 if ((_meter_point == MeterInput) && co) {
321 solo_audible = dsg > 0;
322 mute_audible = dmg > 0;// || !_mute_affects_pre_fader;
324 if ( // muted by solo of another track
328 // muted by mute of this track
332 // rec-enabled but not s/w monitoring
334 // TODO: this is probably wrong
336 (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording()))
340 co->silence (nframes, offset);
344 co->deliver_output (bufs, start_frame, end_frame, nframes, offset);
349 /* ---------------------------------------------------------------------------------------------------
351 -------------------------------------------------------------------------------------------------- */
353 /* FIXME: Somewhere in these loops is where bufs.count() should go from n_inputs() to redirect_max_outs()
354 * (if they differ). Something explicit needs to be done here to make sure the list of redirects will
355 * give us what we need (possibly by inserting transparent 'translators' into the list to make it work) */
357 if (with_redirects) {
358 Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK);
360 if (mute_gain > 0 || !_mute_affects_pre_fader) {
361 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
362 switch ((*i)->placement()) {
364 (*i)->run (bufs, start_frame, end_frame, nframes, offset);
367 post_fader_work = true;
372 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
373 switch ((*i)->placement()) {
375 (*i)->silence (nframes, offset);
378 post_fader_work = true;
386 // FIXME: for now, just hope the redirects list did what it was supposed to
387 bufs.set_count(n_process_buffers());
390 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_post_fader) {
391 Amp::run (bufs, nframes, mute_gain, dmg, false);
393 mute_declick_applied = true;
396 /* ----------------------------------------------------------------------------------------------------
397 PRE-FADER METERING & MONITORING
398 -------------------------------------------------------------------------------------------------- */
400 if (meter && (_meter_point == MeterPreFader)) {
401 _meter->run(bufs, nframes);
405 if ((_meter_point == MeterPreFader) && co) {
407 solo_audible = dsg > 0;
408 mute_audible = dmg > 0 || !_mute_affects_pre_fader;
410 if ( // muted by solo of another track
414 // muted by mute of this track
418 // rec-enabled but not s/w monitoring
420 (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording()))
424 co->silence (nframes, offset);
428 co->deliver_output (bufs, start_frame, end_frame, nframes, offset);
433 /* ----------------------------------------------------------------------------------------------------
435 -------------------------------------------------------------------------------------------------- */
437 /* if not recording or recording and requiring any monitor signal, then apply gain */
439 if ( // not recording
441 !(record_enabled() && _session.actively_recording()) ||
445 // h/w monitoring not in use
447 (!Config->get_monitoring_model() == HardwareMonitoring &&
449 // AND software monitoring required
451 Config->get_monitoring_model() == SoftwareMonitoring)) {
453 if (apply_gain_automation) {
456 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
457 Sample* const sp = i->data(nframes);
459 for (nframes_t nx = 0; nx < nframes; ++nx) {
464 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
465 Sample* const sp = i->data(nframes);
467 for (nframes_t nx = 0; nx < nframes; ++nx) {
473 if (apply_gain_automation && _session.transport_rolling() && nframes > 0) {
474 _effective_gain = gab[nframes-1];
479 /* manual (scalar) gain */
483 Amp::run (bufs, nframes, _gain, dg, _phase_invert);
486 } else if (_gain != 0 && (_phase_invert || _gain != 1.0)) {
488 /* no need to interpolate current gain value,
489 but its non-unity, so apply it. if the gain
490 is zero, do nothing because we'll ship silence
502 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
503 Sample* const sp = i->data(nframes);
504 Session::apply_gain_to_buffer(sp,nframes,this_gain);
507 } else if (_gain == 0) {
508 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
516 /* actively recording, no monitoring required; leave buffers as-is to save CPU cycles */
520 /* ----------------------------------------------------------------------------------------------------
522 -------------------------------------------------------------------------------------------------- */
524 /* note that post_fader_work cannot be true unless with_redirects was also true, so don't test both */
526 if (post_fader_work) {
528 Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK);
530 if (mute_gain > 0 || !_mute_affects_post_fader) {
531 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
532 switch ((*i)->placement()) {
536 (*i)->run (bufs, start_frame, end_frame, nframes, offset);
541 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
542 switch ((*i)->placement()) {
546 (*i)->silence (nframes, offset);
554 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_control_outs) {
555 Amp::run (bufs, nframes, mute_gain, dmg, false);
557 mute_declick_applied = true;
560 /* ----------------------------------------------------------------------------------------------------
562 -------------------------------------------------------------------------------------------------- */
564 if ((_meter_point == MeterPostFader) && co) {
566 solo_audible = solo_gain > 0;
567 mute_audible = dmg > 0 || !_mute_affects_control_outs;
569 if ( // silent anyway
571 (_gain == 0 && !apply_gain_automation) ||
573 // muted by solo of another track
577 // muted by mute of this track
581 // recording but not s/w monitoring
583 (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording()))
587 co->silence (nframes, offset);
591 co->deliver_output (bufs, start_frame, end_frame, nframes, offset);
595 /* ----------------------------------------------------------------------
597 ----------------------------------------------------------------------*/
599 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_main_outs) {
600 Amp::run (bufs, nframes, mute_gain, dmg, false);
602 mute_declick_applied = true;
605 /* ----------------------------------------------------------------------------------------------------
607 -------------------------------------------------------------------------------------------------- */
609 solo_audible = dsg > 0;
610 mute_audible = dmg > 0 || !_mute_affects_main_outs;
612 if (n_outputs().get(_default_type) == 0) {
616 } else if (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording())) {
618 IO::silence (nframes, offset);
622 if ( // silent anyway
624 (_gain == 0 && !apply_gain_automation) ||
626 // muted by solo of another track, but not using control outs for solo
628 (!solo_audible && (Config->get_solo_model() != SoloBus)) ||
630 // muted by mute of this track
636 /* don't use Route::silence() here, because that causes
637 all outputs (sends, port inserts, etc. to be silent).
640 if (_meter_point == MeterPostFader) {
641 peak_meter().reset();
644 IO::silence (nframes, offset);
648 deliver_output(bufs, start_frame, end_frame, nframes, offset);
654 /* ----------------------------------------------------------------------------------------------------
656 -------------------------------------------------------------------------------------------------- */
658 if (meter && (_meter_point == MeterPostFader)) {
659 if ((_gain == 0 && !apply_gain_automation) || dmg == 0) {
662 _meter->run(output_buffers(), nframes, offset);
668 Route::n_process_buffers ()
670 return max (n_inputs(), redirect_max_outs);
674 Route::passthru (nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset, int declick, bool meter_first)
676 BufferSet& bufs = _session.get_scratch_buffers(n_process_buffers());
680 collect_input (bufs, nframes, offset);
682 #define meter_stream meter_first
685 _meter->run(bufs, nframes);
686 meter_stream = false;
691 process_output_buffers (bufs, start_frame, end_frame, nframes, offset, true, declick, meter_stream);
697 Route::passthru_silence (jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset, int declick, bool meter)
699 process_output_buffers (_session.get_silent_buffers (n_process_buffers()), start_frame, end_frame, nframes, offset, true, declick, meter);
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 ChanCount 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 redirect->set_default_type(_default_type);
778 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(redirect)) != 0) {
781 if (pi->input_streams() == ChanCount::ZERO) {
782 /* generator plugin */
783 _have_internal_generator = true;
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?
798 // FIXME: (yes, they should)
800 porti->ensure_io (n_outputs (), n_inputs(), false, this);
803 // Ensure peak vector sizes before the plugin is activated
804 ChanCount potential_max_streams = max(redirect->input_streams(), redirect->output_streams());
805 _meter->setup(potential_max_streams);
807 _redirects.push_back (redirect);
809 if (_reset_plugin_counts (err_streams)) {
810 _redirects.pop_back ();
811 _reset_plugin_counts (0); // it worked before we tried to add it ...
815 redirect->activate ();
816 redirect->active_changed.connect (mem_fun (*this, &Route::redirect_active_proxy));
819 if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
824 redirects_changed (src); /* EMIT SIGNAL */
829 Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_streams)
831 ChanCount old_rmo = redirect_max_outs;
833 if (!_session.engine().connected()) {
838 Glib::RWLock::WriterLock lm (redirect_lock);
840 RedirectList::iterator existing_end = _redirects.end();
843 ChanCount potential_max_streams;
845 for (RedirectList::const_iterator i = others.begin(); i != others.end(); ++i) {
847 boost::shared_ptr<PluginInsert> pi;
849 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
852 ChanCount m = max(pi->input_streams(), pi->output_streams());
853 if (m > potential_max_streams)
854 potential_max_streams = m;
857 // Ensure peak vector sizes before the plugin is activated
858 _meter->setup(potential_max_streams);
860 _redirects.push_back (*i);
862 if (_reset_plugin_counts (err_streams)) {
864 _redirects.erase (existing_end, _redirects.end());
865 _reset_plugin_counts (0); // it worked before we tried to add it ...
870 (*i)->active_changed.connect (mem_fun (*this, &Route::redirect_active_proxy));
874 if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
878 redirects_changed (src); /* EMIT SIGNAL */
883 Route::clear_redirects (void *src)
885 ChanCount old_rmo = redirect_max_outs;
887 if (!_session.engine().connected()) {
892 Glib::RWLock::WriterLock lm (redirect_lock);
893 RedirectList::iterator i;
894 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
895 (*i)->drop_references ();
900 if (redirect_max_outs != old_rmo) {
904 redirect_max_outs.reset();
905 _have_internal_generator = false;
906 redirects_changed (src); /* EMIT SIGNAL */
910 Route::remove_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
912 ChanCount old_rmo = redirect_max_outs;
914 if (!_session.engine().connected()) {
918 redirect_max_outs.reset();
921 Glib::RWLock::WriterLock lm (redirect_lock);
922 RedirectList::iterator i;
923 bool removed = false;
925 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
926 if (*i == redirect) {
928 RedirectList::iterator tmp;
930 /* move along, see failure case for reset_plugin_counts()
931 where we may need to reinsert the redirect.
937 /* stop redirects that send signals to JACK ports
938 from causing noise as a result of no longer being
942 boost::shared_ptr<Send> send;
943 boost::shared_ptr<PortInsert> port_insert;
945 if ((send = boost::dynamic_pointer_cast<Send> (*i)) != 0) {
946 send->disconnect_inputs (this);
947 send->disconnect_outputs (this);
948 } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (*i)) != 0) {
949 port_insert->disconnect_inputs (this);
950 port_insert->disconnect_outputs (this);
953 _redirects.erase (i);
966 if (_reset_plugin_counts (err_streams)) {
967 /* get back to where we where */
968 _redirects.insert (i, redirect);
969 /* we know this will work, because it worked before :) */
970 _reset_plugin_counts (0);
976 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
977 boost::shared_ptr<PluginInsert> pi;
979 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
980 if (pi->is_generator()) {
986 _have_internal_generator = foo;
989 if (old_rmo != redirect_max_outs) {
993 redirect->drop_references ();
995 redirects_changed (src); /* EMIT SIGNAL */
1000 Route::reset_plugin_counts (uint32_t* lpc)
1002 Glib::RWLock::WriterLock lm (redirect_lock);
1003 return _reset_plugin_counts (lpc);
1008 Route::_reset_plugin_counts (uint32_t* err_streams)
1010 RedirectList::iterator r;
1013 map<Placement,list<InsertCount> > insert_map;
1014 nframes_t initial_streams;
1016 redirect_max_outs.reset();
1020 /* divide inserts up by placement so we get the signal flow
1021 properly modelled. we need to do this because the _redirects
1022 list is not sorted by placement, and because other reasons may
1023 exist now or in the future for this separate treatment.
1026 for (r = _redirects.begin(); r != _redirects.end(); ++r) {
1028 boost::shared_ptr<Insert> insert;
1030 /* do this here in case we bomb out before we get to the end of
1034 redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs);
1036 if ((insert = boost::dynamic_pointer_cast<Insert>(*r)) != 0) {
1038 insert_map[insert->placement()].push_back (InsertCount (insert));
1040 /* reset plugin counts back to one for now so
1041 that we have a predictable, controlled
1042 state to try to configure.
1045 boost::shared_ptr<PluginInsert> pi;
1047 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(insert)) != 0) {
1051 } else if (boost::dynamic_pointer_cast<Send> (*r) != 0) {
1064 /* Now process each placement in order, checking to see if we
1065 can really do what has been requested.
1070 if (check_some_plugin_counts (insert_map[PreFader], n_inputs ().get(_default_type), err_streams)) {
1074 /* figure out the streams that will feed into PreFader */
1076 if (!insert_map[PreFader].empty()) {
1077 InsertCount& ic (insert_map[PreFader].back());
1078 initial_streams = ic.insert->compute_output_streams (ic.cnt);
1080 initial_streams = n_inputs ().get(_default_type);
1085 if (check_some_plugin_counts (insert_map[PostFader], initial_streams, err_streams)) {
1089 /* OK, everything can be set up correctly, so lets do it */
1091 apply_some_plugin_counts (insert_map[PreFader]);
1092 apply_some_plugin_counts (insert_map[PostFader]);
1094 /* recompute max outs of any redirect */
1098 redirect_max_outs.reset();
1099 RedirectList::iterator prev = _redirects.end();
1101 for (r = _redirects.begin(); r != _redirects.end(); prev = r, ++r) {
1102 boost::shared_ptr<Send> s;
1104 if ((s = boost::dynamic_pointer_cast<Send> (*r)) != 0) {
1105 if (r == _redirects.begin()) {
1106 s->expect_inputs (n_inputs());
1108 s->expect_inputs ((*prev)->output_streams());
1112 redirect_max_outs = max ((*r)->output_streams(), redirect_max_outs);
1121 Route::apply_some_plugin_counts (list<InsertCount>& iclist)
1123 list<InsertCount>::iterator i;
1125 for (i = iclist.begin(); i != iclist.end(); ++i) {
1127 if ((*i).insert->configure_io ((*i).cnt, (*i).in, (*i).out)) {
1130 /* make sure that however many we have, they are all active */
1131 (*i).insert->activate ();
1138 Route::check_some_plugin_counts (list<InsertCount>& iclist, int32_t required_inputs, uint32_t* err_streams)
1140 list<InsertCount>::iterator i;
1142 for (i = iclist.begin(); i != iclist.end(); ++i) {
1144 if (((*i).cnt = (*i).insert->can_support_input_configuration (required_inputs)) < 0) {
1146 *err_streams = required_inputs;
1151 (*i).in = required_inputs;
1152 (*i).out = (*i).insert->compute_output_streams ((*i).cnt);
1154 required_inputs = (*i).out;
1161 Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_streams)
1163 ChanCount old_rmo = redirect_max_outs;
1169 RedirectList to_be_deleted;
1172 Glib::RWLock::WriterLock lm (redirect_lock);
1173 RedirectList::iterator tmp;
1174 RedirectList the_copy;
1176 the_copy = _redirects;
1178 /* remove all relevant redirects */
1180 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ) {
1184 if ((*i)->placement() == placement) {
1185 to_be_deleted.push_back (*i);
1186 _redirects.erase (i);
1192 /* now copy the relevant ones from "other" */
1194 for (RedirectList::const_iterator i = other._redirects.begin(); i != other._redirects.end(); ++i) {
1195 if ((*i)->placement() == placement) {
1196 _redirects.push_back (Redirect::clone (*i));
1200 /* reset plugin stream handling */
1202 if (_reset_plugin_counts (err_streams)) {
1204 /* FAILED COPY ATTEMPT: we have to restore order */
1206 /* delete all cloned redirects */
1208 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ) {
1213 if ((*i)->placement() == placement) {
1214 _redirects.erase (i);
1220 /* restore the natural order */
1222 _redirects = the_copy;
1223 redirect_max_outs = old_rmo;
1225 /* we failed, even though things are OK again */
1231 /* SUCCESSFUL COPY ATTEMPT: delete the redirects we removed pre-copy */
1232 to_be_deleted.clear ();
1236 if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
1240 redirects_changed (this); /* EMIT SIGNAL */
1245 Route::all_redirects_flip ()
1247 Glib::RWLock::ReaderLock lm (redirect_lock);
1249 if (_redirects.empty()) {
1253 bool first_is_on = _redirects.front()->active();
1255 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1256 (*i)->set_active (!first_is_on, this);
1261 Route::all_redirects_active (bool state)
1263 Glib::RWLock::ReaderLock lm (redirect_lock);
1265 if (_redirects.empty()) {
1269 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1270 (*i)->set_active (state, this);
1274 struct RedirectSorter {
1275 bool operator() (boost::shared_ptr<const Redirect> a, boost::shared_ptr<const Redirect> b) {
1276 return a->sort_key() < b->sort_key();
1281 Route::sort_redirects (uint32_t* err_streams)
1284 RedirectSorter comparator;
1285 Glib::RWLock::WriterLock lm (redirect_lock);
1286 ChanCount old_rmo = redirect_max_outs;
1288 /* the sweet power of C++ ... */
1290 RedirectList as_it_was_before = _redirects;
1292 _redirects.sort (comparator);
1294 if (_reset_plugin_counts (err_streams)) {
1295 _redirects = as_it_was_before;
1296 redirect_max_outs = old_rmo;
1302 redirects_changed (this); /* EMIT SIGNAL */
1314 Route::get_template()
1316 return state(false);
1320 Route::state(bool full_state)
1322 XMLNode *node = new XMLNode("Route");
1323 RedirectList:: iterator i;
1327 node->add_property("flags", enum_2_string (_flags));
1330 node->add_property("default-type", _default_type.to_string());
1332 node->add_property("active", _active?"yes":"no");
1333 node->add_property("muted", _muted?"yes":"no");
1334 node->add_property("soloed", _soloed?"yes":"no");
1335 node->add_property("phase-invert", _phase_invert?"yes":"no");
1336 node->add_property("mute-affects-pre-fader", _mute_affects_pre_fader?"yes":"no");
1337 node->add_property("mute-affects-post-fader", _mute_affects_post_fader?"yes":"no");
1338 node->add_property("mute-affects-control-outs", _mute_affects_control_outs?"yes":"no");
1339 node->add_property("mute-affects-main-outs", _mute_affects_main_outs?"yes":"no");
1342 node->add_property("edit-group", _edit_group->name());
1345 node->add_property("mix-group", _mix_group->name());
1348 string order_string;
1349 OrderKeys::iterator x = order_keys.begin();
1351 while (x != order_keys.end()) {
1352 order_string += (*x).first;
1353 order_string += '=';
1354 snprintf (buf, sizeof(buf), "%ld", (*x).second);
1355 order_string += buf;
1359 if (x == order_keys.end()) {
1363 order_string += ':';
1365 node->add_property ("order-keys", order_string);
1367 node->add_child_nocopy (IO::state (full_state));
1368 node->add_child_nocopy (_solo_control.get_state ());
1369 node->add_child_nocopy (_mute_control.get_state ());
1371 if (_control_outs) {
1372 XMLNode* cnode = new XMLNode (X_("ControlOuts"));
1373 cnode->add_child_nocopy (_control_outs->state (full_state));
1374 node->add_child_nocopy (*cnode);
1377 if (_comment.length()) {
1378 XMLNode *cmt = node->add_child ("Comment");
1379 cmt->add_content (_comment);
1382 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
1383 node->add_child_nocopy((*i)->state (full_state));
1387 node->add_child_copy (*_extra_xml);
1394 Route::set_deferred_state ()
1397 XMLNodeConstIterator niter;
1399 if (!deferred_state) {
1403 nlist = deferred_state->children();
1405 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1406 add_redirect_from_xml (**niter);
1409 delete deferred_state;
1414 Route::add_redirect_from_xml (const XMLNode& node)
1416 const XMLProperty *prop;
1418 if (node.name() == "Send") {
1422 boost::shared_ptr<Send> send (new Send (_session, node));
1423 add_redirect (send, this);
1426 catch (failed_constructor &err) {
1427 error << _("Send construction failed") << endmsg;
1431 } else if (node.name() == "Insert") {
1434 if ((prop = node.property ("type")) != 0) {
1436 boost::shared_ptr<Insert> insert;
1438 if (prop->value() == "ladspa" || prop->value() == "Ladspa" || prop->value() == "vst") {
1440 insert.reset (new PluginInsert(_session, node));
1442 } else if (prop->value() == "port") {
1445 insert.reset (new PortInsert (_session, node));
1449 error << string_compose(_("unknown Insert type \"%1\"; ignored"), prop->value()) << endmsg;
1452 add_redirect (insert, this);
1455 error << _("Insert XML node has no type property") << endmsg;
1459 catch (failed_constructor &err) {
1460 warning << _("insert could not be created. Ignored.") << endmsg;
1467 Route::set_state (const XMLNode& node)
1469 return _set_state (node, true);
1473 Route::_set_state (const XMLNode& node, bool call_base)
1476 XMLNodeConstIterator niter;
1478 XMLPropertyList plist;
1479 const XMLProperty *prop;
1481 if (node.name() != "Route"){
1482 error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
1486 if ((prop = node.property (X_("flags"))) != 0) {
1487 _flags = Flag (string_2_enum (prop->value(), _flags));
1492 if ((prop = node.property (X_("default-type"))) != 0) {
1493 _default_type = DataType(prop->value());
1494 assert(_default_type != DataType::NIL);
1497 if ((prop = node.property (X_("phase-invert"))) != 0) {
1498 set_phase_invert(prop->value()=="yes"?true:false, this);
1501 if ((prop = node.property (X_("active"))) != 0) {
1502 set_active (prop->value() == "yes");
1505 if ((prop = node.property (X_("muted"))) != 0) {
1506 bool yn = prop->value()=="yes"?true:false;
1508 /* force reset of mute status */
1512 mute_gain = desired_mute_gain;
1515 if ((prop = node.property (X_("soloed"))) != 0) {
1516 bool yn = prop->value()=="yes"?true:false;
1518 /* force reset of solo status */
1521 set_solo (yn, this);
1522 solo_gain = desired_solo_gain;
1525 if ((prop = node.property (X_("mute-affects-pre-fader"))) != 0) {
1526 _mute_affects_pre_fader = (prop->value()=="yes")?true:false;
1529 if ((prop = node.property (X_("mute-affects-post-fader"))) != 0) {
1530 _mute_affects_post_fader = (prop->value()=="yes")?true:false;
1533 if ((prop = node.property (X_("mute-affects-control-outs"))) != 0) {
1534 _mute_affects_control_outs = (prop->value()=="yes")?true:false;
1537 if ((prop = node.property (X_("mute-affects-main-outs"))) != 0) {
1538 _mute_affects_main_outs = (prop->value()=="yes")?true:false;
1541 if ((prop = node.property (X_("edit-group"))) != 0) {
1542 RouteGroup* edit_group = _session.edit_group_by_name(prop->value());
1543 if(edit_group == 0) {
1544 error << string_compose(_("Route %1: unknown edit group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
1546 set_edit_group(edit_group, this);
1550 if ((prop = node.property (X_("order-keys"))) != 0) {
1554 string::size_type colon, equal;
1555 string remaining = prop->value();
1557 while (remaining.length()) {
1559 if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
1560 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1563 if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) {
1564 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1567 set_order_key (remaining.substr (0, equal), n);
1571 colon = remaining.find_first_of (':');
1573 if (colon != string::npos) {
1574 remaining = remaining.substr (colon+1);
1581 nlist = node.children();
1583 if (deferred_state) {
1584 delete deferred_state;
1587 deferred_state = new XMLNode(X_("deferred state"));
1589 /* set parent class properties before anything else */
1591 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1595 if (child->name() == IO::state_node_name && call_base) {
1597 IO::set_state (*child);
1602 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1606 if (child->name() == X_("Send")) {
1609 if (!IO::ports_legal) {
1611 deferred_state->add_child_copy (*child);
1614 add_redirect_from_xml (*child);
1617 } else if (child->name() == X_("Insert")) {
1619 if (!IO::ports_legal) {
1621 deferred_state->add_child_copy (*child);
1625 add_redirect_from_xml (*child);
1628 } else if (child->name() == X_("Automation")) {
1630 if ((prop = child->property (X_("path"))) != 0) {
1631 load_automation (prop->value());
1634 } else if (child->name() == X_("ControlOuts")) {
1636 string coutname = _name;
1637 coutname += _("[control]");
1639 _control_outs = new IO (_session, coutname);
1640 _control_outs->set_state (**(child->children().begin()));
1642 } else if (child->name() == X_("Comment")) {
1644 /* XXX this is a terrible API design in libxml++ */
1646 XMLNode *cmt = *(child->children().begin());
1647 _comment = cmt->content();
1649 } else if (child->name() == X_("extra")) {
1650 _extra_xml = new XMLNode (*child);
1651 } else if (child->name() == X_("solo")) {
1652 _solo_control.set_state (*child);
1653 _session.add_controllable (&_solo_control);
1654 } else if (child->name() == X_("mute")) {
1655 _mute_control.set_state (*child);
1656 _session.add_controllable (&_mute_control);
1660 if ((prop = node.property (X_("mix-group"))) != 0) {
1661 RouteGroup* mix_group = _session.mix_group_by_name(prop->value());
1662 if (mix_group == 0) {
1663 error << string_compose(_("Route %1: unknown mix group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
1665 set_mix_group(mix_group, this);
1673 Route::curve_reallocate ()
1675 // _gain_automation_curve.finish_resize ();
1676 // _pan_automation_curve.finish_resize ();
1680 Route::silence (nframes_t nframes, nframes_t offset)
1684 IO::silence (nframes, offset);
1686 if (_control_outs) {
1687 _control_outs->silence (nframes, offset);
1691 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
1694 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1695 boost::shared_ptr<PluginInsert> pi;
1696 if (!_active && (pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
1697 // skip plugins, they don't need anything when we're not active
1701 (*i)->silence (nframes, offset);
1704 if (nframes == _session.get_block_size() && offset == 0) {
1714 Route::set_control_outs (const vector<string>& ports)
1716 Glib::Mutex::Lock lm (control_outs_lock);
1717 vector<string>::const_iterator i;
1719 if (_control_outs) {
1720 delete _control_outs;
1724 if (ports.empty()) {
1728 string coutname = _name;
1729 coutname += _("[control]");
1731 _control_outs = new IO (_session, coutname);
1733 /* our control outs need as many outputs as we
1734 have audio outputs. we track the changes in ::output_change_handler().
1737 _control_outs->ensure_io (ChanCount::ZERO, ChanCount(DataType::AUDIO, n_outputs().get(DataType::AUDIO)), true, this);
1743 Route::set_edit_group (RouteGroup *eg, void *src)
1746 if (eg == _edit_group) {
1751 _edit_group->remove (this);
1754 if ((_edit_group = eg) != 0) {
1755 _edit_group->add (this);
1758 _session.set_dirty ();
1759 edit_group_changed (src); /* EMIT SIGNAL */
1763 Route::drop_edit_group (void *src)
1766 _session.set_dirty ();
1767 edit_group_changed (src); /* EMIT SIGNAL */
1771 Route::set_mix_group (RouteGroup *mg, void *src)
1774 if (mg == _mix_group) {
1779 _mix_group->remove (this);
1782 if ((_mix_group = mg) != 0) {
1783 _mix_group->add (this);
1786 _session.set_dirty ();
1787 mix_group_changed (src); /* EMIT SIGNAL */
1791 Route::drop_mix_group (void *src)
1794 _session.set_dirty ();
1795 mix_group_changed (src); /* EMIT SIGNAL */
1799 Route::set_comment (string cmt, void *src)
1802 comment_changed (src);
1803 _session.set_dirty ();
1807 Route::feeds (boost::shared_ptr<Route> other)
1812 uint32_t no = self.n_outputs().get_total();
1813 uint32_t ni = other->n_inputs ().get_total();
1815 for (i = 0; i < no; ++i) {
1816 for (j = 0; j < ni; ++j) {
1817 if (self.output(i)->connected_to (other->input(j)->name())) {
1823 /* check Redirects which may also interconnect Routes */
1825 for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); r++) {
1827 no = (*r)->n_outputs().get_total();
1829 for (i = 0; i < no; ++i) {
1830 for (j = 0; j < ni; ++j) {
1831 if ((*r)->output(i)->connected_to (other->input (j)->name())) {
1838 /* check for control room outputs which may also interconnect Routes */
1840 if (_control_outs) {
1842 no = _control_outs->n_outputs().get_total();
1844 for (i = 0; i < no; ++i) {
1845 for (j = 0; j < ni; ++j) {
1846 if (_control_outs->output(i)->connected_to (other->input (j)->name())) {
1857 Route::set_mute_config (mute_type t, bool onoff, void *src)
1861 _mute_affects_pre_fader = onoff;
1862 pre_fader_changed(src); /* EMIT SIGNAL */
1866 _mute_affects_post_fader = onoff;
1867 post_fader_changed(src); /* EMIT SIGNAL */
1871 _mute_affects_control_outs = onoff;
1872 control_outs_changed(src); /* EMIT SIGNAL */
1876 _mute_affects_main_outs = onoff;
1877 main_outs_changed(src); /* EMIT SIGNAL */
1883 Route::get_mute_config (mute_type t)
1889 onoff = _mute_affects_pre_fader;
1892 onoff = _mute_affects_post_fader;
1895 onoff = _mute_affects_control_outs;
1898 onoff = _mute_affects_main_outs;
1906 Route::set_active (bool yn)
1909 active_changed(); /* EMIT SIGNAL */
1913 Route::handle_transport_stopped (bool abort_ignored, bool did_locate, bool can_flush_redirects)
1915 nframes_t now = _session.transport_frame();
1918 Glib::RWLock::ReaderLock lm (redirect_lock);
1921 automation_snapshot (now);
1924 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1926 if (Config->get_plugins_stop_with_transport() && can_flush_redirects) {
1927 (*i)->deactivate ();
1931 (*i)->transport_stopped (now);
1935 IO::transport_stopped (now);
1937 _roll_delay = _initial_delay;
1941 Route::input_change_handler (IOChange change, void *ignored)
1943 if (change & ConfigurationChanged) {
1944 reset_plugin_counts (0);
1949 Route::output_change_handler (IOChange change, void *ignored)
1951 if (change & ConfigurationChanged) {
1952 if (_control_outs) {
1953 _control_outs->ensure_io (ChanCount::ZERO, ChanCount(DataType::AUDIO, n_outputs().get(DataType::AUDIO)), true, this);
1956 reset_plugin_counts (0);
1961 Route::pans_required () const
1963 if (n_outputs().get(DataType::AUDIO) < 2) {
1967 return max (n_inputs ().get(DataType::AUDIO), static_cast<size_t>(redirect_max_outs.get(DataType::AUDIO)));
1971 Route::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset,
1972 bool session_state_changing, bool can_record, bool rec_monitors_input)
1974 if (n_outputs().get_total() == 0) {
1978 if (session_state_changing || !_active) {
1979 silence (nframes, offset);
1983 apply_gain_automation = false;
1985 if (n_inputs().get_total()) {
1986 passthru (start_frame, end_frame, nframes, offset, 0, false);
1988 silence (nframes, offset);
1995 Route::check_initial_delay (nframes_t nframes, nframes_t& offset, nframes_t& transport_frame)
1997 if (_roll_delay > nframes) {
1999 _roll_delay -= nframes;
2000 silence (nframes, offset);
2001 /* transport frame is not legal for caller to use */
2004 } else if (_roll_delay > 0) {
2006 nframes -= _roll_delay;
2008 silence (_roll_delay, offset);
2010 offset += _roll_delay;
2011 transport_frame += _roll_delay;
2020 Route::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, int declick,
2021 bool can_record, bool rec_monitors_input)
2024 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
2026 // automation snapshot can also be called from the non-rt context
2027 // and it uses the redirect list, so we take the lock out here
2028 automation_snapshot (_session.transport_frame());
2032 if ((n_outputs().get_total() == 0 && _redirects.empty()) || n_inputs().get_total() == 0 || !_active) {
2033 silence (nframes, offset);
2037 nframes_t unused = 0;
2039 if ((nframes = check_initial_delay (nframes, offset, unused)) == 0) {
2045 apply_gain_automation = false;
2048 Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK);
2050 if (am.locked() && _session.transport_rolling()) {
2052 if (gain_automation_playback()) {
2053 apply_gain_automation = _gain_automation_curve.rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes);
2058 passthru (start_frame, end_frame, nframes, offset, declick, false);
2064 Route::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset,
2065 bool can_record, bool rec_monitors_input)
2067 silence (nframes, offset);
2072 Route::toggle_monitor_input ()
2074 for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
2075 i->ensure_monitor_input( ! i->monitoring_input());
2080 Route::has_external_redirects () const
2082 boost::shared_ptr<const PortInsert> pi;
2084 for (RedirectList::const_iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2085 if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*i)) != 0) {
2087 for (PortSet::const_iterator port = pi->outputs().begin();
2088 port != pi->outputs().end(); ++port) {
2090 string port_name = port->name();
2091 string client_name = port_name.substr (0, port_name.find(':'));
2093 /* only say "yes" if the redirect is actually in use */
2095 if (client_name != "ardour" && pi->active()) {
2106 Route::flush_redirects ()
2108 /* XXX shouldn't really try to take this lock, since
2109 this is called from the RT audio thread.
2112 Glib::RWLock::ReaderLock lm (redirect_lock);
2114 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2115 (*i)->deactivate ();
2121 Route::set_meter_point (MeterPoint p, void *src)
2123 if (_meter_point != p) {
2125 meter_change (src); /* EMIT SIGNAL */
2126 _session.set_dirty ();
2131 Route::update_total_latency ()
2135 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2136 if ((*i)->active ()) {
2137 _own_latency += (*i)->latency ();
2141 set_port_latency (_own_latency);
2143 /* this (virtual) function is used for pure Routes,
2144 not derived classes like AudioTrack. this means
2145 that the data processed here comes from an input
2146 port, not prerecorded material, and therefore we
2147 have to take into account any input latency.
2150 _own_latency += input_latency ();
2152 return _own_latency;
2156 Route::set_latency_delay (nframes_t longest_session_latency)
2158 _initial_delay = longest_session_latency - _own_latency;
2160 if (_session.transport_stopped()) {
2161 _roll_delay = _initial_delay;
2166 Route::automation_snapshot (nframes_t now)
2168 IO::automation_snapshot (now);
2170 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2171 (*i)->automation_snapshot (now);
2175 Route::ToggleControllable::ToggleControllable (std::string name, Route& s, ToggleType tp)
2176 : Controllable (name), route (s), type(tp)
2182 Route::ToggleControllable::set_value (float val)
2184 bool bval = ((val >= 0.5f) ? true: false);
2188 route.set_mute (bval, this);
2191 route.set_solo (bval, this);
2199 Route::ToggleControllable::get_value (void) const
2205 val = route.muted() ? 1.0f : 0.0f;
2208 val = route.soloed() ? 1.0f : 0.0f;
2218 Route::set_block_size (nframes_t nframes)
2220 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2221 (*i)->set_block_size (nframes);
2226 Route::redirect_active_proxy (Redirect* ignored, void* ignored_src)
2228 _session.update_latency_compensation (false, false);
2232 Route::protect_automation ()
2234 switch (gain_automation_state()) {
2237 set_gain_automation_state (Off);
2243 switch (panner().automation_state ()) {
2246 panner().set_automation_state (Off);
2252 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2253 boost::shared_ptr<PluginInsert> pi;
2254 if ((pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
2255 pi->protect_automation ();
2261 Route::set_pending_declick (int declick)
2264 /* this call is not allowed to turn off a pending declick unless "force" is true */
2266 _pending_declick = declick;
2268 // cerr << _name << ": after setting to " << declick << " pending declick = " << _pending_declick << endl;
2270 _pending_declick = 0;