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->is_active() && _route_group->is_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->is_active() && _route_group->is_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->is_active() && _route_group->is_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->is_active() && _route_group->is_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;
1371 if (!_session.engine().connected()) {
1375 processor_max_streams.reset();
1378 Glib::RWLock::WriterLock lm (_processor_lock);
1379 ProcessorList::iterator i;
1380 boost::shared_ptr<Processor> processor;
1382 ProcessorList as_we_were = _processors;
1384 for (i = _processors.begin(); i != _processors.end(); ) {
1388 /* these can never be removed */
1390 if (processor == _amp || processor == _meter || processor == _main_outs) {
1395 /* see if its in the list of processors to delete */
1397 if (find (to_be_deleted.begin(), to_be_deleted.end(), processor) == to_be_deleted.end()) {
1402 /* stop IOProcessors that send to JACK ports
1403 from causing noise as a result of no longer being
1407 boost::shared_ptr<IOProcessor> iop;
1409 if ((iop = boost::dynamic_pointer_cast<IOProcessor> (processor)) != 0) {
1413 deleted.push_back (processor);
1414 i = _processors.erase (i);
1417 if (deleted.empty()) {
1418 /* none of those in the requested list were found */
1422 _output->set_user_latency (0);
1424 if (configure_processors_unlocked (err)) {
1425 /* get back to where we where */
1426 _processors = as_we_were;
1427 /* we know this will work, because it worked before :) */
1428 configure_processors_unlocked (0);
1432 _have_internal_generator = false;
1434 for (i = _processors.begin(); i != _processors.end(); ++i) {
1435 boost::shared_ptr<PluginInsert> pi;
1437 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
1438 if (pi->is_generator()) {
1439 _have_internal_generator = true;
1446 /* now try to do what we need to so that those that were removed will be deleted */
1448 for (ProcessorList::iterator i = deleted.begin(); i != deleted.end(); ++i) {
1449 (*i)->drop_references ();
1452 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1459 Route::configure_processors (ProcessorStreams* err)
1461 if (!_in_configure_processors) {
1462 Glib::RWLock::WriterLock lm (_processor_lock);
1463 return configure_processors_unlocked (err);
1468 /** Configure the input/output configuration of each processor in the processors list.
1469 * Return 0 on success, otherwise configuration is impossible.
1472 Route::configure_processors_unlocked (ProcessorStreams* err)
1474 if (_in_configure_processors) {
1478 _in_configure_processors = true;
1480 // Check each processor in order to see if we can configure as requested
1481 ChanCount in = _input->n_ports ();
1483 list< pair<ChanCount,ChanCount> > configuration;
1486 DEBUG_TRACE (DEBUG::Processors, string_compose ("%1: configure processors\n", _name));
1488 DEBUG_TRACE (DEBUG::Processors, "{\n");
1489 for (list<boost::shared_ptr<Processor> >::const_iterator p = _processors.begin(); p != _processors.end(); ++p) {
1490 DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1 ID = %2\n", (*p)->name(), (*p)->id()));
1492 DEBUG_TRACE (DEBUG::Processors, "}\n");
1495 for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++index) {
1497 if ((*p)->can_support_io_configuration(in, out)) {
1498 DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1in = %2 out = %3\n",(*p)->name(), in, out));
1499 configuration.push_back(make_pair(in, out));
1506 _in_configure_processors = false;
1511 // We can, so configure everything
1512 list< pair<ChanCount,ChanCount> >::iterator c = configuration.begin();
1513 for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++c) {
1514 (*p)->configure_io(c->first, c->second);
1515 processor_max_streams = ChanCount::max(processor_max_streams, c->first);
1516 processor_max_streams = ChanCount::max(processor_max_streams, c->second);
1521 _meter->reset_max_channels (processor_max_streams);
1524 /* make sure we have sufficient scratch buffers to cope with the new processor
1526 _session.ensure_buffers (n_process_buffers ());
1528 _in_configure_processors = false;
1533 Route::all_processors_flip ()
1535 Glib::RWLock::ReaderLock lm (_processor_lock);
1537 if (_processors.empty()) {
1541 bool first_is_on = _processors.front()->active();
1543 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1545 (*i)->deactivate ();
1551 _session.set_dirty ();
1554 /** Set all processors with a given placement to a given active state.
1555 * @param p Placement of processors to change.
1556 * @param state New active state for those processors.
1559 Route::all_processors_active (Placement p, bool state)
1561 Glib::RWLock::ReaderLock lm (_processor_lock);
1563 if (_processors.empty()) {
1566 ProcessorList::iterator start, end;
1567 placement_range(p, start, end);
1569 bool before_amp = true;
1570 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1575 if (p == PreFader && before_amp) {
1579 (*i)->deactivate ();
1584 _session.set_dirty ();
1588 Route::processor_is_prefader (boost::shared_ptr<Processor> p)
1590 bool pre_fader = true;
1591 Glib::RWLock::ReaderLock lm (_processor_lock);
1593 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1595 /* semantic note: if p == amp, we want to return true, so test
1596 for equality before checking if this is the amp
1613 Route::reorder_processors (const ProcessorList& new_order, ProcessorStreams* err)
1615 /* "new_order" is an ordered list of processors to be positioned according to "placement".
1616 NOTE: all processors in "new_order" MUST be marked as display_to_user(). There maybe additional
1617 processors in the current actual processor list that are hidden. Any visible processors
1618 in the current list but not in "new_order" will be assumed to be deleted.
1622 Glib::RWLock::WriterLock lm (_processor_lock);
1623 ChanCount old_pms = processor_max_streams;
1624 ProcessorList::iterator oiter;
1625 ProcessorList::const_iterator niter;
1626 ProcessorList as_it_was_before = _processors;
1627 ProcessorList as_it_will_be;
1629 oiter = _processors.begin();
1630 niter = new_order.begin();
1632 while (niter != new_order.end()) {
1634 /* if the next processor in the old list is invisible (i.e. should not be in the new order)
1635 then append it to the temp list.
1637 Otherwise, see if the next processor in the old list is in the new list. if not,
1638 its been deleted. If its there, append it to the temp list.
1641 if (oiter == _processors.end()) {
1643 /* no more elements in the old list, so just stick the rest of
1644 the new order onto the temp list.
1647 as_it_will_be.insert (as_it_will_be.end(), niter, new_order.end());
1648 while (niter != new_order.end()) {
1655 if (!(*oiter)->display_to_user()) {
1657 as_it_will_be.push_back (*oiter);
1661 /* visible processor: check that its in the new order */
1663 if (find (new_order.begin(), new_order.end(), (*oiter)) == new_order.end()) {
1664 /* deleted: do nothing, shared_ptr<> will clean up */
1666 /* ignore this one, and add the next item from the new order instead */
1667 as_it_will_be.push_back (*niter);
1672 /* now remove from old order - its taken care of no matter what */
1673 oiter = _processors.erase (oiter);
1678 _processors.insert (oiter, as_it_will_be.begin(), as_it_will_be.end());
1680 if (configure_processors_unlocked (err)) {
1681 _processors = as_it_was_before;
1682 processor_max_streams = old_pms;
1687 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1699 Route::get_template()
1701 return state(false);
1705 Route::state(bool full_state)
1707 XMLNode *node = new XMLNode("Route");
1708 ProcessorList::iterator i;
1711 id().print (buf, sizeof (buf));
1712 node->add_property("id", buf);
1713 node->add_property ("name", _name);
1714 node->add_property("default-type", _default_type.to_string());
1717 node->add_property("flags", enum_2_string (_flags));
1720 node->add_property("active", _active?"yes":"no");
1721 node->add_property("phase-invert", _phase_invert?"yes":"no");
1722 node->add_property("denormal-protection", _denormal_protection?"yes":"no");
1723 node->add_property("meter-point", enum_2_string (_meter_point));
1726 node->add_property("route-group", _route_group->name());
1729 string order_string;
1730 OrderKeys::iterator x = order_keys.begin();
1732 while (x != order_keys.end()) {
1733 order_string += string ((*x).first);
1734 order_string += '=';
1735 snprintf (buf, sizeof(buf), "%ld", (*x).second);
1736 order_string += buf;
1740 if (x == order_keys.end()) {
1744 order_string += ':';
1746 node->add_property ("order-keys", order_string);
1747 node->add_property ("self-solo", (_self_solo ? "yes" : "no"));
1748 snprintf (buf, sizeof (buf), "%d", _soloed_by_others);
1749 node->add_property ("soloed-by-others", buf);
1751 node->add_child_nocopy (_input->state (full_state));
1752 node->add_child_nocopy (_output->state (full_state));
1753 node->add_child_nocopy (_solo_control->get_state ());
1754 node->add_child_nocopy (_mute_master->get_state ());
1756 XMLNode* remote_control_node = new XMLNode (X_("RemoteControl"));
1757 snprintf (buf, sizeof (buf), "%d", _remote_control_id);
1758 remote_control_node->add_property (X_("id"), buf);
1759 node->add_child_nocopy (*remote_control_node);
1761 if (_comment.length()) {
1762 XMLNode *cmt = node->add_child ("Comment");
1763 cmt->add_content (_comment);
1766 for (i = _processors.begin(); i != _processors.end(); ++i) {
1767 node->add_child_nocopy((*i)->state (full_state));
1771 node->add_child_copy (*_extra_xml);
1778 Route::set_state (const XMLNode& node, int version)
1780 return _set_state (node, version, true);
1784 Route::_set_state (const XMLNode& node, int version, bool /*call_base*/)
1786 if (version < 3000) {
1787 return _set_state_2X (node, version);
1791 XMLNodeConstIterator niter;
1793 XMLPropertyList plist;
1794 const XMLProperty *prop;
1796 if (node.name() != "Route"){
1797 error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
1801 if ((prop = node.property (X_("name"))) != 0) {
1802 Route::set_name (prop->value());
1805 if ((prop = node.property ("id")) != 0) {
1806 _id = prop->value ();
1809 if ((prop = node.property (X_("flags"))) != 0) {
1810 _flags = Flag (string_2_enum (prop->value(), _flags));
1815 /* add all processors (except amp, which is always present) */
1817 nlist = node.children();
1818 XMLNode processor_state (X_("processor_state"));
1820 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1824 if (child->name() == IO::state_node_name) {
1825 if ((prop = child->property (X_("direction"))) == 0) {
1829 if (prop->value() == "Input") {
1830 _input->set_state (*child, version);
1831 } else if (prop->value() == "Output") {
1832 _output->set_state (*child, version);
1836 if (child->name() == X_("Processor")) {
1837 processor_state.add_child_copy (*child);
1841 set_processor_state (processor_state);
1843 if ((prop = node.property ("self-solo")) != 0) {
1844 set_self_solo (string_is_affirmative (prop->value()));
1847 if ((prop = node.property ("soloed-by-others")) != 0) {
1848 _soloed_by_others = 0; // needed for mod_solo_by_others () to work
1849 mod_solo_by_others (atoi (prop->value()));
1852 if ((prop = node.property ("solo-isolated")) != 0) {
1853 set_solo_isolated (string_is_affirmative (prop->value()), this);
1856 if ((prop = node.property (X_("phase-invert"))) != 0) {
1857 set_phase_invert (string_is_affirmative (prop->value()));
1860 if ((prop = node.property (X_("denormal-protection"))) != 0) {
1861 set_denormal_protection (string_is_affirmative (prop->value()));
1864 if ((prop = node.property (X_("active"))) != 0) {
1865 bool yn = string_is_affirmative (prop->value());
1866 _active = !yn; // force switch
1870 if ((prop = node.property (X_("meter-point"))) != 0) {
1871 _meter_point = MeterPoint (string_2_enum (prop->value (), _meter_point));
1873 _meter->set_display_to_user (_meter_point == MeterCustom);
1877 if ((prop = node.property (X_("order-keys"))) != 0) {
1881 string::size_type colon, equal;
1882 string remaining = prop->value();
1884 while (remaining.length()) {
1886 if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
1887 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1890 if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) {
1891 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1894 set_order_key (remaining.substr (0, equal), n);
1898 colon = remaining.find_first_of (':');
1900 if (colon != string::npos) {
1901 remaining = remaining.substr (colon+1);
1908 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1911 if (child->name() == X_("Comment")) {
1913 /* XXX this is a terrible API design in libxml++ */
1915 XMLNode *cmt = *(child->children().begin());
1916 _comment = cmt->content();
1918 } else if (child->name() == X_("Extra")) {
1920 _extra_xml = new XMLNode (*child);
1922 } else if (child->name() == X_("Controllable") && (prop = child->property("name")) != 0) {
1924 if (prop->value() == "solo") {
1925 _solo_control->set_state (*child, version);
1926 _session.add_controllable (_solo_control);
1929 } else if (child->name() == X_("RemoteControl")) {
1930 if ((prop = child->property (X_("id"))) != 0) {
1932 sscanf (prop->value().c_str(), "%d", &x);
1933 set_remote_control_id (x);
1936 } else if (child->name() == X_("MuteMaster")) {
1937 _mute_master->set_state (*child, version);
1945 Route::_set_state_2X (const XMLNode& node, int version)
1948 XMLNodeConstIterator niter;
1950 XMLPropertyList plist;
1951 const XMLProperty *prop;
1953 /* 2X things which still remain to be handled:
1956 * mute-affects-pre-fader
1957 * mute-affects-post-fader
1958 * mute-affects-control-outs
1959 * mute-affects-main-outs
1964 if (node.name() != "Route") {
1965 error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
1969 if ((prop = node.property (X_("flags"))) != 0) {
1970 _flags = Flag (string_2_enum (prop->value(), _flags));
1975 /* add standard processors */
1977 _meter.reset (new PeakMeter (_session));
1978 add_processor (_meter, PreFader);
1980 if (_flags & ControlOut) {
1981 /* where we listen to tracks */
1982 _intreturn.reset (new InternalReturn (_session));
1983 add_processor (_intreturn, PreFader);
1986 _main_outs.reset (new Delivery (_session, _output, _mute_master, _name, Delivery::Main));
1987 add_processor (_main_outs, PostFader);
1991 nlist = node.children ();
1992 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1996 if (child->name() == IO::state_node_name) {
1998 /* there is a note in IO::set_state_2X() about why we have to call
2002 _input->set_state_2X (*child, version, true);
2003 _output->set_state_2X (*child, version, false);
2005 if ((prop = child->property (X_("name"))) != 0) {
2006 set_name (prop->value ());
2009 if ((prop = child->property (X_("id"))) != 0) {
2010 _id = prop->value ();
2013 if ((prop = child->property (X_("active"))) != 0) {
2014 bool yn = string_is_affirmative (prop->value());
2015 _active = !yn; // force switch
2023 if ((prop = node.property (X_("phase-invert"))) != 0) {
2024 set_phase_invert (string_is_affirmative (prop->value()));
2027 if ((prop = node.property (X_("denormal-protection"))) != 0) {
2028 set_denormal_protection (string_is_affirmative (prop->value()));
2031 if ((prop = node.property (X_("soloed"))) != 0) {
2032 bool yn = string_is_affirmative (prop->value());
2034 /* XXX force reset of solo status */
2036 set_solo (yn, this);
2039 if ((prop = node.property (X_("meter-point"))) != 0) {
2040 _meter_point = MeterPoint (string_2_enum (prop->value (), _meter_point));
2043 /* do not carry over edit/mix groups from 2.X because (a) its hard (b) they
2044 don't mean the same thing.
2047 if ((prop = node.property (X_("order-keys"))) != 0) {
2051 string::size_type colon, equal;
2052 string remaining = prop->value();
2054 while (remaining.length()) {
2056 if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
2057 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
2060 if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) {
2061 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
2064 set_order_key (remaining.substr (0, equal), n);
2068 colon = remaining.find_first_of (':');
2070 if (colon != string::npos) {
2071 remaining = remaining.substr (colon+1);
2078 XMLNodeList redirect_nodes;
2080 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
2084 if (child->name() == X_("Send") || child->name() == X_("Insert")) {
2085 redirect_nodes.push_back(child);
2090 set_processor_state_2X (redirect_nodes, version);
2092 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
2095 if (child->name() == X_("Comment")) {
2097 /* XXX this is a terrible API design in libxml++ */
2099 XMLNode *cmt = *(child->children().begin());
2100 _comment = cmt->content();
2102 } else if (child->name() == X_("Extra")) {
2104 _extra_xml = new XMLNode (*child);
2106 } else if (child->name() == X_("Controllable") && (prop = child->property("name")) != 0) {
2108 if (prop->value() == "solo") {
2109 _solo_control->set_state (*child, version);
2110 _session.add_controllable (_solo_control);
2113 } else if (child->name() == X_("RemoteControl")) {
2114 if ((prop = child->property (X_("id"))) != 0) {
2116 sscanf (prop->value().c_str(), "%d", &x);
2117 set_remote_control_id (x);
2127 Route::get_processor_state ()
2129 XMLNode* root = new XMLNode (X_("redirects"));
2130 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2131 root->add_child_nocopy ((*i)->state (true));
2138 Route::set_processor_state_2X (XMLNodeList const & nList, int version)
2140 /* We don't bother removing existing processors not in nList, as this
2141 method will only be called when creating a Route from scratch, not
2142 for undo purposes. Just put processors in at the appropriate place
2146 for (XMLNodeConstIterator i = nList.begin(); i != nList.end(); ++i) {
2147 add_processor_from_xml_2X (**i, version, _processors.begin ());
2152 Route::set_processor_state (const XMLNode& node)
2154 const XMLNodeList &nlist = node.children();
2155 XMLNodeConstIterator niter;
2156 ProcessorList::iterator i, o;
2158 // Iterate through existing processors, remove those which are not in the state list
2160 for (i = _processors.begin(); i != _processors.end(); ) {
2162 /* leave amp alone, always */
2169 ProcessorList::iterator tmp = i;
2172 bool processorInStateList = false;
2174 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2176 XMLProperty* id_prop = (*niter)->property(X_("id"));
2178 if (id_prop && (*i)->id() == id_prop->value()) {
2179 processorInStateList = true;
2184 if (!processorInStateList) {
2185 remove_processor (*i);
2191 // Iterate through state list and make sure all processors are on the track and in the correct order,
2192 // set the state of existing processors according to the new state on the same go
2194 i = _processors.begin();
2196 for (niter = nlist.begin(); niter != nlist.end(); ++niter, ++i) {
2198 XMLProperty* prop = (*niter)->property ("type");
2202 // Check whether the next processor in the list is the right one,
2203 // except for "amp" which is always there and may not have the
2204 // old ID since it is always created anew in every Route
2206 if (prop->value() != "amp") {
2207 while (o != _processors.end()) {
2208 XMLProperty* id_prop = (*niter)->property(X_("id"));
2209 if (id_prop && (*o)->id() == id_prop->value()) {
2217 // If the processor (*niter) is not on the route,
2218 // create it and move it to the correct location
2220 if (o == _processors.end()) {
2222 if (add_processor_from_xml (**niter, i)) {
2223 --i; // move iterator to the newly inserted processor
2225 cerr << "Error restoring route: unable to restore processor" << endl;
2230 // Otherwise, the processor already exists; just
2231 // ensure it is at the location provided in the XML state
2234 boost::shared_ptr<Processor> tmp = (*o);
2235 _processors.erase (o); // remove the old copy
2236 _processors.insert (i, tmp); // insert the processor at the correct location
2237 --i; // move iterator to the correct processor
2240 // and make it (just) so
2242 (*i)->set_state (**niter, Stateful::current_state_version);
2246 /* note: there is no configure_processors() call because we figure that
2247 the XML state represents a working signal route.
2250 processors_changed (RouteProcessorChange ());
2254 Route::curve_reallocate ()
2256 // _gain_automation_curve.finish_resize ();
2257 // _pan_automation_curve.finish_resize ();
2261 Route::silence (nframes_t nframes)
2265 _output->silence (nframes);
2268 Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
2271 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2272 boost::shared_ptr<PluginInsert> pi;
2274 if (!_active && (pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
2275 // skip plugins, they don't need anything when we're not active
2279 (*i)->silence (nframes);
2282 if (nframes == _session.get_block_size()) {
2292 Route::add_internal_return ()
2295 _intreturn.reset (new InternalReturn (_session));
2296 add_processor (_intreturn, PreFader);
2301 Route::get_return_buffer () const
2303 Glib::RWLock::ReaderLock rm (_processor_lock);
2305 for (ProcessorList::const_iterator x = _processors.begin(); x != _processors.end(); ++x) {
2306 boost::shared_ptr<InternalReturn> d = boost::dynamic_pointer_cast<InternalReturn>(*x);
2309 BufferSet* bs = d->get_buffers ();
2318 Route::release_return_buffer () const
2320 Glib::RWLock::ReaderLock rm (_processor_lock);
2322 for (ProcessorList::const_iterator x = _processors.begin(); x != _processors.end(); ++x) {
2323 boost::shared_ptr<InternalReturn> d = boost::dynamic_pointer_cast<InternalReturn>(*x);
2326 return d->release_buffers ();
2332 Route::listen_via (boost::shared_ptr<Route> route, Placement placement, bool /*active*/, bool aux)
2334 vector<string> ports;
2335 vector<string>::const_iterator i;
2338 Glib::RWLock::ReaderLock rm (_processor_lock);
2340 for (ProcessorList::iterator x = _processors.begin(); x != _processors.end(); ++x) {
2342 boost::shared_ptr<InternalSend> d = boost::dynamic_pointer_cast<InternalSend>(*x);
2344 if (d && d->target_route() == route) {
2346 /* if the target is the control outs, then make sure
2347 we take note of which i-send is doing that.
2350 if (route == _session.control_out()) {
2351 _control_outs = boost::dynamic_pointer_cast<Delivery>(d);
2354 /* already listening via the specified IO: do nothing */
2361 boost::shared_ptr<InternalSend> listener;
2364 listener.reset (new InternalSend (_session, _mute_master, route, (aux ? Delivery::Aux : Delivery::Listen)));
2366 } catch (failed_constructor& err) {
2370 if (route == _session.control_out()) {
2371 _control_outs = listener;
2374 add_processor (listener, placement);
2380 Route::drop_listen (boost::shared_ptr<Route> route)
2382 ProcessorStreams err;
2383 ProcessorList::iterator tmp;
2385 Glib::RWLock::ReaderLock rl(_processor_lock);
2389 for (ProcessorList::iterator x = _processors.begin(); x != _processors.end(); ) {
2391 boost::shared_ptr<InternalSend> d = boost::dynamic_pointer_cast<InternalSend>(*x);
2393 if (d && d->target_route() == route) {
2395 remove_processor (*x, &err);
2398 /* list could have been demolished while we dropped the lock
2408 if (route == _session.control_out()) {
2409 _control_outs.reset ();
2414 Route::set_comment (string cmt, void *src)
2417 comment_changed (src);
2418 _session.set_dirty ();
2422 Route::feeds (boost::shared_ptr<Route> other, bool* only_send)
2424 DEBUG_TRACE (DEBUG::Graph, string_compose ("Feeds? %1\n", _name));
2426 if (_output->connected_to (other->input())) {
2427 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tdirect FEEDS %2\n", other->name()));
2436 for (ProcessorList::iterator r = _processors.begin(); r != _processors.end(); ++r) {
2438 boost::shared_ptr<IOProcessor> iop;
2440 if ((iop = boost::dynamic_pointer_cast<IOProcessor>(*r)) != 0) {
2441 if (iop->feeds (other)) {
2442 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tIOP %1 does feed %2\n", iop->name(), other->name()));
2448 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tIOP %1 does NOT feed %2\n", iop->name(), other->name()));
2451 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tPROC %1 is not an IOP\n", (*r)->name()));
2456 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tdoes NOT feed %1\n", other->name()));
2461 Route::handle_transport_stopped (bool /*abort_ignored*/, bool did_locate, bool can_flush_processors)
2463 nframes_t now = _session.transport_frame();
2466 Glib::RWLock::ReaderLock lm (_processor_lock);
2469 automation_snapshot (now, true);
2472 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2474 if (Config->get_plugins_stop_with_transport() && can_flush_processors) {
2475 (*i)->deactivate ();
2479 (*i)->transport_stopped (now);
2483 _roll_delay = _initial_delay;
2487 Route::input_change_handler (IOChange change, void * /*src*/)
2489 if ((change & ConfigurationChanged)) {
2490 configure_processors (0);
2495 Route::output_change_handler (IOChange change, void * /*src*/)
2497 if ((change & ConfigurationChanged)) {
2499 /* XXX resize all listeners to match _main_outs? */
2501 // configure_processors (0);
2506 Route::pans_required () const
2508 if (n_outputs().n_audio() < 2) {
2512 return max (n_inputs ().n_audio(), processor_max_streams.n_audio());
2516 Route::no_roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame,
2517 bool session_state_changing, bool /*can_record*/, bool /*rec_monitors_input*/)
2519 if (n_outputs().n_total() == 0) {
2523 if (!_active || n_inputs() == ChanCount::ZERO) {
2527 if (session_state_changing) {
2528 if (_session.transport_speed() != 0.0f) {
2529 /* we're rolling but some state is changing (e.g. our diskstream contents)
2530 so we cannot use them. Be silent till this is over.
2532 XXX note the absurdity of ::no_roll() being called when we ARE rolling!
2537 /* we're really not rolling, so we're either delivery silence or actually
2538 monitoring, both of which are safe to do while session_state_changing is true.
2542 _amp->apply_gain_automation (false);
2543 passthru (start_frame, end_frame, nframes, 0);
2549 Route::check_initial_delay (nframes_t nframes, nframes_t& transport_frame)
2551 if (_roll_delay > nframes) {
2553 _roll_delay -= nframes;
2555 /* transport frame is not legal for caller to use */
2558 } else if (_roll_delay > 0) {
2560 nframes -= _roll_delay;
2561 silence (_roll_delay);
2562 /* we've written _roll_delay of samples into the
2563 output ports, so make a note of that for
2566 _main_outs->increment_output_offset (_roll_delay);
2567 transport_frame += _roll_delay;
2576 Route::roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame, int declick,
2577 bool /*can_record*/, bool /*rec_monitors_input*/)
2580 // automation snapshot can also be called from the non-rt context
2581 // and it uses the processor list, so we try to acquire the lock here
2582 Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
2585 automation_snapshot (_session.transport_frame(), false);
2589 if (n_outputs().n_total() == 0) {
2593 if (!_active || n_inputs().n_total() == 0) {
2598 nframes_t unused = 0;
2600 if ((nframes = check_initial_delay (nframes, unused)) == 0) {
2606 passthru (start_frame, end_frame, nframes, declick);
2612 Route::silent_roll (nframes_t nframes, sframes_t /*start_frame*/, sframes_t /*end_frame*/,
2613 bool /*can_record*/, bool /*rec_monitors_input*/)
2620 Route::toggle_monitor_input ()
2622 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
2623 i->ensure_monitor_input( ! i->monitoring_input());
2628 Route::has_external_redirects () const
2630 // FIXME: what about sends? - they don't return a signal back to ardour?
2632 boost::shared_ptr<const PortInsert> pi;
2634 for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
2636 if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*i)) != 0) {
2638 for (PortSet::const_iterator port = pi->output()->ports().begin(); port != pi->output()->ports().end(); ++port) {
2640 string port_name = port->name();
2641 string client_name = port_name.substr (0, port_name.find(':'));
2643 /* only say "yes" if the redirect is actually in use */
2645 if (client_name != "ardour" && pi->active()) {
2656 Route::flush_processors ()
2658 /* XXX shouldn't really try to take this lock, since
2659 this is called from the RT audio thread.
2662 Glib::RWLock::ReaderLock lm (_processor_lock);
2664 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2665 (*i)->deactivate ();
2671 Route::set_meter_point (MeterPoint p, void *src)
2673 /* CAN BE CALLED FROM PROCESS CONTEXT */
2675 if (_meter_point == p) {
2679 bool meter_was_visible_to_user = _meter->display_to_user ();
2682 Glib::RWLock::WriterLock lm (_processor_lock);
2684 if (p != MeterCustom) {
2685 // Move meter in the processors list to reflect the new position
2686 ProcessorList::iterator loc = find (_processors.begin(), _processors.end(), _meter);
2687 _processors.erase(loc);
2690 loc = _processors.begin();
2693 loc = find (_processors.begin(), _processors.end(), _amp);
2695 case MeterPostFader:
2696 loc = _processors.end();
2704 if (loc == _processors.begin()) {
2705 m_in = _input->n_ports();
2707 ProcessorList::iterator before = loc;
2709 m_in = (*before)->output_streams ();
2712 _meter->reflect_inputs (m_in);
2714 _processors.insert (loc, _meter);
2716 /* we do not need to reconfigure the processors, because the meter
2717 (a) is always ready to handle processor_max_streams
2718 (b) is always an N-in/N-out processor, and thus moving
2719 it doesn't require any changes to the other processors.
2722 _meter->set_display_to_user (false);
2726 // just make it visible and let the user move it
2728 _meter->set_display_to_user (true);
2733 meter_change (src); /* EMIT SIGNAL */
2735 bool const meter_visibly_changed = (_meter->display_to_user() != meter_was_visible_to_user);
2737 processors_changed (RouteProcessorChange (RouteProcessorChange::MeterPointChange, meter_visibly_changed)); /* EMIT SIGNAL */
2741 Route::put_control_outs_at (Placement p)
2743 if (!_control_outs) {
2748 Glib::RWLock::WriterLock lm (_processor_lock);
2749 ProcessorList as_it_was (_processors);
2750 // Move meter in the processors list
2751 ProcessorList::iterator loc = find(_processors.begin(), _processors.end(), _control_outs);
2752 _processors.erase(loc);
2756 loc = find(_processors.begin(), _processors.end(), _amp);
2757 if (loc != _processors.begin()) {
2762 loc = find(_processors.begin(), _processors.end(), _amp);
2763 assert (loc != _processors.end());
2768 _processors.insert(loc, _control_outs);
2770 if (configure_processors_unlocked (0)) {
2771 _processors = as_it_was;
2772 configure_processors_unlocked (0); // it worked before we tried to add it ...
2777 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
2778 _session.set_dirty ();
2782 Route::update_total_latency ()
2784 nframes_t old = _output->effective_latency();
2785 nframes_t own_latency = _output->user_latency();
2787 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2788 if ((*i)->active ()) {
2789 own_latency += (*i)->signal_latency ();
2793 DEBUG_TRACE (DEBUG::Latency, string_compose ("%1: internal redirect latency = %2\n", _name, own_latency));
2795 _output->set_port_latency (own_latency);
2797 if (_output->user_latency() == 0) {
2799 /* this (virtual) function is used for pure Routes,
2800 not derived classes like AudioTrack. this means
2801 that the data processed here comes from an input
2802 port, not prerecorded material, and therefore we
2803 have to take into account any input latency.
2806 own_latency += _input->signal_latency ();
2809 if (old != own_latency) {
2810 _output->set_latency_delay (own_latency);
2811 signal_latency_changed (); /* EMIT SIGNAL */
2814 DEBUG_TRACE (DEBUG::Latency, string_compose ("%1: input latency = %2 total = %3\n", _name, _input->signal_latency(), own_latency));
2816 return _output->effective_latency ();
2820 Route::set_user_latency (nframes_t nframes)
2822 _output->set_user_latency (nframes);
2823 _session.update_latency_compensation (false, false);
2827 Route::set_latency_delay (nframes_t longest_session_latency)
2829 nframes_t old = _initial_delay;
2831 if (_output->effective_latency() < longest_session_latency) {
2832 _initial_delay = longest_session_latency - _output->effective_latency();
2837 if (_initial_delay != old) {
2838 initial_delay_changed (); /* EMIT SIGNAL */
2841 if (_session.transport_stopped()) {
2842 _roll_delay = _initial_delay;
2847 Route::automation_snapshot (nframes_t now, bool force)
2849 panner()->automation_snapshot (now, force);
2851 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2852 (*i)->automation_snapshot (now, force);
2856 Route::SoloControllable::SoloControllable (std::string name, Route& r)
2857 : AutomationControl (r.session(), Evoral::Parameter (SoloAutomation),
2858 boost::shared_ptr<AutomationList>(), name)
2861 boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloAutomation)));
2866 Route::SoloControllable::set_value (float val)
2868 bool bval = ((val >= 0.5f) ? true: false);
2870 this is how it should be done
2872 boost::shared_ptr<RouteList> rl (new RouteList);
2873 rl->push_back (route);
2875 if (Config->get_solo_control_is_listen_control()) {
2876 _session.set_listen (rl, bval);
2878 _session.set_solo (rl, bval);
2881 route.set_solo (bval, this);
2886 Route::SoloControllable::get_value (void) const
2888 if (Config->get_solo_control_is_listen_control()) {
2889 return route.listening() ? 1.0f : 0.0f;
2891 return route.self_soloed() ? 1.0f : 0.0f;
2895 Route::MuteControllable::MuteControllable (std::string name, Route& r)
2896 : AutomationControl (r.session(), Evoral::Parameter (MuteAutomation),
2897 boost::shared_ptr<AutomationList>(), name)
2900 boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(MuteAutomation)));
2905 Route::MuteControllable::set_value (float val)
2907 bool bval = ((val >= 0.5f) ? true: false);
2909 this is how it should be done
2911 boost::shared_ptr<RouteList> rl (new RouteList);
2912 rl->push_back (route);
2913 _session.set_mute (rl, bval);
2915 route.set_mute (bval, this);
2920 Route::MuteControllable::get_value (void) const
2922 return route.muted() ? 1.0f : 0.0f;
2926 Route::set_block_size (nframes_t nframes)
2928 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2929 (*i)->set_block_size (nframes);
2932 _session.ensure_buffers (n_process_buffers ());
2936 Route::protect_automation ()
2938 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i)
2939 (*i)->protect_automation();
2943 Route::set_pending_declick (int declick)
2946 /* this call is not allowed to turn off a pending declick unless "force" is true */
2948 _pending_declick = declick;
2950 // cerr << _name << ": after setting to " << declick << " pending declick = " << _pending_declick << endl;
2952 _pending_declick = 0;
2957 /** Shift automation forwards from a particular place, thereby inserting time.
2958 * Adds undo commands for any shifts that are performed.
2960 * @param pos Position to start shifting from.
2961 * @param frames Amount to shift forwards by.
2965 Route::shift (nframes64_t /*pos*/, nframes64_t /*frames*/)
2967 #ifdef THIS_NEEDS_FIXING_FOR_V3
2969 /* gain automation */
2970 XMLNode &before = _gain_control->get_state ();
2971 _gain_control->shift (pos, frames);
2972 XMLNode &after = _gain_control->get_state ();
2973 _session.add_command (new MementoCommand<AutomationList> (_gain_automation_curve, &before, &after));
2975 /* pan automation */
2976 for (std::vector<StreamPanner*>::iterator i = _panner->begin (); i != _panner->end (); ++i) {
2977 Curve & c = (*i)->automation ();
2978 XMLNode &before = c.get_state ();
2979 c.shift (pos, frames);
2980 XMLNode &after = c.get_state ();
2981 _session.add_command (new MementoCommand<AutomationList> (c, &before, &after));
2984 /* redirect automation */
2986 Glib::RWLock::ReaderLock lm (redirect_lock);
2987 for (RedirectList::iterator i = _redirects.begin (); i != _redirects.end (); ++i) {
2990 (*i)->what_has_automation (a);
2992 for (set<uint32_t>::const_iterator j = a.begin (); j != a.end (); ++j) {
2993 AutomationList & al = (*i)->automation_list (*j);
2994 XMLNode &before = al.get_state ();
2995 al.shift (pos, frames);
2996 XMLNode &after = al.get_state ();
2997 _session.add_command (new MementoCommand<AutomationList> (al, &before, &after));
3007 Route::save_as_template (const string& path, const string& name)
3009 XMLNode& node (state (false));
3012 IO::set_name_in_state (*node.children().front(), name);
3014 tree.set_root (&node);
3015 return tree.write (path.c_str());
3020 Route::set_name (const string& str)
3026 name = Route::ensure_track_or_route_name (str, _session);
3027 SessionObject::set_name (name);
3029 ret = (_input->set_name(name) && _output->set_name(name));
3033 Glib::RWLock::ReaderLock lm (_processor_lock);
3035 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
3037 /* rename all I/O processors that have inputs or outputs */
3039 boost::shared_ptr<IOProcessor> iop = boost::dynamic_pointer_cast<IOProcessor> (*i);
3041 if (iop && (iop->output() || iop->input())) {
3042 if (!iop->set_name (name)) {
3053 boost::shared_ptr<Send>
3054 Route::internal_send_for (boost::shared_ptr<const Route> target) const
3056 Glib::RWLock::ReaderLock lm (_processor_lock);
3058 for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
3059 boost::shared_ptr<InternalSend> send;
3061 if ((send = boost::dynamic_pointer_cast<InternalSend>(*i)) != 0) {
3062 if (send->target_route() == target) {
3068 return boost::shared_ptr<Send>();
3072 Route::set_phase_invert (bool yn)
3074 if (_phase_invert != yn) {
3075 _phase_invert = 0xffff; // XXX all channels
3076 phase_invert_changed (); /* EMIT SIGNAL */
3081 Route::phase_invert () const
3083 return _phase_invert != 0;
3087 Route::set_denormal_protection (bool yn)
3089 if (_denormal_protection != yn) {
3090 _denormal_protection = yn;
3091 denormal_protection_changed (); /* EMIT SIGNAL */
3096 Route::denormal_protection () const
3098 return _denormal_protection;
3102 Route::set_active (bool yn)
3104 if (_active != yn) {
3106 _input->set_active (yn);
3107 _output->set_active (yn);
3108 active_changed (); // EMIT SIGNAL
3115 Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
3121 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
3123 boost::shared_ptr<Send> s;
3124 boost::shared_ptr<Return> r;
3126 if ((s = boost::dynamic_pointer_cast<Send> (*i)) != 0) {
3127 s->meter()->meter();
3128 } else if ((r = boost::dynamic_pointer_cast<Return> (*i)) != 0) {
3129 r->meter()->meter ();
3134 boost::shared_ptr<Panner>
3135 Route::panner() const
3137 return _main_outs->panner();
3140 boost::shared_ptr<AutomationControl>
3141 Route::gain_control() const
3143 return _amp->gain_control();
3146 boost::shared_ptr<AutomationControl>
3147 Route::get_control (const Evoral::Parameter& param)
3149 /* either we own the control or .... */
3151 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(control (param));
3155 /* maybe one of our processors does or ... */
3157 Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
3158 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
3159 if ((c = boost::dynamic_pointer_cast<AutomationControl>((*i)->control (param))) != 0) {
3167 /* nobody does so we'll make a new one */
3169 c = boost::dynamic_pointer_cast<AutomationControl>(control_factory(param));
3176 boost::shared_ptr<Processor>
3177 Route::nth_plugin (uint32_t n)
3179 Glib::RWLock::ReaderLock lm (_processor_lock);
3180 ProcessorList::iterator i;
3182 for (i = _processors.begin(); i != _processors.end(); ++i) {
3183 if (boost::dynamic_pointer_cast<PluginInsert> (*i)) {
3190 return boost::shared_ptr<Processor> ();
3193 boost::shared_ptr<Processor>
3194 Route::nth_send (uint32_t n)
3196 Glib::RWLock::ReaderLock lm (_processor_lock);
3197 ProcessorList::iterator i;
3199 for (i = _processors.begin(); i != _processors.end(); ++i) {
3200 cerr << "check " << (*i)->name() << endl;
3201 if (boost::dynamic_pointer_cast<Send> (*i)) {
3206 cerr << "\tnot a send\n";
3210 return boost::shared_ptr<Processor> ();