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 "pbd/xml++.h"
26 #include "pbd/enumwriter.h"
27 #include "pbd/memento_command.h"
28 #include "pbd/stacktrace.h"
29 #include "pbd/convert.h"
31 #include "evoral/Curve.hpp"
33 #include "ardour/amp.h"
34 #include "ardour/audio_port.h"
35 #include "ardour/audioengine.h"
36 #include "ardour/buffer.h"
37 #include "ardour/buffer_set.h"
38 #include "ardour/configuration.h"
39 #include "ardour/cycle_timer.h"
40 #include "ardour/debug.h"
41 #include "ardour/delivery.h"
42 #include "ardour/dB.h"
43 #include "ardour/internal_send.h"
44 #include "ardour/internal_return.h"
45 #include "ardour/ladspa_plugin.h"
46 #include "ardour/meter.h"
47 #include "ardour/mix.h"
48 #include "ardour/panner.h"
49 #include "ardour/plugin_insert.h"
50 #include "ardour/port.h"
51 #include "ardour/port_insert.h"
52 #include "ardour/processor.h"
53 #include "ardour/profile.h"
54 #include "ardour/route.h"
55 #include "ardour/route_group.h"
56 #include "ardour/send.h"
57 #include "ardour/session.h"
58 #include "ardour/timestamps.h"
59 #include "ardour/utils.h"
64 using namespace ARDOUR;
67 uint32_t Route::order_key_cnt = 0;
68 PBD::Signal1<void,string const&> Route::SyncOrderKeys;
69 PBD::Signal0<void> Route::RemoteControlIDChange;
71 Route::Route (Session& sess, string name, Flag flg, DataType default_type)
72 : SessionObject (sess, name)
73 , AutomatableControls (sess)
75 , _solo_control (new SoloControllable (X_("solo"), *this))
76 , _mute_control (new MuteControllable (X_("mute"), *this))
77 , _mute_master (new MuteMaster (sess, name))
78 , _default_type (default_type)
83 /* add standard processors other than amp (added by ::init()) */
85 _meter.reset (new PeakMeter (_session));
86 _meter->set_display_to_user (false);
87 add_processor (_meter, PostFader);
89 if (_flags & ControlOut) {
90 /* where we listen to tracks */
91 _intreturn.reset (new InternalReturn (_session));
92 add_processor (_intreturn, PreFader);
95 _main_outs.reset (new Delivery (_session, _output, _mute_master, _name, Delivery::Main));
96 add_processor (_main_outs, PostFader);
98 /* now that we have _meter, its safe to connect to this */
100 Metering::Meter.connect_same_thread (*this, (boost::bind (&Route::meter, this)));
103 Route::Route (Session& sess, const XMLNode& node, DataType default_type)
104 : SessionObject (sess, "toBeReset")
105 , AutomatableControls (sess)
106 , _solo_control (new SoloControllable (X_("solo"), *this))
107 , _mute_control (new MuteControllable (X_("mute"), *this))
108 , _mute_master (new MuteMaster (sess, "toBeReset"))
109 , _default_type (default_type)
113 _set_state (node, Stateful::loading_state_version, false);
115 /* now that we have _meter, its safe to connect to this */
117 Metering::Meter.connect_same_thread (*this, (boost::bind (&Route::meter, this)));
124 _soloed_by_others = 0;
128 processor_max_streams.reset();
130 order_keys[N_("signal")] = order_key_cnt++;
132 _meter_point = MeterPostFader;
135 _have_internal_generator = false;
136 _declickable = false;
137 _pending_declick = true;
138 _remote_control_id = 0;
139 _in_configure_processors = false;
140 _mute_points = MuteMaster::AllPoints;
143 _denormal_protection = false;
145 /* add standard controls */
147 _solo_control->set_flags (Controllable::Flag (_solo_control->flags() | Controllable::Toggle));
148 _mute_control->set_flags (Controllable::Flag (_solo_control->flags() | Controllable::Toggle));
150 add_control (_solo_control);
151 add_control (_mute_control);
153 /* input and output objects */
155 _input.reset (new IO (_session, _name, IO::Input, _default_type));
156 _output.reset (new IO (_session, _name, IO::Output, _default_type));
158 _input->changed.connect_same_thread (*this, boost::bind (&Route::input_change_handler, this, _1, _2));
159 _output->changed.connect_same_thread (*this, boost::bind (&Route::output_change_handler, this, _1, _2));
161 /* add amp processor */
163 _amp.reset (new Amp (_session, _mute_master));
164 add_processor (_amp, PostFader);
169 DEBUG_TRACE (DEBUG::Destruction, string_compose ("route %1 destructor\n", _name));
171 /* do this early so that we don't get incoming signals as we are going through destruction
176 /* don't use clear_processors here, as it depends on the session which may
177 be half-destroyed by now
180 Glib::RWLock::WriterLock lm (_processor_lock);
181 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
182 (*i)->drop_references ();
185 _processors.clear ();
189 Route::set_remote_control_id (uint32_t id, bool notify_class_listeners)
191 if (id != _remote_control_id) {
192 _remote_control_id = id;
193 RemoteControlIDChanged ();
194 if (notify_class_listeners) {
195 RemoteControlIDChange ();
201 Route::remote_control_id() const
203 return _remote_control_id;
207 Route::order_key (std::string const & name) const
209 OrderKeys::const_iterator i = order_keys.find (name);
210 if (i == order_keys.end()) {
218 Route::set_order_key (std::string const & name, long n)
220 order_keys[name] = n;
222 if (Config->get_sync_all_route_ordering()) {
223 for (OrderKeys::iterator x = order_keys.begin(); x != order_keys.end(); ++x) {
228 _session.set_dirty ();
231 /** Set all order keys to be the same as that for `base', if such a key
232 * exists in this route.
233 * @param base Base key.
236 Route::sync_order_keys (std::string const & base)
238 if (order_keys.empty()) {
242 OrderKeys::iterator i;
245 if ((i = order_keys.find (base)) == order_keys.end()) {
246 /* key doesn't exist, use the first existing key (during session initialization) */
247 i = order_keys.begin();
251 /* key exists - use it and reset all others (actually, itself included) */
253 i = order_keys.begin();
256 for (; i != order_keys.end(); ++i) {
262 Route::ensure_track_or_route_name(string name, Session &session)
264 string newname = name;
266 while (session.route_by_name (newname) != NULL) {
267 newname = bump_name_once (newname);
275 Route::inc_gain (gain_t fraction, void *src)
277 _amp->inc_gain (fraction, src);
281 Route::set_gain (gain_t val, void *src)
283 if (src != 0 && _route_group && src != _route_group && _route_group->active_property (RouteGroup::Gain)) {
285 if (_route_group->is_relative()) {
287 gain_t usable_gain = _amp->gain();
288 if (usable_gain < 0.000001f) {
289 usable_gain = 0.000001f;
293 if (delta < 0.000001f) {
297 delta -= usable_gain;
302 gain_t factor = delta / usable_gain;
305 factor = _route_group->get_max_factor(factor);
306 if (factor == 0.0f) {
307 _amp->gain_control()->Changed(); /* EMIT SIGNAL */
311 factor = _route_group->get_min_factor(factor);
312 if (factor == 0.0f) {
313 _amp->gain_control()->Changed(); /* EMIT SIGNAL */
318 _route_group->apply (&Route::inc_gain, factor, _route_group);
322 _route_group->apply (&Route::set_gain, val, _route_group);
328 if (val == _amp->gain()) {
332 _amp->set_gain (val, src);
335 /** Process this route for one (sub) cycle (process thread)
337 * @param bufs Scratch buffers to use for the signal path
338 * @param start_frame Initial transport frame
339 * @param end_frame Final transport frame
340 * @param nframes Number of frames to output (to ports)
342 * Note that (end_frame - start_frame) may not be equal to nframes when the
343 * transport speed isn't 1.0 (eg varispeed).
346 Route::process_output_buffers (BufferSet& bufs,
347 sframes_t start_frame, sframes_t end_frame, nframes_t nframes,
348 bool /*with_processors*/, int declick)
352 bufs.is_silent (false);
354 switch (Config->get_monitoring_model()) {
355 case HardwareMonitoring:
356 case ExternalMonitoring:
357 monitor = !record_enabled() || (_session.config.get_auto_input() && !_session.actively_recording());
364 declick = _pending_declick;
367 /* figure out if we're going to use gain automation */
368 _amp->setup_gain_automation (start_frame, end_frame, nframes);
371 /* tell main outs what to do about monitoring */
372 _main_outs->no_outs_cuz_we_no_monitor (!monitor);
375 /* -------------------------------------------------------------------------------------------
376 GLOBAL DECLICK (for transport changes etc.)
377 ----------------------------------------------------------------------------------------- */
380 Amp::apply_gain (bufs, nframes, 0.0, 1.0);
381 } else if (declick < 0) {
382 Amp::apply_gain (bufs, nframes, 1.0, 0.0);
385 _pending_declick = 0;
387 /* -------------------------------------------------------------------------------------------
388 DENORMAL CONTROL/PHASE INVERT
389 ----------------------------------------------------------------------------------------- */
395 if (_denormal_protection || Config->get_denormal_protection()) {
397 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i, ++chn) {
398 Sample* const sp = i->data();
400 if (_phase_invert & chn) {
401 for (nframes_t nx = 0; nx < nframes; ++nx) {
406 for (nframes_t nx = 0; nx < nframes; ++nx) {
414 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i, ++chn) {
415 Sample* const sp = i->data();
417 if (_phase_invert & chn) {
418 for (nframes_t nx = 0; nx < nframes; ++nx) {
427 if (_denormal_protection || Config->get_denormal_protection()) {
429 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
430 Sample* const sp = i->data();
431 for (nframes_t nx = 0; nx < nframes; ++nx) {
439 /* -------------------------------------------------------------------------------------------
441 ----------------------------------------------------------------------------------------- */
443 Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
446 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
448 if (bufs.count() != (*i)->input_streams()) {
449 cerr << _name << " bufs = " << bufs.count()
450 << " input for " << (*i)->name() << " = " << (*i)->input_streams()
453 assert (bufs.count() == (*i)->input_streams());
455 (*i)->run (bufs, start_frame, end_frame, nframes, *i != _processors.back());
456 bufs.set_count ((*i)->output_streams());
462 Route::n_process_buffers ()
464 return max (_input->n_ports(), processor_max_streams);
468 Route::passthru (sframes_t start_frame, sframes_t end_frame, nframes_t nframes, int declick)
470 BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers());
474 assert (bufs.available() >= _input->n_ports());
476 if (_input->n_ports() == ChanCount::ZERO) {
480 bufs.set_count (_input->n_ports());
482 if (is_control() && _session.listening()) {
484 /* control/monitor bus ignores input ports when something is
485 feeding the listen "stream". data will "arrive" into the
486 route from the intreturn processor element.
489 bufs.silence (nframes, 0);
493 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
495 BufferSet::iterator o = bufs.begin(*t);
496 PortSet& ports (_input->ports());
498 for (PortSet::iterator i = ports.begin(*t); i != ports.end(*t); ++i, ++o) {
499 o->read_from (i->get_buffer(nframes), nframes);
504 write_out_of_band_data (bufs, start_frame, end_frame, nframes);
505 process_output_buffers (bufs, start_frame, end_frame, nframes, true, declick);
509 Route::passthru_silence (sframes_t start_frame, sframes_t end_frame, nframes_t nframes, int declick)
511 BufferSet& bufs (_session.get_silent_buffers (n_process_buffers()));
512 bufs.set_count (_input->n_ports());
513 write_out_of_band_data (bufs, start_frame, end_frame, nframes);
514 process_output_buffers (bufs, start_frame, end_frame, nframes, true, declick);
518 Route::set_listen (bool yn, void* src)
521 if (yn != _control_outs->active()) {
523 _control_outs->activate ();
525 _control_outs->deactivate ();
528 listen_changed (src); /* EMIT SIGNAL */
534 Route::listening () const
537 return _control_outs->active ();
544 Route::set_solo_safe (bool yn, void *src)
546 if (_solo_safe != yn) {
548 solo_safe_changed (src);
553 Route::solo_safe() const
559 Route::set_solo (bool yn, void *src)
565 if (_route_group && src != _route_group && _route_group->active_property (RouteGroup::Solo)) {
566 _route_group->apply (&Route::set_solo, yn, _route_group);
570 if (self_soloed() != yn) {
572 set_delivery_solo ();
573 solo_changed (src); /* EMIT SIGNAL */
574 _solo_control->Changed (); /* EMIT SIGNAL */
579 Route::set_self_solo (bool yn)
585 Route::mod_solo_by_others (int32_t delta)
588 if (_soloed_by_others >= (uint32_t) delta) {
589 _soloed_by_others += delta;
591 _soloed_by_others = 0;
594 _soloed_by_others += delta;
597 set_delivery_solo ();
601 Route::set_delivery_solo ()
603 /* tell all delivery processors what the solo situation is, so that they keep
604 delivering even though Session::soloing() is true and they were not
608 Glib::RWLock::ReaderLock rm (_processor_lock);
609 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
610 boost::shared_ptr<Delivery> d;
612 if ((d = boost::dynamic_pointer_cast<Delivery> (*i)) != 0) {
613 d->set_solo_level (soloed ());
614 d->set_solo_isolated (solo_isolated());
620 Route::set_solo_isolated (bool yn, void *src)
622 if (is_master() || is_control() || is_hidden()) {
626 if (_route_group && src != _route_group && _route_group->active_property (RouteGroup::Solo)) {
627 _route_group->apply (&Route::set_solo_isolated, yn, _route_group);
631 /* forward propagate solo-isolate status to everything fed by this route, but not those via sends only */
633 boost::shared_ptr<RouteList> routes = _session.get_routes ();
634 for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
636 bool does_feed = feeds (*i, &sends_only);
638 if (does_feed && !sends_only) {
639 (*i)->set_solo_isolated (yn, (*i)->route_group());
643 bool changed = false;
646 if (_solo_isolated == 0) {
651 changed = (_solo_isolated == 1);
652 if (_solo_isolated > 0) {
658 set_delivery_solo ();
659 solo_isolated_changed (src);
664 Route::solo_isolated () const
666 return _solo_isolated > 0;
670 Route::set_mute_points (MuteMaster::MutePoint mp)
673 mute_points_changed (); /* EMIT SIGNAL */
675 if (_mute_master->muted()) {
676 _mute_master->mute_at (_mute_points);
677 mute_changed (this); /* EMIT SIGNAL */
682 Route::set_mute (bool yn, void *src)
684 if (_route_group && src != _route_group && _route_group->active_property (RouteGroup::Mute)) {
685 _route_group->apply (&Route::set_mute, yn, _route_group);
691 _mute_master->mute_at (_mute_points);
693 _mute_master->clear_mute ();
696 mute_changed (src); /* EMIT SIGNAL */
703 return _mute_master->muted ();
708 dump_processors(const string& name, const list<boost::shared_ptr<Processor> >& procs)
710 cerr << name << " {" << endl;
711 for (list<boost::shared_ptr<Processor> >::const_iterator p = procs.begin();
712 p != procs.end(); ++p) {
713 cerr << "\t" << (*p)->name() << " ID = " << (*p)->id() << endl;
720 Route::add_processor (boost::shared_ptr<Processor> processor, Placement placement, ProcessorStreams* err)
722 ProcessorList::iterator loc;
724 /* XXX this is not thread safe - we don't hold the lock across determining the iter
725 to add before and actually doing the insertion. dammit.
728 if (placement == PreFader) {
729 /* generic pre-fader: insert immediately before the amp */
730 loc = find (_processors.begin(), _processors.end(), _amp);
732 /* generic post-fader: insert right before the main outs */
733 loc = find (_processors.begin(), _processors.end(), _main_outs);
736 return add_processor (processor, loc, err);
740 /** Add a processor to the route.
741 * If @a iter is not NULL, it must point to an iterator in _processors and the new
742 * processor will be inserted immediately before this location. Otherwise,
743 * @a position is used.
746 Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::iterator iter, ProcessorStreams* err)
748 ChanCount old_pms = processor_max_streams;
750 if (!_session.engine().connected() || !processor) {
755 Glib::RWLock::WriterLock lm (_processor_lock);
757 boost::shared_ptr<PluginInsert> pi;
758 boost::shared_ptr<PortInsert> porti;
760 ProcessorList::iterator loc = find(_processors.begin(), _processors.end(), processor);
762 if (processor == _amp || processor == _meter || processor == _main_outs) {
763 // Ensure only one of these are in the list at any time
764 if (loc != _processors.end()) {
765 if (iter == loc) { // Already in place, do nothing
767 } else { // New position given, relocate
768 _processors.erase (loc);
773 if (loc != _processors.end()) {
774 cerr << "ERROR: Processor added to route twice!" << endl;
781 _processors.insert (loc, processor);
783 // Set up processor list channels. This will set processor->[input|output]_streams(),
784 // configure redirect ports properly, etc.
786 if (configure_processors_unlocked (err)) {
787 ProcessorList::iterator ploc = loc;
789 _processors.erase(ploc);
790 configure_processors_unlocked (0); // it worked before we tried to add it ...
791 cerr << "configure failed\n";
795 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(processor)) != 0) {
797 if (pi->natural_input_streams() == ChanCount::ZERO) {
798 /* generator plugin */
799 _have_internal_generator = true;
804 if (_control_outs != processor) {
805 // XXX: do we want to emit the signal here ? change call order.
806 processor->activate ();
809 processor->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false, false));
811 _output->set_user_latency (0);
814 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
820 Route::add_processor_from_xml (const XMLNode& node, ProcessorList::iterator iter)
822 const XMLProperty *prop;
824 if (node.name() != "Processor") {
829 if ((prop = node.property ("type")) != 0) {
831 boost::shared_ptr<Processor> processor;
833 if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
834 prop->value() == "lv2" ||
835 prop->value() == "vst" ||
836 prop->value() == "audiounit") {
838 processor.reset (new PluginInsert(_session, node));
840 } else if (prop->value() == "port") {
842 processor.reset (new PortInsert (_session, _mute_master, node));
844 } else if (prop->value() == "send") {
846 processor.reset (new Send (_session, _mute_master, node));
848 } else if (prop->value() == "meter") {
851 if (_meter->set_state (node, Stateful::loading_state_version)) {
858 _meter.reset (new PeakMeter (_session, node));
859 _meter->set_display_to_user (_meter_point == MeterCustom);
862 } else if (prop->value() == "amp") {
864 /* amp always exists */
867 if (processor->set_state (node, Stateful::loading_state_version)) {
870 /* never any reason to add it */
874 } else if (prop->value() == "intsend") {
876 processor.reset (new InternalSend (_session, _mute_master, node));
878 } else if (prop->value() == "intreturn") {
881 if (_intreturn->set_state (node, Stateful::loading_state_version)) {
887 _intreturn.reset (new InternalReturn (_session, node));
888 processor = _intreturn;
890 } else if (prop->value() == "main-outs") {
893 if (_main_outs->set_state (node, Stateful::loading_state_version)) {
900 _main_outs.reset (new Delivery (_session, _output, _mute_master, node));
901 processor = _main_outs;
904 error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
908 if (iter == _processors.end() && processor->display_to_user() && !_processors.empty()) {
909 /* check for invisible processors stacked at the end and leave them there */
910 ProcessorList::iterator p;
911 p = _processors.end();
913 while (!(*p)->display_to_user() && p != _processors.begin()) {
920 return (add_processor (processor, iter) == 0);
923 error << _("Processor XML node has no type property") << endmsg;
928 catch (failed_constructor &err) {
929 warning << _("processor could not be created. Ignored.") << endmsg;
936 Route::add_processor_from_xml_2X (const XMLNode& node, int version, ProcessorList::iterator iter)
938 const XMLProperty *prop;
941 boost::shared_ptr<Processor> processor;
943 if (node.name() == "Insert") {
945 if ((prop = node.property ("type")) != 0) {
947 if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
948 prop->value() == "lv2" ||
949 prop->value() == "vst" ||
950 prop->value() == "audiounit") {
952 processor.reset (new PluginInsert (_session, node));
956 processor.reset (new PortInsert (_session, _mute_master, node));
961 } else if (node.name() == "Send") {
963 processor.reset (new Send (_session, _mute_master, node, version));
967 error << string_compose(_("unknown Processor type \"%1\"; ignored"), node.name()) << endmsg;
971 if (iter == _processors.end() && processor->display_to_user() && !_processors.empty()) {
972 /* check for invisible processors stacked at the end and leave them there */
973 ProcessorList::iterator p;
974 p = _processors.end();
976 while (!(*p)->display_to_user() && p != _processors.begin()) {
983 return (add_processor (processor, iter) == 0);
986 catch (failed_constructor &err) {
987 warning << _("processor could not be created. Ignored.") << endmsg;
993 Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor> before, ProcessorStreams* err)
995 ProcessorList::iterator loc;
998 loc = find(_processors.begin(), _processors.end(), before);
1000 /* nothing specified - at end but before main outs */
1001 loc = find (_processors.begin(), _processors.end(), _main_outs);
1004 return add_processors (others, loc, err);
1008 Route::add_processors (const ProcessorList& others, ProcessorList::iterator iter, ProcessorStreams* err)
1010 /* NOTE: this is intended to be used ONLY when copying
1011 processors from another Route. Hence the subtle
1012 differences between this and ::add_processor()
1015 ChanCount old_pms = processor_max_streams;
1017 if (!_session.engine().connected()) {
1021 if (others.empty()) {
1026 Glib::RWLock::WriterLock lm (_processor_lock);
1028 ChanCount potential_max_streams = ChanCount::max (_input->n_ports(), _output->n_ports());
1030 for (ProcessorList::const_iterator i = others.begin(); i != others.end(); ++i) {
1032 // Ensure meter only appears in the list once
1034 ProcessorList::iterator m = find(_processors.begin(), _processors.end(), *i);
1035 if (m != _processors.end()) {
1036 _processors.erase(m);
1040 boost::shared_ptr<PluginInsert> pi;
1042 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
1045 ChanCount m = max (pi->input_streams(), pi->output_streams());
1047 if (m > potential_max_streams) {
1048 potential_max_streams = m;
1052 ProcessorList::iterator inserted = _processors.insert (iter, *i);
1054 if ((*i)->active()) {
1058 if (configure_processors_unlocked (err)) {
1059 _processors.erase (inserted);
1060 configure_processors_unlocked (0); // it worked before we tried to add it ...
1064 (*i)->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false, false));
1067 _output->set_user_latency (0);
1070 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1076 Route::placement_range(Placement p, ProcessorList::iterator& start, ProcessorList::iterator& end)
1078 if (p == PreFader) {
1079 start = _processors.begin();
1080 end = find(_processors.begin(), _processors.end(), _amp);
1082 start = find(_processors.begin(), _processors.end(), _amp);
1084 end = _processors.end();
1088 /** Turn off all processors with a given placement
1089 * @param p Placement of processors to disable
1092 Route::disable_processors (Placement p)
1094 Glib::RWLock::ReaderLock lm (_processor_lock);
1096 ProcessorList::iterator start, end;
1097 placement_range(p, start, end);
1099 for (ProcessorList::iterator i = start; i != end; ++i) {
1100 (*i)->deactivate ();
1103 _session.set_dirty ();
1106 /** Turn off all redirects
1109 Route::disable_processors ()
1111 Glib::RWLock::ReaderLock lm (_processor_lock);
1113 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1114 (*i)->deactivate ();
1117 _session.set_dirty ();
1120 /** Turn off all redirects with a given placement
1121 * @param p Placement of redirects to disable
1124 Route::disable_plugins (Placement p)
1126 Glib::RWLock::ReaderLock lm (_processor_lock);
1128 ProcessorList::iterator start, end;
1129 placement_range(p, start, end);
1131 for (ProcessorList::iterator i = start; i != end; ++i) {
1132 if (boost::dynamic_pointer_cast<PluginInsert> (*i)) {
1133 (*i)->deactivate ();
1137 _session.set_dirty ();
1140 /** Turn off all plugins
1143 Route::disable_plugins ()
1145 Glib::RWLock::ReaderLock lm (_processor_lock);
1147 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1148 if (boost::dynamic_pointer_cast<PluginInsert> (*i)) {
1149 (*i)->deactivate ();
1153 _session.set_dirty ();
1158 Route::ab_plugins (bool forward)
1160 Glib::RWLock::ReaderLock lm (_processor_lock);
1164 /* forward = turn off all active redirects, and mark them so that the next time
1165 we go the other way, we will revert them
1168 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1169 if (!boost::dynamic_pointer_cast<PluginInsert> (*i)) {
1173 if ((*i)->active()) {
1174 (*i)->deactivate ();
1175 (*i)->set_next_ab_is_active (true);
1177 (*i)->set_next_ab_is_active (false);
1183 /* backward = if the redirect was marked to go active on the next ab, do so */
1185 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1187 if (!boost::dynamic_pointer_cast<PluginInsert> (*i)) {
1191 if ((*i)->get_next_ab_is_active()) {
1194 (*i)->deactivate ();
1199 _session.set_dirty ();
1203 /** Remove processors with a given placement.
1204 * @param p Placement of processors to remove.
1207 Route::clear_processors (Placement p)
1209 const ChanCount old_pms = processor_max_streams;
1211 if (!_session.engine().connected()) {
1215 bool already_deleting = _session.deletion_in_progress();
1216 if (!already_deleting) {
1217 _session.set_deletion_in_progress();
1221 Glib::RWLock::WriterLock lm (_processor_lock);
1222 ProcessorList new_list;
1223 ProcessorStreams err;
1224 bool seen_amp = false;
1226 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1232 if ((*i) == _amp || (*i) == _meter || (*i) == _main_outs) {
1234 /* you can't remove these */
1236 new_list.push_back (*i);
1243 new_list.push_back (*i);
1246 (*i)->drop_references ();
1254 (*i)->drop_references ();
1257 new_list.push_back (*i);
1264 _processors = new_list;
1265 configure_processors_unlocked (&err); // this can't fail
1268 processor_max_streams.reset();
1269 _have_internal_generator = false;
1270 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1272 if (!already_deleting) {
1273 _session.clear_deletion_in_progress();
1278 Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStreams* err)
1280 /* these can never be removed */
1282 if (processor == _amp || processor == _meter || processor == _main_outs) {
1286 ChanCount old_pms = processor_max_streams;
1288 if (!_session.engine().connected()) {
1292 processor_max_streams.reset();
1295 Glib::RWLock::WriterLock lm (_processor_lock);
1296 ProcessorList::iterator i;
1297 bool removed = false;
1299 for (i = _processors.begin(); i != _processors.end(); ) {
1300 if (*i == processor) {
1302 /* move along, see failure case for configure_processors()
1303 where we may need to reconfigure the processor.
1306 /* stop redirects that send signals to JACK ports
1307 from causing noise as a result of no longer being
1311 boost::shared_ptr<IOProcessor> iop;
1313 if ((iop = boost::dynamic_pointer_cast<IOProcessor> (*i)) != 0) {
1315 iop->input()->disconnect (this);
1317 if (iop->output()) {
1318 iop->output()->disconnect (this);
1322 i = _processors.erase (i);
1330 _output->set_user_latency (0);
1338 if (configure_processors_unlocked (err)) {
1339 /* get back to where we where */
1340 _processors.insert (i, processor);
1341 /* we know this will work, because it worked before :) */
1342 configure_processors_unlocked (0);
1346 _have_internal_generator = false;
1348 for (i = _processors.begin(); i != _processors.end(); ++i) {
1349 boost::shared_ptr<PluginInsert> pi;
1351 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
1352 if (pi->is_generator()) {
1353 _have_internal_generator = true;
1360 processor->drop_references ();
1361 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1367 Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams* err)
1369 ProcessorList deleted;
1370 ProcessorList as_we_were;
1372 if (!_session.engine().connected()) {
1376 processor_max_streams.reset();
1379 Glib::RWLock::WriterLock lm (_processor_lock);
1380 ProcessorList::iterator i;
1381 boost::shared_ptr<Processor> processor;
1383 as_we_were = _processors;
1385 for (i = _processors.begin(); i != _processors.end(); ) {
1389 /* these can never be removed */
1391 if (processor == _amp || processor == _meter || processor == _main_outs) {
1396 /* see if its in the list of processors to delete */
1398 if (find (to_be_deleted.begin(), to_be_deleted.end(), processor) == to_be_deleted.end()) {
1403 /* stop IOProcessors that send to JACK ports
1404 from causing noise as a result of no longer being
1408 boost::shared_ptr<IOProcessor> iop;
1410 if ((iop = boost::dynamic_pointer_cast<IOProcessor> (processor)) != 0) {
1414 deleted.push_back (processor);
1415 i = _processors.erase (i);
1418 if (deleted.empty()) {
1419 /* none of those in the requested list were found */
1423 _output->set_user_latency (0);
1425 if (configure_processors_unlocked (err)) {
1426 /* get back to where we where */
1427 _processors = as_we_were;
1428 /* we know this will work, because it worked before :) */
1429 configure_processors_unlocked (0);
1433 _have_internal_generator = false;
1435 for (i = _processors.begin(); i != _processors.end(); ++i) {
1436 boost::shared_ptr<PluginInsert> pi;
1438 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
1439 if (pi->is_generator()) {
1440 _have_internal_generator = true;
1447 /* now try to do what we need to so that those that were removed will be deleted */
1449 for (ProcessorList::iterator i = deleted.begin(); i != deleted.end(); ++i) {
1450 (*i)->drop_references ();
1453 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1460 Route::configure_processors (ProcessorStreams* err)
1462 if (!_in_configure_processors) {
1463 Glib::RWLock::WriterLock lm (_processor_lock);
1464 return configure_processors_unlocked (err);
1469 /** Configure the input/output configuration of each processor in the processors list.
1470 * Return 0 on success, otherwise configuration is impossible.
1473 Route::configure_processors_unlocked (ProcessorStreams* err)
1475 if (_in_configure_processors) {
1479 _in_configure_processors = true;
1481 // Check each processor in order to see if we can configure as requested
1482 ChanCount in = _input->n_ports ();
1484 list< pair<ChanCount,ChanCount> > configuration;
1487 DEBUG_TRACE (DEBUG::Processors, string_compose ("%1: configure processors\n", _name));
1489 DEBUG_TRACE (DEBUG::Processors, "{\n");
1490 for (list<boost::shared_ptr<Processor> >::const_iterator p = _processors.begin(); p != _processors.end(); ++p) {
1491 DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1 ID = %2\n", (*p)->name(), (*p)->id()));
1493 DEBUG_TRACE (DEBUG::Processors, "}\n");
1496 for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++index) {
1498 if ((*p)->can_support_io_configuration(in, out)) {
1499 DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1in = %2 out = %3\n",(*p)->name(), in, out));
1500 configuration.push_back(make_pair(in, out));
1507 _in_configure_processors = false;
1512 // We can, so configure everything
1513 list< pair<ChanCount,ChanCount> >::iterator c = configuration.begin();
1514 for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++c) {
1515 (*p)->configure_io(c->first, c->second);
1516 processor_max_streams = ChanCount::max(processor_max_streams, c->first);
1517 processor_max_streams = ChanCount::max(processor_max_streams, c->second);
1522 _meter->reset_max_channels (processor_max_streams);
1525 /* make sure we have sufficient scratch buffers to cope with the new processor
1527 _session.ensure_buffers (n_process_buffers ());
1529 _in_configure_processors = false;
1534 Route::all_processors_flip ()
1536 Glib::RWLock::ReaderLock lm (_processor_lock);
1538 if (_processors.empty()) {
1542 bool first_is_on = _processors.front()->active();
1544 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1546 (*i)->deactivate ();
1552 _session.set_dirty ();
1555 /** Set all processors with a given placement to a given active state.
1556 * @param p Placement of processors to change.
1557 * @param state New active state for those processors.
1560 Route::all_processors_active (Placement p, bool state)
1562 Glib::RWLock::ReaderLock lm (_processor_lock);
1564 if (_processors.empty()) {
1567 ProcessorList::iterator start, end;
1568 placement_range(p, start, end);
1570 bool before_amp = true;
1571 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1576 if (p == PreFader && before_amp) {
1580 (*i)->deactivate ();
1585 _session.set_dirty ();
1589 Route::processor_is_prefader (boost::shared_ptr<Processor> p)
1591 bool pre_fader = true;
1592 Glib::RWLock::ReaderLock lm (_processor_lock);
1594 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1596 /* semantic note: if p == amp, we want to return true, so test
1597 for equality before checking if this is the amp
1614 Route::reorder_processors (const ProcessorList& new_order, ProcessorStreams* err)
1616 /* "new_order" is an ordered list of processors to be positioned according to "placement".
1617 NOTE: all processors in "new_order" MUST be marked as display_to_user(). There maybe additional
1618 processors in the current actual processor list that are hidden. Any visible processors
1619 in the current list but not in "new_order" will be assumed to be deleted.
1623 Glib::RWLock::WriterLock lm (_processor_lock);
1624 ChanCount old_pms = processor_max_streams;
1625 ProcessorList::iterator oiter;
1626 ProcessorList::const_iterator niter;
1627 ProcessorList as_it_was_before = _processors;
1628 ProcessorList as_it_will_be;
1630 oiter = _processors.begin();
1631 niter = new_order.begin();
1633 while (niter != new_order.end()) {
1635 /* if the next processor in the old list is invisible (i.e. should not be in the new order)
1636 then append it to the temp list.
1638 Otherwise, see if the next processor in the old list is in the new list. if not,
1639 its been deleted. If its there, append it to the temp list.
1642 if (oiter == _processors.end()) {
1644 /* no more elements in the old list, so just stick the rest of
1645 the new order onto the temp list.
1648 as_it_will_be.insert (as_it_will_be.end(), niter, new_order.end());
1649 while (niter != new_order.end()) {
1656 if (!(*oiter)->display_to_user()) {
1658 as_it_will_be.push_back (*oiter);
1662 /* visible processor: check that its in the new order */
1664 if (find (new_order.begin(), new_order.end(), (*oiter)) == new_order.end()) {
1665 /* deleted: do nothing, shared_ptr<> will clean up */
1667 /* ignore this one, and add the next item from the new order instead */
1668 as_it_will_be.push_back (*niter);
1673 /* now remove from old order - its taken care of no matter what */
1674 oiter = _processors.erase (oiter);
1679 _processors.insert (oiter, as_it_will_be.begin(), as_it_will_be.end());
1681 if (configure_processors_unlocked (err)) {
1682 _processors = as_it_was_before;
1683 processor_max_streams = old_pms;
1688 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1700 Route::get_template()
1702 return state(false);
1706 Route::state(bool full_state)
1708 XMLNode *node = new XMLNode("Route");
1709 ProcessorList::iterator i;
1712 id().print (buf, sizeof (buf));
1713 node->add_property("id", buf);
1714 node->add_property ("name", _name);
1715 node->add_property("default-type", _default_type.to_string());
1718 node->add_property("flags", enum_2_string (_flags));
1721 node->add_property("active", _active?"yes":"no");
1722 node->add_property("phase-invert", _phase_invert?"yes":"no");
1723 node->add_property("denormal-protection", _denormal_protection?"yes":"no");
1724 node->add_property("meter-point", enum_2_string (_meter_point));
1727 node->add_property("route-group", _route_group->name());
1730 string order_string;
1731 OrderKeys::iterator x = order_keys.begin();
1733 while (x != order_keys.end()) {
1734 order_string += string ((*x).first);
1735 order_string += '=';
1736 snprintf (buf, sizeof(buf), "%ld", (*x).second);
1737 order_string += buf;
1741 if (x == order_keys.end()) {
1745 order_string += ':';
1747 node->add_property ("order-keys", order_string);
1748 node->add_property ("self-solo", (_self_solo ? "yes" : "no"));
1749 snprintf (buf, sizeof (buf), "%d", _soloed_by_others);
1750 node->add_property ("soloed-by-others", buf);
1752 node->add_child_nocopy (_input->state (full_state));
1753 node->add_child_nocopy (_output->state (full_state));
1754 node->add_child_nocopy (_solo_control->get_state ());
1755 node->add_child_nocopy (_mute_master->get_state ());
1757 XMLNode* remote_control_node = new XMLNode (X_("RemoteControl"));
1758 snprintf (buf, sizeof (buf), "%d", _remote_control_id);
1759 remote_control_node->add_property (X_("id"), buf);
1760 node->add_child_nocopy (*remote_control_node);
1762 if (_comment.length()) {
1763 XMLNode *cmt = node->add_child ("Comment");
1764 cmt->add_content (_comment);
1767 for (i = _processors.begin(); i != _processors.end(); ++i) {
1768 node->add_child_nocopy((*i)->state (full_state));
1772 node->add_child_copy (*_extra_xml);
1779 Route::set_state (const XMLNode& node, int version)
1781 return _set_state (node, version, true);
1785 Route::_set_state (const XMLNode& node, int version, bool /*call_base*/)
1787 if (version < 3000) {
1788 return _set_state_2X (node, version);
1792 XMLNodeConstIterator niter;
1794 XMLPropertyList plist;
1795 const XMLProperty *prop;
1797 if (node.name() != "Route"){
1798 error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
1802 if ((prop = node.property (X_("name"))) != 0) {
1803 Route::set_name (prop->value());
1806 if ((prop = node.property ("id")) != 0) {
1807 _id = prop->value ();
1810 if ((prop = node.property (X_("flags"))) != 0) {
1811 _flags = Flag (string_2_enum (prop->value(), _flags));
1816 /* add all processors (except amp, which is always present) */
1818 nlist = node.children();
1819 XMLNode processor_state (X_("processor_state"));
1821 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1825 if (child->name() == IO::state_node_name) {
1826 if ((prop = child->property (X_("direction"))) == 0) {
1830 if (prop->value() == "Input") {
1831 _input->set_state (*child, version);
1832 } else if (prop->value() == "Output") {
1833 _output->set_state (*child, version);
1837 if (child->name() == X_("Processor")) {
1838 processor_state.add_child_copy (*child);
1842 set_processor_state (processor_state);
1844 if ((prop = node.property ("self-solo")) != 0) {
1845 set_self_solo (string_is_affirmative (prop->value()));
1848 if ((prop = node.property ("soloed-by-others")) != 0) {
1849 _soloed_by_others = 0; // needed for mod_solo_by_others () to work
1850 mod_solo_by_others (atoi (prop->value()));
1853 if ((prop = node.property ("solo-isolated")) != 0) {
1854 set_solo_isolated (string_is_affirmative (prop->value()), this);
1857 if ((prop = node.property (X_("phase-invert"))) != 0) {
1858 set_phase_invert (string_is_affirmative (prop->value()));
1861 if ((prop = node.property (X_("denormal-protection"))) != 0) {
1862 set_denormal_protection (string_is_affirmative (prop->value()));
1865 if ((prop = node.property (X_("active"))) != 0) {
1866 bool yn = string_is_affirmative (prop->value());
1867 _active = !yn; // force switch
1871 if ((prop = node.property (X_("meter-point"))) != 0) {
1872 _meter_point = MeterPoint (string_2_enum (prop->value (), _meter_point));
1874 _meter->set_display_to_user (_meter_point == MeterCustom);
1878 if ((prop = node.property (X_("order-keys"))) != 0) {
1882 string::size_type colon, equal;
1883 string remaining = prop->value();
1885 while (remaining.length()) {
1887 if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
1888 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1891 if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) {
1892 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1895 set_order_key (remaining.substr (0, equal), n);
1899 colon = remaining.find_first_of (':');
1901 if (colon != string::npos) {
1902 remaining = remaining.substr (colon+1);
1909 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1912 if (child->name() == X_("Comment")) {
1914 /* XXX this is a terrible API design in libxml++ */
1916 XMLNode *cmt = *(child->children().begin());
1917 _comment = cmt->content();
1919 } else if (child->name() == X_("Extra")) {
1921 _extra_xml = new XMLNode (*child);
1923 } else if (child->name() == X_("Controllable") && (prop = child->property("name")) != 0) {
1925 if (prop->value() == "solo") {
1926 _solo_control->set_state (*child, version);
1927 _session.add_controllable (_solo_control);
1930 } else if (child->name() == X_("RemoteControl")) {
1931 if ((prop = child->property (X_("id"))) != 0) {
1933 sscanf (prop->value().c_str(), "%d", &x);
1934 set_remote_control_id (x);
1937 } else if (child->name() == X_("MuteMaster")) {
1938 _mute_master->set_state (*child, version);
1946 Route::_set_state_2X (const XMLNode& node, int version)
1949 XMLNodeConstIterator niter;
1951 XMLPropertyList plist;
1952 const XMLProperty *prop;
1954 /* 2X things which still remain to be handled:
1957 * mute-affects-pre-fader
1958 * mute-affects-post-fader
1959 * mute-affects-control-outs
1960 * mute-affects-main-outs
1965 if (node.name() != "Route") {
1966 error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
1970 if ((prop = node.property (X_("flags"))) != 0) {
1971 _flags = Flag (string_2_enum (prop->value(), _flags));
1976 /* add standard processors */
1978 _meter.reset (new PeakMeter (_session));
1979 add_processor (_meter, PreFader);
1981 if (_flags & ControlOut) {
1982 /* where we listen to tracks */
1983 _intreturn.reset (new InternalReturn (_session));
1984 add_processor (_intreturn, PreFader);
1987 _main_outs.reset (new Delivery (_session, _output, _mute_master, _name, Delivery::Main));
1988 add_processor (_main_outs, PostFader);
1992 nlist = node.children ();
1993 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1997 if (child->name() == IO::state_node_name) {
1999 /* there is a note in IO::set_state_2X() about why we have to call
2003 _input->set_state_2X (*child, version, true);
2004 _output->set_state_2X (*child, version, false);
2006 if ((prop = child->property (X_("name"))) != 0) {
2007 set_name (prop->value ());
2010 if ((prop = child->property (X_("id"))) != 0) {
2011 _id = prop->value ();
2014 if ((prop = child->property (X_("active"))) != 0) {
2015 bool yn = string_is_affirmative (prop->value());
2016 _active = !yn; // force switch
2024 if ((prop = node.property (X_("phase-invert"))) != 0) {
2025 set_phase_invert (string_is_affirmative (prop->value()));
2028 if ((prop = node.property (X_("denormal-protection"))) != 0) {
2029 set_denormal_protection (string_is_affirmative (prop->value()));
2032 if ((prop = node.property (X_("soloed"))) != 0) {
2033 bool yn = string_is_affirmative (prop->value());
2035 /* XXX force reset of solo status */
2037 set_solo (yn, this);
2040 if ((prop = node.property (X_("meter-point"))) != 0) {
2041 _meter_point = MeterPoint (string_2_enum (prop->value (), _meter_point));
2044 /* do not carry over edit/mix groups from 2.X because (a) its hard (b) they
2045 don't mean the same thing.
2048 if ((prop = node.property (X_("order-keys"))) != 0) {
2052 string::size_type colon, equal;
2053 string remaining = prop->value();
2055 while (remaining.length()) {
2057 if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
2058 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
2061 if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) {
2062 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
2065 set_order_key (remaining.substr (0, equal), n);
2069 colon = remaining.find_first_of (':');
2071 if (colon != string::npos) {
2072 remaining = remaining.substr (colon+1);
2079 XMLNodeList redirect_nodes;
2081 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
2085 if (child->name() == X_("Send") || child->name() == X_("Insert")) {
2086 redirect_nodes.push_back(child);
2091 set_processor_state_2X (redirect_nodes, version);
2093 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
2096 if (child->name() == X_("Comment")) {
2098 /* XXX this is a terrible API design in libxml++ */
2100 XMLNode *cmt = *(child->children().begin());
2101 _comment = cmt->content();
2103 } else if (child->name() == X_("Extra")) {
2105 _extra_xml = new XMLNode (*child);
2107 } else if (child->name() == X_("Controllable") && (prop = child->property("name")) != 0) {
2109 if (prop->value() == "solo") {
2110 _solo_control->set_state (*child, version);
2111 _session.add_controllable (_solo_control);
2114 } else if (child->name() == X_("RemoteControl")) {
2115 if ((prop = child->property (X_("id"))) != 0) {
2117 sscanf (prop->value().c_str(), "%d", &x);
2118 set_remote_control_id (x);
2128 Route::get_processor_state ()
2130 XMLNode* root = new XMLNode (X_("redirects"));
2131 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2132 root->add_child_nocopy ((*i)->state (true));
2139 Route::set_processor_state_2X (XMLNodeList const & nList, int version)
2141 /* We don't bother removing existing processors not in nList, as this
2142 method will only be called when creating a Route from scratch, not
2143 for undo purposes. Just put processors in at the appropriate place
2147 for (XMLNodeConstIterator i = nList.begin(); i != nList.end(); ++i) {
2148 add_processor_from_xml_2X (**i, version, _processors.begin ());
2153 Route::set_processor_state (const XMLNode& node)
2155 const XMLNodeList &nlist = node.children();
2156 XMLNodeConstIterator niter;
2157 ProcessorList::iterator i, o;
2159 // Iterate through existing processors, remove those which are not in the state list
2161 for (i = _processors.begin(); i != _processors.end(); ) {
2163 /* leave amp alone, always */
2170 ProcessorList::iterator tmp = i;
2173 bool processorInStateList = false;
2175 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2177 XMLProperty* id_prop = (*niter)->property(X_("id"));
2179 if (id_prop && (*i)->id() == id_prop->value()) {
2180 processorInStateList = true;
2185 if (!processorInStateList) {
2186 remove_processor (*i);
2192 // Iterate through state list and make sure all processors are on the track and in the correct order,
2193 // set the state of existing processors according to the new state on the same go
2195 i = _processors.begin();
2197 for (niter = nlist.begin(); niter != nlist.end(); ++niter, ++i) {
2199 XMLProperty* prop = (*niter)->property ("type");
2203 // Check whether the next processor in the list is the right one,
2204 // except for "amp" which is always there and may not have the
2205 // old ID since it is always created anew in every Route
2207 if (prop->value() != "amp") {
2208 while (o != _processors.end()) {
2209 XMLProperty* id_prop = (*niter)->property(X_("id"));
2210 if (id_prop && (*o)->id() == id_prop->value()) {
2218 // If the processor (*niter) is not on the route,
2219 // create it and move it to the correct location
2221 if (o == _processors.end()) {
2223 if (add_processor_from_xml (**niter, i)) {
2224 --i; // move iterator to the newly inserted processor
2226 cerr << "Error restoring route: unable to restore processor" << endl;
2231 // Otherwise, the processor already exists; just
2232 // ensure it is at the location provided in the XML state
2235 boost::shared_ptr<Processor> tmp = (*o);
2236 _processors.erase (o); // remove the old copy
2237 _processors.insert (i, tmp); // insert the processor at the correct location
2238 --i; // move iterator to the correct processor
2241 // and make it (just) so
2243 (*i)->set_state (**niter, Stateful::current_state_version);
2247 /* note: there is no configure_processors() call because we figure that
2248 the XML state represents a working signal route.
2251 processors_changed (RouteProcessorChange ());
2255 Route::curve_reallocate ()
2257 // _gain_automation_curve.finish_resize ();
2258 // _pan_automation_curve.finish_resize ();
2262 Route::silence (nframes_t nframes)
2266 _output->silence (nframes);
2269 Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
2272 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2273 boost::shared_ptr<PluginInsert> pi;
2275 if (!_active && (pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
2276 // skip plugins, they don't need anything when we're not active
2280 (*i)->silence (nframes);
2283 if (nframes == _session.get_block_size()) {
2293 Route::add_internal_return ()
2296 _intreturn.reset (new InternalReturn (_session));
2297 add_processor (_intreturn, PreFader);
2302 Route::get_return_buffer () const
2304 Glib::RWLock::ReaderLock rm (_processor_lock);
2306 for (ProcessorList::const_iterator x = _processors.begin(); x != _processors.end(); ++x) {
2307 boost::shared_ptr<InternalReturn> d = boost::dynamic_pointer_cast<InternalReturn>(*x);
2310 BufferSet* bs = d->get_buffers ();
2319 Route::release_return_buffer () const
2321 Glib::RWLock::ReaderLock rm (_processor_lock);
2323 for (ProcessorList::const_iterator x = _processors.begin(); x != _processors.end(); ++x) {
2324 boost::shared_ptr<InternalReturn> d = boost::dynamic_pointer_cast<InternalReturn>(*x);
2327 return d->release_buffers ();
2333 Route::listen_via (boost::shared_ptr<Route> route, Placement placement, bool /*active*/, bool aux)
2335 vector<string> ports;
2336 vector<string>::const_iterator i;
2339 Glib::RWLock::ReaderLock rm (_processor_lock);
2341 for (ProcessorList::iterator x = _processors.begin(); x != _processors.end(); ++x) {
2343 boost::shared_ptr<InternalSend> d = boost::dynamic_pointer_cast<InternalSend>(*x);
2345 if (d && d->target_route() == route) {
2347 /* if the target is the control outs, then make sure
2348 we take note of which i-send is doing that.
2351 if (route == _session.control_out()) {
2352 _control_outs = boost::dynamic_pointer_cast<Delivery>(d);
2355 /* already listening via the specified IO: do nothing */
2362 boost::shared_ptr<InternalSend> listener;
2365 listener.reset (new InternalSend (_session, _mute_master, route, (aux ? Delivery::Aux : Delivery::Listen)));
2367 } catch (failed_constructor& err) {
2371 if (route == _session.control_out()) {
2372 _control_outs = listener;
2375 add_processor (listener, placement);
2381 Route::drop_listen (boost::shared_ptr<Route> route)
2383 ProcessorStreams err;
2384 ProcessorList::iterator tmp;
2386 Glib::RWLock::ReaderLock rl(_processor_lock);
2390 for (ProcessorList::iterator x = _processors.begin(); x != _processors.end(); ) {
2392 boost::shared_ptr<InternalSend> d = boost::dynamic_pointer_cast<InternalSend>(*x);
2394 if (d && d->target_route() == route) {
2396 remove_processor (*x, &err);
2399 /* list could have been demolished while we dropped the lock
2409 if (route == _session.control_out()) {
2410 _control_outs.reset ();
2415 Route::set_comment (string cmt, void *src)
2418 comment_changed (src);
2419 _session.set_dirty ();
2423 Route::feeds (boost::shared_ptr<Route> other, bool* only_send)
2425 DEBUG_TRACE (DEBUG::Graph, string_compose ("Feeds? %1\n", _name));
2427 if (_output->connected_to (other->input())) {
2428 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tdirect FEEDS %2\n", other->name()));
2437 for (ProcessorList::iterator r = _processors.begin(); r != _processors.end(); r++) {
2439 boost::shared_ptr<IOProcessor> iop;
2441 if ((iop = boost::dynamic_pointer_cast<IOProcessor>(*r)) != 0) {
2442 if (iop->feeds (other)) {
2443 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tIOP %1 does feed %2\n", iop->name(), other->name()));
2449 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tIOP %1 does NOT feed %2\n", iop->name(), other->name()));
2452 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tPROC %1 is not an IOP\n", (*r)->name()));
2457 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tdoes NOT feed %1\n", other->name()));
2462 Route::handle_transport_stopped (bool /*abort_ignored*/, bool did_locate, bool can_flush_processors)
2464 nframes_t now = _session.transport_frame();
2467 Glib::RWLock::ReaderLock lm (_processor_lock);
2470 automation_snapshot (now, true);
2473 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2475 if (Config->get_plugins_stop_with_transport() && can_flush_processors) {
2476 (*i)->deactivate ();
2480 (*i)->transport_stopped (now);
2484 _roll_delay = _initial_delay;
2488 Route::input_change_handler (IOChange change, void * /*src*/)
2490 if ((change & ConfigurationChanged)) {
2491 configure_processors (0);
2496 Route::output_change_handler (IOChange change, void * /*src*/)
2498 if ((change & ConfigurationChanged)) {
2500 /* XXX resize all listeners to match _main_outs? */
2502 // configure_processors (0);
2507 Route::pans_required () const
2509 if (n_outputs().n_audio() < 2) {
2513 return max (n_inputs ().n_audio(), processor_max_streams.n_audio());
2517 Route::no_roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame,
2518 bool session_state_changing, bool /*can_record*/, bool /*rec_monitors_input*/)
2520 if (n_outputs().n_total() == 0) {
2524 if (!_active || n_inputs() == ChanCount::ZERO) {
2528 if (session_state_changing) {
2529 if (_session.transport_speed() != 0.0f) {
2530 /* we're rolling but some state is changing (e.g. our diskstream contents)
2531 so we cannot use them. Be silent till this is over.
2533 XXX note the absurdity of ::no_roll() being called when we ARE rolling!
2538 /* we're really not rolling, so we're either delivery silence or actually
2539 monitoring, both of which are safe to do while session_state_changing is true.
2543 _amp->apply_gain_automation (false);
2544 passthru (start_frame, end_frame, nframes, 0);
2550 Route::check_initial_delay (nframes_t nframes, nframes_t& transport_frame)
2552 if (_roll_delay > nframes) {
2554 _roll_delay -= nframes;
2556 /* transport frame is not legal for caller to use */
2559 } else if (_roll_delay > 0) {
2561 nframes -= _roll_delay;
2562 silence (_roll_delay);
2563 /* we've written _roll_delay of samples into the
2564 output ports, so make a note of that for
2567 _main_outs->increment_output_offset (_roll_delay);
2568 transport_frame += _roll_delay;
2577 Route::roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame, int declick,
2578 bool /*can_record*/, bool /*rec_monitors_input*/)
2581 // automation snapshot can also be called from the non-rt context
2582 // and it uses the processor list, so we try to acquire the lock here
2583 Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
2586 automation_snapshot (_session.transport_frame(), false);
2590 if (n_outputs().n_total() == 0) {
2594 if (!_active || n_inputs().n_total() == 0) {
2599 nframes_t unused = 0;
2601 if ((nframes = check_initial_delay (nframes, unused)) == 0) {
2607 passthru (start_frame, end_frame, nframes, declick);
2613 Route::silent_roll (nframes_t nframes, sframes_t /*start_frame*/, sframes_t /*end_frame*/,
2614 bool /*can_record*/, bool /*rec_monitors_input*/)
2621 Route::toggle_monitor_input ()
2623 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
2624 i->ensure_monitor_input( ! i->monitoring_input());
2629 Route::has_external_redirects () const
2631 // FIXME: what about sends? - they don't return a signal back to ardour?
2633 boost::shared_ptr<const PortInsert> pi;
2635 for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
2637 if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*i)) != 0) {
2639 for (PortSet::const_iterator port = pi->output()->ports().begin(); port != pi->output()->ports().end(); ++port) {
2641 string port_name = port->name();
2642 string client_name = port_name.substr (0, port_name.find(':'));
2644 /* only say "yes" if the redirect is actually in use */
2646 if (client_name != "ardour" && pi->active()) {
2657 Route::flush_processors ()
2659 /* XXX shouldn't really try to take this lock, since
2660 this is called from the RT audio thread.
2663 Glib::RWLock::ReaderLock lm (_processor_lock);
2665 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2666 (*i)->deactivate ();
2672 Route::set_meter_point (MeterPoint p, void *src)
2674 /* CAN BE CALLED FROM PROCESS CONTEXT */
2676 if (_meter_point == p) {
2680 bool meter_was_visible_to_user = _meter->display_to_user ();
2683 Glib::RWLock::WriterLock lm (_processor_lock);
2685 if (p != MeterCustom) {
2686 // Move meter in the processors list to reflect the new position
2687 ProcessorList::iterator loc = find (_processors.begin(), _processors.end(), _meter);
2688 _processors.erase(loc);
2691 loc = _processors.begin();
2694 loc = find (_processors.begin(), _processors.end(), _amp);
2696 case MeterPostFader:
2697 loc = _processors.end();
2705 if (loc == _processors.begin()) {
2706 m_in = _input->n_ports();
2708 ProcessorList::iterator before = loc;
2710 m_in = (*before)->output_streams ();
2713 _meter->reflect_inputs (m_in);
2715 _processors.insert (loc, _meter);
2717 /* we do not need to reconfigure the processors, because the meter
2718 (a) is always ready to handle processor_max_streams
2719 (b) is always an N-in/N-out processor, and thus moving
2720 it doesn't require any changes to the other processors.
2723 _meter->set_display_to_user (false);
2727 // just make it visible and let the user move it
2729 _meter->set_display_to_user (true);
2734 meter_change (src); /* EMIT SIGNAL */
2736 bool const meter_visibly_changed = (_meter->display_to_user() != meter_was_visible_to_user);
2738 processors_changed (RouteProcessorChange (RouteProcessorChange::MeterPointChange, meter_visibly_changed)); /* EMIT SIGNAL */
2742 Route::put_control_outs_at (Placement p)
2744 if (!_control_outs) {
2749 Glib::RWLock::WriterLock lm (_processor_lock);
2750 ProcessorList as_it_was (_processors);
2751 // Move meter in the processors list
2752 ProcessorList::iterator loc = find(_processors.begin(), _processors.end(), _control_outs);
2753 _processors.erase(loc);
2757 loc = find(_processors.begin(), _processors.end(), _amp);
2758 if (loc != _processors.begin()) {
2763 loc = find(_processors.begin(), _processors.end(), _amp);
2764 assert (loc != _processors.end());
2769 _processors.insert(loc, _control_outs);
2771 if (configure_processors_unlocked (0)) {
2772 _processors = as_it_was;
2773 configure_processors_unlocked (0); // it worked before we tried to add it ...
2778 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
2779 _session.set_dirty ();
2783 Route::update_total_latency ()
2785 nframes_t old = _output->effective_latency();
2786 nframes_t own_latency = _output->user_latency();
2788 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2789 if ((*i)->active ()) {
2790 own_latency += (*i)->signal_latency ();
2794 DEBUG_TRACE (DEBUG::Latency, string_compose ("%1: internal redirect latency = %2\n", _name, own_latency));
2796 _output->set_port_latency (own_latency);
2798 if (_output->user_latency() == 0) {
2800 /* this (virtual) function is used for pure Routes,
2801 not derived classes like AudioTrack. this means
2802 that the data processed here comes from an input
2803 port, not prerecorded material, and therefore we
2804 have to take into account any input latency.
2807 own_latency += _input->signal_latency ();
2810 if (old != own_latency) {
2811 _output->set_latency_delay (own_latency);
2812 signal_latency_changed (); /* EMIT SIGNAL */
2815 DEBUG_TRACE (DEBUG::Latency, string_compose ("%1: input latency = %2 total = %3\n", _name, _input->signal_latency(), own_latency));
2817 return _output->effective_latency ();
2821 Route::set_user_latency (nframes_t nframes)
2823 _output->set_user_latency (nframes);
2824 _session.update_latency_compensation (false, false);
2828 Route::set_latency_delay (nframes_t longest_session_latency)
2830 nframes_t old = _initial_delay;
2832 if (_output->effective_latency() < longest_session_latency) {
2833 _initial_delay = longest_session_latency - _output->effective_latency();
2838 if (_initial_delay != old) {
2839 initial_delay_changed (); /* EMIT SIGNAL */
2842 if (_session.transport_stopped()) {
2843 _roll_delay = _initial_delay;
2848 Route::automation_snapshot (nframes_t now, bool force)
2850 panner()->automation_snapshot (now, force);
2852 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2853 (*i)->automation_snapshot (now, force);
2857 Route::SoloControllable::SoloControllable (std::string name, Route& r)
2858 : AutomationControl (r.session(), Evoral::Parameter (SoloAutomation),
2859 boost::shared_ptr<AutomationList>(), name)
2862 boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloAutomation)));
2867 Route::SoloControllable::set_value (float val)
2869 bool bval = ((val >= 0.5f) ? true: false);
2871 this is how it should be done
2873 boost::shared_ptr<RouteList> rl (new RouteList);
2874 rl->push_back (route);
2876 if (Config->get_solo_control_is_listen_control()) {
2877 _session.set_listen (rl, bval);
2879 _session.set_solo (rl, bval);
2882 route.set_solo (bval, this);
2887 Route::SoloControllable::get_value (void) const
2889 if (Config->get_solo_control_is_listen_control()) {
2890 return route.listening() ? 1.0f : 0.0f;
2892 return route.self_soloed() ? 1.0f : 0.0f;
2896 Route::MuteControllable::MuteControllable (std::string name, Route& r)
2897 : AutomationControl (r.session(), Evoral::Parameter (MuteAutomation),
2898 boost::shared_ptr<AutomationList>(), name)
2901 boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(MuteAutomation)));
2906 Route::MuteControllable::set_value (float val)
2908 bool bval = ((val >= 0.5f) ? true: false);
2910 this is how it should be done
2912 boost::shared_ptr<RouteList> rl (new RouteList);
2913 rl->push_back (route);
2914 _session.set_mute (rl, bval);
2916 route.set_mute (bval, this);
2921 Route::MuteControllable::get_value (void) const
2923 return route.muted() ? 1.0f : 0.0f;
2927 Route::set_block_size (nframes_t nframes)
2929 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2930 (*i)->set_block_size (nframes);
2933 _session.ensure_buffers (n_process_buffers ());
2937 Route::protect_automation ()
2939 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i)
2940 (*i)->protect_automation();
2944 Route::set_pending_declick (int declick)
2947 /* this call is not allowed to turn off a pending declick unless "force" is true */
2949 _pending_declick = declick;
2951 // cerr << _name << ": after setting to " << declick << " pending declick = " << _pending_declick << endl;
2953 _pending_declick = 0;
2958 /** Shift automation forwards from a particular place, thereby inserting time.
2959 * Adds undo commands for any shifts that are performed.
2961 * @param pos Position to start shifting from.
2962 * @param frames Amount to shift forwards by.
2966 Route::shift (nframes64_t /*pos*/, nframes64_t /*frames*/)
2968 #ifdef THIS_NEEDS_FIXING_FOR_V3
2970 /* gain automation */
2971 XMLNode &before = _gain_control->get_state ();
2972 _gain_control->shift (pos, frames);
2973 XMLNode &after = _gain_control->get_state ();
2974 _session.add_command (new MementoCommand<AutomationList> (_gain_automation_curve, &before, &after));
2976 /* pan automation */
2977 for (std::vector<StreamPanner*>::iterator i = _panner->begin (); i != _panner->end (); ++i) {
2978 Curve & c = (*i)->automation ();
2979 XMLNode &before = c.get_state ();
2980 c.shift (pos, frames);
2981 XMLNode &after = c.get_state ();
2982 _session.add_command (new MementoCommand<AutomationList> (c, &before, &after));
2985 /* redirect automation */
2987 Glib::RWLock::ReaderLock lm (redirect_lock);
2988 for (RedirectList::iterator i = _redirects.begin (); i != _redirects.end (); ++i) {
2991 (*i)->what_has_automation (a);
2993 for (set<uint32_t>::const_iterator j = a.begin (); j != a.end (); ++j) {
2994 AutomationList & al = (*i)->automation_list (*j);
2995 XMLNode &before = al.get_state ();
2996 al.shift (pos, frames);
2997 XMLNode &after = al.get_state ();
2998 _session.add_command (new MementoCommand<AutomationList> (al, &before, &after));
3008 Route::save_as_template (const string& path, const string& name)
3010 XMLNode& node (state (false));
3013 IO::set_name_in_state (*node.children().front(), name);
3015 tree.set_root (&node);
3016 return tree.write (path.c_str());
3021 Route::set_name (const string& str)
3027 name = Route::ensure_track_or_route_name (str, _session);
3028 SessionObject::set_name (name);
3030 ret = (_input->set_name(name) && _output->set_name(name));
3034 Glib::RWLock::ReaderLock lm (_processor_lock);
3036 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
3038 /* rename all I/O processors that have inputs or outputs */
3040 boost::shared_ptr<IOProcessor> iop = boost::dynamic_pointer_cast<IOProcessor> (*i);
3042 if (iop && (iop->output() || iop->input())) {
3043 if (!iop->set_name (name)) {
3054 boost::shared_ptr<Send>
3055 Route::internal_send_for (boost::shared_ptr<const Route> target) const
3057 Glib::RWLock::ReaderLock lm (_processor_lock);
3059 for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
3060 boost::shared_ptr<InternalSend> send;
3062 if ((send = boost::dynamic_pointer_cast<InternalSend>(*i)) != 0) {
3063 if (send->target_route() == target) {
3069 return boost::shared_ptr<Send>();
3073 Route::set_phase_invert (bool yn)
3075 if (_phase_invert != yn) {
3076 _phase_invert = 0xffff; // XXX all channels
3077 phase_invert_changed (); /* EMIT SIGNAL */
3082 Route::phase_invert () const
3084 return _phase_invert != 0;
3088 Route::set_denormal_protection (bool yn)
3090 if (_denormal_protection != yn) {
3091 _denormal_protection = yn;
3092 denormal_protection_changed (); /* EMIT SIGNAL */
3097 Route::denormal_protection () const
3099 return _denormal_protection;
3103 Route::set_active (bool yn)
3105 if (_active != yn) {
3107 _input->set_active (yn);
3108 _output->set_active (yn);
3109 active_changed (); // EMIT SIGNAL
3116 Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
3122 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
3124 boost::shared_ptr<Send> s;
3125 boost::shared_ptr<Return> r;
3127 if ((s = boost::dynamic_pointer_cast<Send> (*i)) != 0) {
3128 s->meter()->meter();
3129 } else if ((r = boost::dynamic_pointer_cast<Return> (*i)) != 0) {
3130 r->meter()->meter ();
3135 boost::shared_ptr<Panner>
3136 Route::panner() const
3138 return _main_outs->panner();
3141 boost::shared_ptr<AutomationControl>
3142 Route::gain_control() const
3144 return _amp->gain_control();
3147 boost::shared_ptr<AutomationControl>
3148 Route::get_control (const Evoral::Parameter& param)
3150 /* either we own the control or .... */
3152 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(control (param));
3156 /* maybe one of our processors does or ... */
3158 Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
3159 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
3160 if ((c = boost::dynamic_pointer_cast<AutomationControl>((*i)->control (param))) != 0) {
3168 /* nobody does so we'll make a new one */
3170 c = boost::dynamic_pointer_cast<AutomationControl>(control_factory(param));
3177 boost::shared_ptr<Processor>
3178 Route::nth_plugin (uint32_t n)
3180 Glib::RWLock::ReaderLock lm (_processor_lock);
3181 ProcessorList::iterator i;
3183 for (i = _processors.begin(); i != _processors.end(); ++i) {
3184 if (boost::dynamic_pointer_cast<PluginInsert> (*i)) {
3191 return boost::shared_ptr<Processor> ();
3194 boost::shared_ptr<Processor>
3195 Route::nth_send (uint32_t n)
3197 Glib::RWLock::ReaderLock lm (_processor_lock);
3198 ProcessorList::iterator i;
3200 for (i = _processors.begin(); i != _processors.end(); ++i) {
3201 cerr << "check " << (*i)->name() << endl;
3202 if (boost::dynamic_pointer_cast<Send> (*i)) {
3207 cerr << "\tnot a send\n";
3211 return boost::shared_ptr<Processor> ();