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"
30 #include "evoral/Curve.hpp"
32 #include "ardour/amp.h"
33 #include "ardour/audio_port.h"
34 #include "ardour/audioengine.h"
35 #include "ardour/buffer.h"
36 #include "ardour/buffer_set.h"
37 #include "ardour/configuration.h"
38 #include "ardour/cycle_timer.h"
39 #include "ardour/debug.h"
40 #include "ardour/delivery.h"
41 #include "ardour/dB.h"
42 #include "ardour/internal_send.h"
43 #include "ardour/internal_return.h"
44 #include "ardour/ladspa_plugin.h"
45 #include "ardour/meter.h"
46 #include "ardour/mix.h"
47 #include "ardour/panner.h"
48 #include "ardour/plugin_insert.h"
49 #include "ardour/port.h"
50 #include "ardour/port_insert.h"
51 #include "ardour/processor.h"
52 #include "ardour/profile.h"
53 #include "ardour/route.h"
54 #include "ardour/route_group.h"
55 #include "ardour/send.h"
56 #include "ardour/session.h"
57 #include "ardour/timestamps.h"
58 #include "ardour/utils.h"
63 using namespace ARDOUR;
66 uint32_t Route::order_key_cnt = 0;
67 PBD::Signal1<void,string const&> Route::SyncOrderKeys;
68 PBD::Signal0<void> Route::RemoteControlIDChange;
70 Route::Route (Session& sess, string name, Flag flg, DataType default_type)
71 : SessionObject (sess, name)
72 , AutomatableControls (sess)
74 , _solo_control (new SoloControllable (X_("solo"), *this))
75 , _mute_control (new MuteControllable (X_("mute"), *this))
76 , _mute_master (new MuteMaster (sess, name))
77 , _default_type (default_type)
82 /* add standard processors other than amp (added by ::init()) */
84 _meter.reset (new PeakMeter (_session));
85 _meter->set_display_to_user (false);
86 add_processor (_meter, PostFader);
88 if (_flags & ControlOut) {
89 /* where we listen to tracks */
90 _intreturn.reset (new InternalReturn (_session));
91 add_processor (_intreturn, PreFader);
94 _main_outs.reset (new Delivery (_session, _output, _mute_master, _name, Delivery::Main));
95 add_processor (_main_outs, PostFader);
97 /* now that we have _meter, its safe to connect to this */
99 Metering::Meter.connect_same_thread (*this, (boost::bind (&Route::meter, this)));
102 Route::Route (Session& sess, const XMLNode& node, DataType default_type)
103 : SessionObject (sess, "toBeReset")
104 , AutomatableControls (sess)
105 , _solo_control (new SoloControllable (X_("solo"), *this))
106 , _mute_control (new MuteControllable (X_("mute"), *this))
107 , _mute_master (new MuteMaster (sess, "toBeReset"))
108 , _default_type (default_type)
112 _set_state (node, Stateful::loading_state_version, false);
114 /* now that we have _meter, its safe to connect to this */
116 Metering::Meter.connect_same_thread (*this, (boost::bind (&Route::meter, this)));
123 _soloed_by_others = 0;
127 processor_max_streams.reset();
129 order_keys[N_("signal")] = order_key_cnt++;
131 _meter_point = MeterPostFader;
134 _have_internal_generator = false;
135 _declickable = false;
136 _pending_declick = true;
137 _remote_control_id = 0;
138 _in_configure_processors = false;
139 _mute_points = MuteMaster::AllPoints;
142 _denormal_protection = false;
144 /* add standard controls */
146 _solo_control->set_flags (Controllable::Flag (_solo_control->flags() | Controllable::Toggle));
147 _mute_control->set_flags (Controllable::Flag (_solo_control->flags() | Controllable::Toggle));
149 add_control (_solo_control);
150 add_control (_mute_control);
152 /* input and output objects */
154 _input.reset (new IO (_session, _name, IO::Input, _default_type));
155 _output.reset (new IO (_session, _name, IO::Output, _default_type));
157 _input->changed.connect_same_thread (*this, boost::bind (&Route::input_change_handler, this, _1, _2));
158 _output->changed.connect_same_thread (*this, boost::bind (&Route::output_change_handler, this, _1, _2));
160 /* add amp processor */
162 _amp.reset (new Amp (_session, _mute_master));
163 add_processor (_amp, PostFader);
168 DEBUG_TRACE (DEBUG::Destruction, string_compose ("route %1 destructor\n", _name));
170 /* do this early so that we don't get incoming signals as we are going through destruction
175 /* don't use clear_processors here, as it depends on the session which may
176 be half-destroyed by now
179 Glib::RWLock::WriterLock lm (_processor_lock);
180 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
181 (*i)->drop_references ();
184 _processors.clear ();
188 Route::set_remote_control_id (uint32_t id, bool notify_class_listeners)
190 if (id != _remote_control_id) {
191 _remote_control_id = id;
192 RemoteControlIDChanged ();
193 if (notify_class_listeners) {
194 RemoteControlIDChange ();
200 Route::remote_control_id() const
202 return _remote_control_id;
206 Route::order_key (std::string const & name) const
208 OrderKeys::const_iterator i = order_keys.find (name);
209 if (i == order_keys.end()) {
217 Route::set_order_key (std::string const & name, long n)
219 order_keys[name] = n;
221 if (Config->get_sync_all_route_ordering()) {
222 for (OrderKeys::iterator x = order_keys.begin(); x != order_keys.end(); ++x) {
227 _session.set_dirty ();
230 /** Set all order keys to be the same as that for `base', if such a key
231 * exists in this route.
232 * @param base Base key.
235 Route::sync_order_keys (std::string const & base)
237 if (order_keys.empty()) {
241 OrderKeys::iterator i;
244 if ((i = order_keys.find (base)) == order_keys.end()) {
245 /* key doesn't exist, use the first existing key (during session initialization) */
246 i = order_keys.begin();
250 /* key exists - use it and reset all others (actually, itself included) */
252 i = order_keys.begin();
255 for (; i != order_keys.end(); ++i) {
261 Route::ensure_track_or_route_name(string name, Session &session)
263 string newname = name;
265 while (session.route_by_name (newname) != NULL) {
266 newname = bump_name_once (newname);
274 Route::inc_gain (gain_t fraction, void *src)
276 _amp->inc_gain (fraction, src);
280 Route::set_gain (gain_t val, void *src)
282 if (src != 0 && _route_group && src != _route_group && _route_group->active_property (RouteGroup::Gain)) {
284 if (_route_group->is_relative()) {
286 gain_t usable_gain = _amp->gain();
287 if (usable_gain < 0.000001f) {
288 usable_gain = 0.000001f;
292 if (delta < 0.000001f) {
296 delta -= usable_gain;
301 gain_t factor = delta / usable_gain;
304 factor = _route_group->get_max_factor(factor);
305 if (factor == 0.0f) {
306 _amp->gain_control()->Changed(); /* EMIT SIGNAL */
310 factor = _route_group->get_min_factor(factor);
311 if (factor == 0.0f) {
312 _amp->gain_control()->Changed(); /* EMIT SIGNAL */
317 _route_group->apply (&Route::inc_gain, factor, _route_group);
321 _route_group->apply (&Route::set_gain, val, _route_group);
327 if (val == _amp->gain()) {
331 _amp->set_gain (val, src);
334 /** Process this route for one (sub) cycle (process thread)
336 * @param bufs Scratch buffers to use for the signal path
337 * @param start_frame Initial transport frame
338 * @param end_frame Final transport frame
339 * @param nframes Number of frames to output (to ports)
341 * Note that (end_frame - start_frame) may not be equal to nframes when the
342 * transport speed isn't 1.0 (eg varispeed).
345 Route::process_output_buffers (BufferSet& bufs,
346 sframes_t start_frame, sframes_t end_frame, nframes_t nframes,
347 bool /*with_processors*/, int declick)
351 bufs.is_silent (false);
353 switch (Config->get_monitoring_model()) {
354 case HardwareMonitoring:
355 case ExternalMonitoring:
356 monitor = !record_enabled() || (_session.config.get_auto_input() && !_session.actively_recording());
363 declick = _pending_declick;
366 /* figure out if we're going to use gain automation */
367 _amp->setup_gain_automation (start_frame, end_frame, nframes);
370 /* tell main outs what to do about monitoring */
371 _main_outs->no_outs_cuz_we_no_monitor (!monitor);
374 /* -------------------------------------------------------------------------------------------
375 GLOBAL DECLICK (for transport changes etc.)
376 ----------------------------------------------------------------------------------------- */
379 Amp::apply_gain (bufs, nframes, 0.0, 1.0);
380 } else if (declick < 0) {
381 Amp::apply_gain (bufs, nframes, 1.0, 0.0);
384 _pending_declick = 0;
386 /* -------------------------------------------------------------------------------------------
387 DENORMAL CONTROL/PHASE INVERT
388 ----------------------------------------------------------------------------------------- */
394 if (_denormal_protection || Config->get_denormal_protection()) {
396 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i, ++chn) {
397 Sample* const sp = i->data();
399 if (_phase_invert & chn) {
400 for (nframes_t nx = 0; nx < nframes; ++nx) {
405 for (nframes_t nx = 0; nx < nframes; ++nx) {
413 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i, ++chn) {
414 Sample* const sp = i->data();
416 if (_phase_invert & chn) {
417 for (nframes_t nx = 0; nx < nframes; ++nx) {
426 if (_denormal_protection || Config->get_denormal_protection()) {
428 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
429 Sample* const sp = i->data();
430 for (nframes_t nx = 0; nx < nframes; ++nx) {
438 /* -------------------------------------------------------------------------------------------
440 ----------------------------------------------------------------------------------------- */
442 Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
445 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
447 if (bufs.count() != (*i)->input_streams()) {
448 cerr << _name << " bufs = " << bufs.count()
449 << " input for " << (*i)->name() << " = " << (*i)->input_streams()
452 assert (bufs.count() == (*i)->input_streams());
454 (*i)->run (bufs, start_frame, end_frame, nframes, *i != _processors.back());
455 bufs.set_count (ChanCount::max(bufs.count(), (*i)->output_streams()));
458 if (!_processors.empty()) {
459 bufs.set_count (ChanCount::max (bufs.count(), _processors.back()->output_streams()));
465 Route::n_process_buffers ()
467 return max (_input->n_ports(), processor_max_streams);
471 Route::passthru (sframes_t start_frame, sframes_t end_frame, nframes_t nframes, int declick)
473 BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers());
477 assert (bufs.available() >= _input->n_ports());
479 if (_input->n_ports() == ChanCount::ZERO) {
483 bufs.set_count (_input->n_ports());
485 if (is_control() && _session.listening()) {
487 /* control/monitor bus ignores input ports when something is
488 feeding the listen "stream". data will "arrive" into the
489 route from the intreturn processor element.
492 bufs.silence (nframes, 0);
496 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
498 BufferSet::iterator o = bufs.begin(*t);
499 PortSet& ports (_input->ports());
501 for (PortSet::iterator i = ports.begin(*t); i != ports.end(*t); ++i, ++o) {
502 o->read_from (i->get_buffer(nframes), nframes);
507 write_out_of_band_data (bufs, start_frame, end_frame, nframes);
508 process_output_buffers (bufs, start_frame, end_frame, nframes, true, declick);
512 Route::passthru_silence (sframes_t start_frame, sframes_t end_frame, nframes_t nframes, int declick)
514 BufferSet& bufs (_session.get_silent_buffers (n_process_buffers()));
515 bufs.set_count (_input->n_ports());
516 write_out_of_band_data (bufs, start_frame, end_frame, nframes);
517 process_output_buffers (bufs, start_frame, end_frame, nframes, true, declick);
521 Route::set_listen (bool yn, void* src)
524 if (yn != _control_outs->active()) {
526 _control_outs->activate ();
528 _control_outs->deactivate ();
531 listen_changed (src); /* EMIT SIGNAL */
537 Route::listening () const
540 return _control_outs->active ();
547 Route::set_solo_safe (bool yn, void *src)
549 if (_solo_safe != yn) {
551 solo_safe_changed (src);
556 Route::solo_safe() const
562 Route::set_solo (bool yn, void *src)
568 if (_route_group && src != _route_group && _route_group->active_property (RouteGroup::Solo)) {
569 _route_group->apply (&Route::set_solo, yn, _route_group);
573 if (self_soloed() != yn) {
575 set_delivery_solo ();
576 solo_changed (src); /* EMIT SIGNAL */
577 _solo_control->Changed (); /* EMIT SIGNAL */
582 Route::set_self_solo (bool yn)
588 Route::mod_solo_by_others (int32_t delta)
591 if (_soloed_by_others >= (uint32_t) delta) {
592 _soloed_by_others += delta;
594 _soloed_by_others = 0;
597 _soloed_by_others += delta;
600 set_delivery_solo ();
604 Route::set_delivery_solo ()
606 /* tell all delivery processors what the solo situation is, so that they keep
607 delivering even though Session::soloing() is true and they were not
611 Glib::RWLock::ReaderLock rm (_processor_lock);
612 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
613 boost::shared_ptr<Delivery> d;
615 if ((d = boost::dynamic_pointer_cast<Delivery> (*i)) != 0) {
616 d->set_solo_level (soloed ());
617 d->set_solo_isolated (solo_isolated());
623 Route::set_solo_isolated (bool yn, void *src)
625 if (is_master() || is_control() || is_hidden()) {
629 if (_route_group && src != _route_group && _route_group->active_property (RouteGroup::Solo)) {
630 _route_group->apply (&Route::set_solo_isolated, yn, _route_group);
634 /* forward propagate solo-isolate status to everything fed by this route, but not those via sends only */
636 boost::shared_ptr<RouteList> routes = _session.get_routes ();
637 for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
639 bool does_feed = feeds (*i, &sends_only);
641 if (does_feed && !sends_only) {
642 (*i)->set_solo_isolated (yn, (*i)->route_group());
646 bool changed = false;
649 if (_solo_isolated == 0) {
654 changed = (_solo_isolated == 1);
655 if (_solo_isolated > 0) {
661 set_delivery_solo ();
662 solo_isolated_changed (src);
667 Route::solo_isolated () const
669 return _solo_isolated > 0;
673 Route::set_mute_points (MuteMaster::MutePoint mp)
676 mute_points_changed (); /* EMIT SIGNAL */
678 if (_mute_master->muted()) {
679 _mute_master->mute_at (_mute_points);
680 mute_changed (this); /* EMIT SIGNAL */
685 Route::set_mute (bool yn, void *src)
687 if (_route_group && src != _route_group && _route_group->active_property (RouteGroup::Mute)) {
688 _route_group->apply (&Route::set_mute, yn, _route_group);
694 _mute_master->mute_at (_mute_points);
696 _mute_master->clear_mute ();
699 mute_changed (src); /* EMIT SIGNAL */
706 return _mute_master->muted ();
711 dump_processors(const string& name, const list<boost::shared_ptr<Processor> >& procs)
713 cerr << name << " {" << endl;
714 for (list<boost::shared_ptr<Processor> >::const_iterator p = procs.begin();
715 p != procs.end(); ++p) {
716 cerr << "\t" << (*p)->name() << " ID = " << (*p)->id() << endl;
723 Route::add_processor (boost::shared_ptr<Processor> processor, Placement placement, ProcessorStreams* err)
725 ProcessorList::iterator loc;
727 /* XXX this is not thread safe - we don't hold the lock across determining the iter
728 to add before and actually doing the insertion. dammit.
731 if (placement == PreFader) {
732 /* generic pre-fader: insert immediately before the amp */
733 loc = find (_processors.begin(), _processors.end(), _amp);
735 /* generic post-fader: insert right before the main outs */
736 loc = find (_processors.begin(), _processors.end(), _main_outs);
739 return add_processor (processor, loc, err);
743 /** Add a processor to the route.
744 * If @a iter is not NULL, it must point to an iterator in _processors and the new
745 * processor will be inserted immediately before this location. Otherwise,
746 * @a position is used.
749 Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::iterator iter, ProcessorStreams* err)
751 ChanCount old_pms = processor_max_streams;
753 if (!_session.engine().connected() || !processor) {
758 Glib::RWLock::WriterLock lm (_processor_lock);
760 boost::shared_ptr<PluginInsert> pi;
761 boost::shared_ptr<PortInsert> porti;
763 ProcessorList::iterator loc = find(_processors.begin(), _processors.end(), processor);
765 if (processor == _amp || processor == _meter || processor == _main_outs) {
766 // Ensure only one of these are in the list at any time
767 if (loc != _processors.end()) {
768 if (iter == loc) { // Already in place, do nothing
770 } else { // New position given, relocate
771 _processors.erase (loc);
776 if (loc != _processors.end()) {
777 cerr << "ERROR: Processor added to route twice!" << endl;
784 _processors.insert (loc, processor);
786 // Set up processor list channels. This will set processor->[input|output]_streams(),
787 // configure redirect ports properly, etc.
789 if (configure_processors_unlocked (err)) {
790 ProcessorList::iterator ploc = loc;
792 _processors.erase(ploc);
793 configure_processors_unlocked (0); // it worked before we tried to add it ...
794 cerr << "configure failed\n";
798 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(processor)) != 0) {
800 if (pi->natural_input_streams() == ChanCount::ZERO) {
801 /* generator plugin */
802 _have_internal_generator = true;
807 if (_control_outs != processor) {
808 // XXX: do we want to emit the signal here ? change call order.
809 processor->activate ();
812 processor->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false, false));
814 _output->set_user_latency (0);
817 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
823 Route::add_processor_from_xml (const XMLNode& node, ProcessorList::iterator iter)
825 const XMLProperty *prop;
827 if (node.name() != "Processor") {
832 if ((prop = node.property ("type")) != 0) {
834 boost::shared_ptr<Processor> processor;
836 if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
837 prop->value() == "lv2" ||
838 prop->value() == "vst" ||
839 prop->value() == "audiounit") {
841 processor.reset (new PluginInsert(_session, node));
843 } else if (prop->value() == "port") {
845 processor.reset (new PortInsert (_session, _mute_master, node));
847 } else if (prop->value() == "send") {
849 processor.reset (new Send (_session, _mute_master, node));
851 } else if (prop->value() == "meter") {
854 if (_meter->set_state (node, Stateful::loading_state_version)) {
861 _meter.reset (new PeakMeter (_session, node));
862 _meter->set_display_to_user (_meter_point == MeterCustom);
865 } else if (prop->value() == "amp") {
867 /* amp always exists */
870 if (processor->set_state (node, Stateful::loading_state_version)) {
873 /* never any reason to add it */
877 } else if (prop->value() == "intsend") {
879 processor.reset (new InternalSend (_session, _mute_master, node));
881 } else if (prop->value() == "intreturn") {
884 if (_intreturn->set_state (node, Stateful::loading_state_version)) {
890 _intreturn.reset (new InternalReturn (_session, node));
891 processor = _intreturn;
893 } else if (prop->value() == "main-outs") {
896 if (_main_outs->set_state (node, Stateful::loading_state_version)) {
903 _main_outs.reset (new Delivery (_session, _output, _mute_master, node));
904 processor = _main_outs;
907 error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
911 if (iter == _processors.end() && processor->display_to_user() && !_processors.empty()) {
912 /* check for invisible processors stacked at the end and leave them there */
913 ProcessorList::iterator p;
914 p = _processors.end();
916 while (!(*p)->display_to_user() && p != _processors.begin()) {
923 return (add_processor (processor, iter) == 0);
926 error << _("Processor XML node has no type property") << endmsg;
931 catch (failed_constructor &err) {
932 warning << _("processor could not be created. Ignored.") << endmsg;
939 Route::add_processor_from_xml_2X (const XMLNode& node, int version, ProcessorList::iterator iter)
941 const XMLProperty *prop;
944 boost::shared_ptr<Processor> processor;
946 if (node.name() == "Insert") {
948 if ((prop = node.property ("type")) != 0) {
950 if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
951 prop->value() == "lv2" ||
952 prop->value() == "vst" ||
953 prop->value() == "audiounit") {
955 processor.reset (new PluginInsert (_session, node));
959 processor.reset (new PortInsert (_session, _mute_master, node));
964 } else if (node.name() == "Send") {
966 processor.reset (new Send (_session, _mute_master, node, version));
970 error << string_compose(_("unknown Processor type \"%1\"; ignored"), node.name()) << endmsg;
974 if (iter == _processors.end() && processor->display_to_user() && !_processors.empty()) {
975 /* check for invisible processors stacked at the end and leave them there */
976 ProcessorList::iterator p;
977 p = _processors.end();
979 while (!(*p)->display_to_user() && p != _processors.begin()) {
986 return (add_processor (processor, iter) == 0);
989 catch (failed_constructor &err) {
990 warning << _("processor could not be created. Ignored.") << endmsg;
996 Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor> before, ProcessorStreams* err)
998 ProcessorList::iterator loc;
1001 loc = find(_processors.begin(), _processors.end(), before);
1003 /* nothing specified - at end but before main outs */
1004 loc = find (_processors.begin(), _processors.end(), _main_outs);
1007 return add_processors (others, loc, err);
1011 Route::add_processors (const ProcessorList& others, ProcessorList::iterator iter, ProcessorStreams* err)
1013 /* NOTE: this is intended to be used ONLY when copying
1014 processors from another Route. Hence the subtle
1015 differences between this and ::add_processor()
1018 ChanCount old_pms = processor_max_streams;
1020 if (!_session.engine().connected()) {
1024 if (others.empty()) {
1029 Glib::RWLock::WriterLock lm (_processor_lock);
1031 ChanCount potential_max_streams = ChanCount::max (_input->n_ports(), _output->n_ports());
1033 for (ProcessorList::const_iterator i = others.begin(); i != others.end(); ++i) {
1035 // Ensure meter only appears in the list once
1037 ProcessorList::iterator m = find(_processors.begin(), _processors.end(), *i);
1038 if (m != _processors.end()) {
1039 _processors.erase(m);
1043 boost::shared_ptr<PluginInsert> pi;
1045 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
1048 ChanCount m = max (pi->input_streams(), pi->output_streams());
1050 if (m > potential_max_streams) {
1051 potential_max_streams = m;
1055 ProcessorList::iterator inserted = _processors.insert (iter, *i);
1057 if ((*i)->active()) {
1061 if (configure_processors_unlocked (err)) {
1062 _processors.erase (inserted);
1063 configure_processors_unlocked (0); // it worked before we tried to add it ...
1067 (*i)->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false, false));
1070 _output->set_user_latency (0);
1073 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1079 Route::placement_range(Placement p, ProcessorList::iterator& start, ProcessorList::iterator& end)
1081 if (p == PreFader) {
1082 start = _processors.begin();
1083 end = find(_processors.begin(), _processors.end(), _amp);
1085 start = find(_processors.begin(), _processors.end(), _amp);
1087 end = _processors.end();
1091 /** Turn off all processors with a given placement
1092 * @param p Placement of processors to disable
1095 Route::disable_processors (Placement p)
1097 Glib::RWLock::ReaderLock lm (_processor_lock);
1099 ProcessorList::iterator start, end;
1100 placement_range(p, start, end);
1102 for (ProcessorList::iterator i = start; i != end; ++i) {
1103 (*i)->deactivate ();
1106 _session.set_dirty ();
1109 /** Turn off all redirects
1112 Route::disable_processors ()
1114 Glib::RWLock::ReaderLock lm (_processor_lock);
1116 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1117 (*i)->deactivate ();
1120 _session.set_dirty ();
1123 /** Turn off all redirects with a given placement
1124 * @param p Placement of redirects to disable
1127 Route::disable_plugins (Placement p)
1129 Glib::RWLock::ReaderLock lm (_processor_lock);
1131 ProcessorList::iterator start, end;
1132 placement_range(p, start, end);
1134 for (ProcessorList::iterator i = start; i != end; ++i) {
1135 if (boost::dynamic_pointer_cast<PluginInsert> (*i)) {
1136 (*i)->deactivate ();
1140 _session.set_dirty ();
1143 /** Turn off all plugins
1146 Route::disable_plugins ()
1148 Glib::RWLock::ReaderLock lm (_processor_lock);
1150 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1151 if (boost::dynamic_pointer_cast<PluginInsert> (*i)) {
1152 (*i)->deactivate ();
1156 _session.set_dirty ();
1161 Route::ab_plugins (bool forward)
1163 Glib::RWLock::ReaderLock lm (_processor_lock);
1167 /* forward = turn off all active redirects, and mark them so that the next time
1168 we go the other way, we will revert them
1171 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1172 if (!boost::dynamic_pointer_cast<PluginInsert> (*i)) {
1176 if ((*i)->active()) {
1177 (*i)->deactivate ();
1178 (*i)->set_next_ab_is_active (true);
1180 (*i)->set_next_ab_is_active (false);
1186 /* backward = if the redirect was marked to go active on the next ab, do so */
1188 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1190 if (!boost::dynamic_pointer_cast<PluginInsert> (*i)) {
1194 if ((*i)->get_next_ab_is_active()) {
1197 (*i)->deactivate ();
1202 _session.set_dirty ();
1206 /** Remove processors with a given placement.
1207 * @param p Placement of processors to remove.
1210 Route::clear_processors (Placement p)
1212 const ChanCount old_pms = processor_max_streams;
1214 if (!_session.engine().connected()) {
1218 bool already_deleting = _session.deletion_in_progress();
1219 if (!already_deleting) {
1220 _session.set_deletion_in_progress();
1224 Glib::RWLock::WriterLock lm (_processor_lock);
1225 ProcessorList new_list;
1226 ProcessorStreams err;
1227 bool seen_amp = false;
1229 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1235 if ((*i) == _amp || (*i) == _meter || (*i) == _main_outs) {
1237 /* you can't remove these */
1239 new_list.push_back (*i);
1246 new_list.push_back (*i);
1249 (*i)->drop_references ();
1257 (*i)->drop_references ();
1260 new_list.push_back (*i);
1267 _processors = new_list;
1268 configure_processors_unlocked (&err); // this can't fail
1271 processor_max_streams.reset();
1272 _have_internal_generator = false;
1273 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1275 if (!already_deleting) {
1276 _session.clear_deletion_in_progress();
1281 Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStreams* err)
1283 /* these can never be removed */
1285 if (processor == _amp || processor == _meter || processor == _main_outs) {
1289 ChanCount old_pms = processor_max_streams;
1291 if (!_session.engine().connected()) {
1295 processor_max_streams.reset();
1298 Glib::RWLock::WriterLock lm (_processor_lock);
1299 ProcessorList::iterator i;
1300 bool removed = false;
1302 for (i = _processors.begin(); i != _processors.end(); ) {
1303 if (*i == processor) {
1305 /* move along, see failure case for configure_processors()
1306 where we may need to reconfigure the processor.
1309 /* stop redirects that send signals to JACK ports
1310 from causing noise as a result of no longer being
1314 boost::shared_ptr<IOProcessor> iop;
1316 if ((iop = boost::dynamic_pointer_cast<IOProcessor> (*i)) != 0) {
1318 iop->input()->disconnect (this);
1320 if (iop->output()) {
1321 iop->output()->disconnect (this);
1325 i = _processors.erase (i);
1333 _output->set_user_latency (0);
1341 if (configure_processors_unlocked (err)) {
1342 /* get back to where we where */
1343 _processors.insert (i, processor);
1344 /* we know this will work, because it worked before :) */
1345 configure_processors_unlocked (0);
1349 _have_internal_generator = false;
1351 for (i = _processors.begin(); i != _processors.end(); ++i) {
1352 boost::shared_ptr<PluginInsert> pi;
1354 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
1355 if (pi->is_generator()) {
1356 _have_internal_generator = true;
1363 processor->drop_references ();
1364 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1370 Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams* err)
1372 ProcessorList deleted;
1373 ProcessorList as_we_were;
1375 if (!_session.engine().connected()) {
1379 processor_max_streams.reset();
1382 Glib::RWLock::WriterLock lm (_processor_lock);
1383 ProcessorList::iterator i;
1384 boost::shared_ptr<Processor> processor;
1386 as_we_were = _processors;
1388 for (i = _processors.begin(); i != _processors.end(); ) {
1392 /* these can never be removed */
1394 if (processor == _amp || processor == _meter || processor == _main_outs) {
1399 /* see if its in the list of processors to delete */
1401 if (find (to_be_deleted.begin(), to_be_deleted.end(), processor) == to_be_deleted.end()) {
1406 /* stop IOProcessors that send to JACK ports
1407 from causing noise as a result of no longer being
1411 boost::shared_ptr<IOProcessor> iop;
1413 if ((iop = boost::dynamic_pointer_cast<IOProcessor> (processor)) != 0) {
1417 deleted.push_back (processor);
1418 i = _processors.erase (i);
1421 if (deleted.empty()) {
1422 /* none of those in the requested list were found */
1426 _output->set_user_latency (0);
1428 if (configure_processors_unlocked (err)) {
1429 /* get back to where we where */
1430 _processors = as_we_were;
1431 /* we know this will work, because it worked before :) */
1432 configure_processors_unlocked (0);
1436 _have_internal_generator = false;
1438 for (i = _processors.begin(); i != _processors.end(); ++i) {
1439 boost::shared_ptr<PluginInsert> pi;
1441 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
1442 if (pi->is_generator()) {
1443 _have_internal_generator = true;
1450 /* now try to do what we need to so that those that were removed will be deleted */
1452 for (ProcessorList::iterator i = deleted.begin(); i != deleted.end(); ++i) {
1453 (*i)->drop_references ();
1456 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1463 Route::configure_processors (ProcessorStreams* err)
1465 if (!_in_configure_processors) {
1466 Glib::RWLock::WriterLock lm (_processor_lock);
1467 return configure_processors_unlocked (err);
1472 /** Configure the input/output configuration of each processor in the processors list.
1473 * Return 0 on success, otherwise configuration is impossible.
1476 Route::configure_processors_unlocked (ProcessorStreams* err)
1478 if (_in_configure_processors) {
1482 _in_configure_processors = true;
1484 // Check each processor in order to see if we can configure as requested
1485 ChanCount in = _input->n_ports ();
1487 list< pair<ChanCount,ChanCount> > configuration;
1490 DEBUG_TRACE (DEBUG::Processors, string_compose ("%1: configure processors\n", _name));
1492 DEBUG_TRACE (DEBUG::Processors, "{\n");
1493 for (list<boost::shared_ptr<Processor> >::const_iterator p = _processors.begin(); p != _processors.end(); ++p) {
1494 DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1 ID = %2\n", (*p)->name(), (*p)->id()));
1496 DEBUG_TRACE (DEBUG::Processors, "}\n");
1499 for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++index) {
1501 if ((*p)->can_support_io_configuration(in, out)) {
1502 DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1in = %2 out = %3\n",(*p)->name(), in, out));
1503 configuration.push_back(make_pair(in, out));
1510 _in_configure_processors = false;
1515 // We can, so configure everything
1516 list< pair<ChanCount,ChanCount> >::iterator c = configuration.begin();
1517 for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++c) {
1518 (*p)->configure_io(c->first, c->second);
1519 processor_max_streams = ChanCount::max(processor_max_streams, c->first);
1520 processor_max_streams = ChanCount::max(processor_max_streams, c->second);
1525 _meter->reset_max_channels (processor_max_streams);
1528 /* make sure we have sufficient scratch buffers to cope with the new processor
1530 _session.ensure_buffers (n_process_buffers ());
1532 _in_configure_processors = false;
1537 Route::all_processors_flip ()
1539 Glib::RWLock::ReaderLock lm (_processor_lock);
1541 if (_processors.empty()) {
1545 bool first_is_on = _processors.front()->active();
1547 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1549 (*i)->deactivate ();
1555 _session.set_dirty ();
1558 /** Set all processors with a given placement to a given active state.
1559 * @param p Placement of processors to change.
1560 * @param state New active state for those processors.
1563 Route::all_processors_active (Placement p, bool state)
1565 Glib::RWLock::ReaderLock lm (_processor_lock);
1567 if (_processors.empty()) {
1570 ProcessorList::iterator start, end;
1571 placement_range(p, start, end);
1573 bool before_amp = true;
1574 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1579 if (p == PreFader && before_amp) {
1583 (*i)->deactivate ();
1588 _session.set_dirty ();
1592 Route::processor_is_prefader (boost::shared_ptr<Processor> p)
1594 bool pre_fader = true;
1595 Glib::RWLock::ReaderLock lm (_processor_lock);
1597 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1599 /* semantic note: if p == amp, we want to return true, so test
1600 for equality before checking if this is the amp
1617 Route::reorder_processors (const ProcessorList& new_order, ProcessorStreams* err)
1619 /* "new_order" is an ordered list of processors to be positioned according to "placement".
1620 NOTE: all processors in "new_order" MUST be marked as display_to_user(). There maybe additional
1621 processors in the current actual processor list that are hidden. Any visible processors
1622 in the current list but not in "new_order" will be assumed to be deleted.
1626 Glib::RWLock::WriterLock lm (_processor_lock);
1627 ChanCount old_pms = processor_max_streams;
1628 ProcessorList::iterator oiter;
1629 ProcessorList::const_iterator niter;
1630 ProcessorList as_it_was_before = _processors;
1631 ProcessorList as_it_will_be;
1633 oiter = _processors.begin();
1634 niter = new_order.begin();
1636 while (niter != new_order.end()) {
1638 /* if the next processor in the old list is invisible (i.e. should not be in the new order)
1639 then append it to the temp list.
1641 Otherwise, see if the next processor in the old list is in the new list. if not,
1642 its been deleted. If its there, append it to the temp list.
1645 if (oiter == _processors.end()) {
1647 /* no more elements in the old list, so just stick the rest of
1648 the new order onto the temp list.
1651 as_it_will_be.insert (as_it_will_be.end(), niter, new_order.end());
1652 while (niter != new_order.end()) {
1659 if (!(*oiter)->display_to_user()) {
1661 as_it_will_be.push_back (*oiter);
1665 /* visible processor: check that its in the new order */
1667 if (find (new_order.begin(), new_order.end(), (*oiter)) == new_order.end()) {
1668 /* deleted: do nothing, shared_ptr<> will clean up */
1670 /* ignore this one, and add the next item from the new order instead */
1671 as_it_will_be.push_back (*niter);
1676 /* now remove from old order - its taken care of no matter what */
1677 oiter = _processors.erase (oiter);
1682 _processors.insert (oiter, as_it_will_be.begin(), as_it_will_be.end());
1684 if (configure_processors_unlocked (err)) {
1685 _processors = as_it_was_before;
1686 processor_max_streams = old_pms;
1691 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1703 Route::get_template()
1705 return state(false);
1709 Route::state(bool full_state)
1711 XMLNode *node = new XMLNode("Route");
1712 ProcessorList::iterator i;
1715 id().print (buf, sizeof (buf));
1716 node->add_property("id", buf);
1717 node->add_property ("name", _name);
1718 node->add_property("default-type", _default_type.to_string());
1721 node->add_property("flags", enum_2_string (_flags));
1724 node->add_property("active", _active?"yes":"no");
1725 node->add_property("phase-invert", _phase_invert?"yes":"no");
1726 node->add_property("denormal-protection", _denormal_protection?"yes":"no");
1727 node->add_property("meter-point", enum_2_string (_meter_point));
1730 node->add_property("route-group", _route_group->name());
1733 string order_string;
1734 OrderKeys::iterator x = order_keys.begin();
1736 while (x != order_keys.end()) {
1737 order_string += string ((*x).first);
1738 order_string += '=';
1739 snprintf (buf, sizeof(buf), "%ld", (*x).second);
1740 order_string += buf;
1744 if (x == order_keys.end()) {
1748 order_string += ':';
1750 node->add_property ("order-keys", order_string);
1751 node->add_property ("self-solo", (_self_solo ? "yes" : "no"));
1752 snprintf (buf, sizeof (buf), "%d", _soloed_by_others);
1753 node->add_property ("soloed-by-others", buf);
1755 node->add_child_nocopy (_input->state (full_state));
1756 node->add_child_nocopy (_output->state (full_state));
1757 node->add_child_nocopy (_solo_control->get_state ());
1758 node->add_child_nocopy (_mute_master->get_state ());
1760 XMLNode* remote_control_node = new XMLNode (X_("RemoteControl"));
1761 snprintf (buf, sizeof (buf), "%d", _remote_control_id);
1762 remote_control_node->add_property (X_("id"), buf);
1763 node->add_child_nocopy (*remote_control_node);
1765 if (_comment.length()) {
1766 XMLNode *cmt = node->add_child ("Comment");
1767 cmt->add_content (_comment);
1770 for (i = _processors.begin(); i != _processors.end(); ++i) {
1771 node->add_child_nocopy((*i)->state (full_state));
1775 node->add_child_copy (*_extra_xml);
1782 Route::set_state (const XMLNode& node, int version)
1784 return _set_state (node, version, true);
1788 Route::_set_state (const XMLNode& node, int version, bool /*call_base*/)
1790 if (version < 3000) {
1791 return _set_state_2X (node, version);
1795 XMLNodeConstIterator niter;
1797 XMLPropertyList plist;
1798 const XMLProperty *prop;
1800 if (node.name() != "Route"){
1801 error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
1805 if ((prop = node.property (X_("name"))) != 0) {
1806 Route::set_name (prop->value());
1809 if ((prop = node.property ("id")) != 0) {
1810 _id = prop->value ();
1813 if ((prop = node.property (X_("flags"))) != 0) {
1814 _flags = Flag (string_2_enum (prop->value(), _flags));
1819 /* add all processors (except amp, which is always present) */
1821 nlist = node.children();
1822 XMLNode processor_state (X_("processor_state"));
1824 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1828 if (child->name() == IO::state_node_name) {
1829 if ((prop = child->property (X_("direction"))) == 0) {
1833 if (prop->value() == "Input") {
1834 _input->set_state (*child, version);
1835 } else if (prop->value() == "Output") {
1836 _output->set_state (*child, version);
1840 if (child->name() == X_("Processor")) {
1841 processor_state.add_child_copy (*child);
1845 set_processor_state (processor_state);
1847 if ((prop = node.property ("self-solo")) != 0) {
1848 set_self_solo (string_is_affirmative (prop->value()));
1851 if ((prop = node.property ("soloed-by-others")) != 0) {
1852 _soloed_by_others = 0; // needed for mod_solo_by_others () to work
1853 mod_solo_by_others (atoi (prop->value()));
1856 if ((prop = node.property ("solo-isolated")) != 0) {
1857 set_solo_isolated (string_is_affirmative (prop->value()), this);
1860 if ((prop = node.property (X_("phase-invert"))) != 0) {
1861 set_phase_invert (string_is_affirmative (prop->value()));
1864 if ((prop = node.property (X_("denormal-protection"))) != 0) {
1865 set_denormal_protection (string_is_affirmative (prop->value()));
1868 if ((prop = node.property (X_("active"))) != 0) {
1869 bool yn = string_is_affirmative (prop->value());
1870 _active = !yn; // force switch
1874 if ((prop = node.property (X_("meter-point"))) != 0) {
1875 _meter_point = MeterPoint (string_2_enum (prop->value (), _meter_point));
1877 _meter->set_display_to_user (_meter_point == MeterCustom);
1881 if ((prop = node.property (X_("order-keys"))) != 0) {
1885 string::size_type colon, equal;
1886 string remaining = prop->value();
1888 while (remaining.length()) {
1890 if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
1891 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1894 if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) {
1895 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1898 set_order_key (remaining.substr (0, equal), n);
1902 colon = remaining.find_first_of (':');
1904 if (colon != string::npos) {
1905 remaining = remaining.substr (colon+1);
1912 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1915 if (child->name() == X_("Comment")) {
1917 /* XXX this is a terrible API design in libxml++ */
1919 XMLNode *cmt = *(child->children().begin());
1920 _comment = cmt->content();
1922 } else if (child->name() == X_("Extra")) {
1924 _extra_xml = new XMLNode (*child);
1926 } else if (child->name() == X_("Controllable") && (prop = child->property("name")) != 0) {
1928 if (prop->value() == "solo") {
1929 _solo_control->set_state (*child, version);
1930 _session.add_controllable (_solo_control);
1933 } else if (child->name() == X_("RemoteControl")) {
1934 if ((prop = child->property (X_("id"))) != 0) {
1936 sscanf (prop->value().c_str(), "%d", &x);
1937 set_remote_control_id (x);
1940 } else if (child->name() == X_("MuteMaster")) {
1941 _mute_master->set_state (*child, version);
1949 Route::_set_state_2X (const XMLNode& node, int version)
1952 XMLNodeConstIterator niter;
1954 XMLPropertyList plist;
1955 const XMLProperty *prop;
1957 /* 2X things which still remain to be handled:
1960 * mute-affects-pre-fader
1961 * mute-affects-post-fader
1962 * mute-affects-control-outs
1963 * mute-affects-main-outs
1968 if (node.name() != "Route") {
1969 error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
1973 if ((prop = node.property (X_("flags"))) != 0) {
1974 _flags = Flag (string_2_enum (prop->value(), _flags));
1979 /* add standard processors */
1981 _meter.reset (new PeakMeter (_session));
1982 add_processor (_meter, PreFader);
1984 if (_flags & ControlOut) {
1985 /* where we listen to tracks */
1986 _intreturn.reset (new InternalReturn (_session));
1987 add_processor (_intreturn, PreFader);
1990 _main_outs.reset (new Delivery (_session, _output, _mute_master, _name, Delivery::Main));
1991 add_processor (_main_outs, PostFader);
1995 nlist = node.children ();
1996 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2000 if (child->name() == IO::state_node_name) {
2002 /* there is a note in IO::set_state_2X() about why we have to call
2006 _input->set_state_2X (*child, version, true);
2007 _output->set_state_2X (*child, version, false);
2009 if ((prop = child->property (X_("name"))) != 0) {
2010 set_name (prop->value ());
2013 if ((prop = child->property (X_("id"))) != 0) {
2014 _id = prop->value ();
2017 if ((prop = child->property (X_("active"))) != 0) {
2018 bool yn = string_is_affirmative (prop->value());
2019 _active = !yn; // force switch
2027 if ((prop = node.property (X_("phase-invert"))) != 0) {
2028 set_phase_invert (string_is_affirmative (prop->value()));
2031 if ((prop = node.property (X_("denormal-protection"))) != 0) {
2032 set_denormal_protection (string_is_affirmative (prop->value()));
2035 if ((prop = node.property (X_("soloed"))) != 0) {
2036 bool yn = string_is_affirmative (prop->value());
2038 /* XXX force reset of solo status */
2040 set_solo (yn, this);
2043 if ((prop = node.property (X_("meter-point"))) != 0) {
2044 _meter_point = MeterPoint (string_2_enum (prop->value (), _meter_point));
2047 /* do not carry over edit/mix groups from 2.X because (a) its hard (b) they
2048 don't mean the same thing.
2051 if ((prop = node.property (X_("order-keys"))) != 0) {
2055 string::size_type colon, equal;
2056 string remaining = prop->value();
2058 while (remaining.length()) {
2060 if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
2061 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
2064 if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) {
2065 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
2068 set_order_key (remaining.substr (0, equal), n);
2072 colon = remaining.find_first_of (':');
2074 if (colon != string::npos) {
2075 remaining = remaining.substr (colon+1);
2082 XMLNodeList redirect_nodes;
2084 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
2088 if (child->name() == X_("Send") || child->name() == X_("Insert")) {
2089 redirect_nodes.push_back(child);
2094 set_processor_state_2X (redirect_nodes, version);
2096 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
2099 if (child->name() == X_("Comment")) {
2101 /* XXX this is a terrible API design in libxml++ */
2103 XMLNode *cmt = *(child->children().begin());
2104 _comment = cmt->content();
2106 } else if (child->name() == X_("Extra")) {
2108 _extra_xml = new XMLNode (*child);
2110 } else if (child->name() == X_("Controllable") && (prop = child->property("name")) != 0) {
2112 if (prop->value() == "solo") {
2113 _solo_control->set_state (*child, version);
2114 _session.add_controllable (_solo_control);
2117 } else if (child->name() == X_("RemoteControl")) {
2118 if ((prop = child->property (X_("id"))) != 0) {
2120 sscanf (prop->value().c_str(), "%d", &x);
2121 set_remote_control_id (x);
2131 Route::get_processor_state ()
2133 XMLNode* root = new XMLNode (X_("redirects"));
2134 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2135 root->add_child_nocopy ((*i)->state (true));
2142 Route::set_processor_state_2X (XMLNodeList const & nList, int version)
2144 /* We don't bother removing existing processors not in nList, as this
2145 method will only be called when creating a Route from scratch, not
2146 for undo purposes. Just put processors in at the appropriate place
2150 for (XMLNodeConstIterator i = nList.begin(); i != nList.end(); ++i) {
2151 add_processor_from_xml_2X (**i, version, _processors.begin ());
2156 Route::set_processor_state (const XMLNode& node)
2158 const XMLNodeList &nlist = node.children();
2159 XMLNodeConstIterator niter;
2160 ProcessorList::iterator i, o;
2162 // Iterate through existing processors, remove those which are not in the state list
2164 for (i = _processors.begin(); i != _processors.end(); ) {
2166 /* leave amp alone, always */
2173 ProcessorList::iterator tmp = i;
2176 bool processorInStateList = false;
2178 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2180 XMLProperty* id_prop = (*niter)->property(X_("id"));
2182 if (id_prop && (*i)->id() == id_prop->value()) {
2183 processorInStateList = true;
2188 if (!processorInStateList) {
2189 remove_processor (*i);
2195 // Iterate through state list and make sure all processors are on the track and in the correct order,
2196 // set the state of existing processors according to the new state on the same go
2198 i = _processors.begin();
2200 for (niter = nlist.begin(); niter != nlist.end(); ++niter, ++i) {
2202 XMLProperty* prop = (*niter)->property ("type");
2206 // Check whether the next processor in the list is the right one,
2207 // except for "amp" which is always there and may not have the
2208 // old ID since it is always created anew in every Route
2210 if (prop->value() != "amp") {
2211 while (o != _processors.end()) {
2212 XMLProperty* id_prop = (*niter)->property(X_("id"));
2213 if (id_prop && (*o)->id() == id_prop->value()) {
2221 // If the processor (*niter) is not on the route,
2222 // create it and move it to the correct location
2224 if (o == _processors.end()) {
2226 if (add_processor_from_xml (**niter, i)) {
2227 --i; // move iterator to the newly inserted processor
2229 cerr << "Error restoring route: unable to restore processor" << endl;
2234 // Otherwise, the processor already exists; just
2235 // ensure it is at the location provided in the XML state
2238 boost::shared_ptr<Processor> tmp = (*o);
2239 _processors.erase (o); // remove the old copy
2240 _processors.insert (i, tmp); // insert the processor at the correct location
2241 --i; // move iterator to the correct processor
2244 // and make it (just) so
2246 (*i)->set_state (**niter, Stateful::current_state_version);
2250 /* note: there is no configure_processors() call because we figure that
2251 the XML state represents a working signal route.
2254 processors_changed (RouteProcessorChange ());
2258 Route::curve_reallocate ()
2260 // _gain_automation_curve.finish_resize ();
2261 // _pan_automation_curve.finish_resize ();
2265 Route::silence (nframes_t nframes)
2269 _output->silence (nframes);
2272 Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
2275 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2276 boost::shared_ptr<PluginInsert> pi;
2278 if (!_active && (pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
2279 // skip plugins, they don't need anything when we're not active
2283 (*i)->silence (nframes);
2286 if (nframes == _session.get_block_size()) {
2296 Route::add_internal_return ()
2299 _intreturn.reset (new InternalReturn (_session));
2300 add_processor (_intreturn, PreFader);
2305 Route::get_return_buffer () const
2307 Glib::RWLock::ReaderLock rm (_processor_lock);
2309 for (ProcessorList::const_iterator x = _processors.begin(); x != _processors.end(); ++x) {
2310 boost::shared_ptr<InternalReturn> d = boost::dynamic_pointer_cast<InternalReturn>(*x);
2313 BufferSet* bs = d->get_buffers ();
2322 Route::release_return_buffer () const
2324 Glib::RWLock::ReaderLock rm (_processor_lock);
2326 for (ProcessorList::const_iterator x = _processors.begin(); x != _processors.end(); ++x) {
2327 boost::shared_ptr<InternalReturn> d = boost::dynamic_pointer_cast<InternalReturn>(*x);
2330 return d->release_buffers ();
2336 Route::listen_via (boost::shared_ptr<Route> route, Placement placement, bool /*active*/, bool aux)
2338 vector<string> ports;
2339 vector<string>::const_iterator i;
2342 Glib::RWLock::ReaderLock rm (_processor_lock);
2344 for (ProcessorList::iterator x = _processors.begin(); x != _processors.end(); ++x) {
2346 boost::shared_ptr<InternalSend> d = boost::dynamic_pointer_cast<InternalSend>(*x);
2348 if (d && d->target_route() == route) {
2350 /* if the target is the control outs, then make sure
2351 we take note of which i-send is doing that.
2354 if (route == _session.control_out()) {
2355 _control_outs = boost::dynamic_pointer_cast<Delivery>(d);
2358 /* already listening via the specified IO: do nothing */
2365 boost::shared_ptr<InternalSend> listener;
2368 listener.reset (new InternalSend (_session, _mute_master, route, (aux ? Delivery::Aux : Delivery::Listen)));
2370 } catch (failed_constructor& err) {
2374 if (route == _session.control_out()) {
2375 _control_outs = listener;
2378 add_processor (listener, placement);
2384 Route::drop_listen (boost::shared_ptr<Route> route)
2386 ProcessorStreams err;
2387 ProcessorList::iterator tmp;
2389 Glib::RWLock::ReaderLock rl(_processor_lock);
2393 for (ProcessorList::iterator x = _processors.begin(); x != _processors.end(); ) {
2395 boost::shared_ptr<InternalSend> d = boost::dynamic_pointer_cast<InternalSend>(*x);
2397 if (d && d->target_route() == route) {
2399 remove_processor (*x, &err);
2402 /* list could have been demolished while we dropped the lock
2412 if (route == _session.control_out()) {
2413 _control_outs.reset ();
2418 Route::set_comment (string cmt, void *src)
2421 comment_changed (src);
2422 _session.set_dirty ();
2426 Route::feeds (boost::shared_ptr<Route> other, bool* only_send)
2428 DEBUG_TRACE (DEBUG::Graph, string_compose ("Feeds? %1\n", _name));
2430 if (_output->connected_to (other->input())) {
2431 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tdirect FEEDS %2\n", other->name()));
2440 for (ProcessorList::iterator r = _processors.begin(); r != _processors.end(); r++) {
2442 boost::shared_ptr<IOProcessor> iop;
2444 if ((iop = boost::dynamic_pointer_cast<IOProcessor>(*r)) != 0) {
2445 if (iop->feeds (other)) {
2446 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tIOP %1 does feed %2\n", iop->name(), other->name()));
2452 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tIOP %1 does NOT feed %2\n", iop->name(), other->name()));
2455 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tPROC %1 is not an IOP\n", (*r)->name()));
2460 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tdoes NOT feed %1\n", other->name()));
2465 Route::handle_transport_stopped (bool /*abort_ignored*/, bool did_locate, bool can_flush_processors)
2467 nframes_t now = _session.transport_frame();
2470 Glib::RWLock::ReaderLock lm (_processor_lock);
2473 automation_snapshot (now, true);
2476 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2478 if (Config->get_plugins_stop_with_transport() && can_flush_processors) {
2479 (*i)->deactivate ();
2483 (*i)->transport_stopped (now);
2487 _roll_delay = _initial_delay;
2491 Route::input_change_handler (IOChange change, void * /*src*/)
2493 if ((change & ConfigurationChanged)) {
2494 configure_processors (0);
2499 Route::output_change_handler (IOChange change, void * /*src*/)
2501 if ((change & ConfigurationChanged)) {
2503 /* XXX resize all listeners to match _main_outs? */
2505 // configure_processors (0);
2510 Route::pans_required () const
2512 if (n_outputs().n_audio() < 2) {
2516 return max (n_inputs ().n_audio(), processor_max_streams.n_audio());
2520 Route::no_roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame,
2521 bool session_state_changing, bool /*can_record*/, bool /*rec_monitors_input*/)
2523 if (n_outputs().n_total() == 0) {
2527 if (session_state_changing || !_active || n_inputs() == ChanCount::ZERO) {
2532 _amp->apply_gain_automation (false);
2533 passthru (start_frame, end_frame, nframes, 0);
2539 Route::check_initial_delay (nframes_t nframes, nframes_t& transport_frame)
2541 if (_roll_delay > nframes) {
2543 _roll_delay -= nframes;
2545 /* transport frame is not legal for caller to use */
2548 } else if (_roll_delay > 0) {
2550 nframes -= _roll_delay;
2551 silence (_roll_delay);
2552 /* we've written _roll_delay of samples into the
2553 output ports, so make a note of that for
2556 _main_outs->increment_output_offset (_roll_delay);
2557 transport_frame += _roll_delay;
2566 Route::roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame, int declick,
2567 bool /*can_record*/, bool /*rec_monitors_input*/)
2570 // automation snapshot can also be called from the non-rt context
2571 // and it uses the processor list, so we try to acquire the lock here
2572 Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
2575 automation_snapshot (_session.transport_frame(), false);
2579 if (n_outputs().n_total() == 0) {
2583 if (!_active || n_inputs().n_total() == 0) {
2588 nframes_t unused = 0;
2590 if ((nframes = check_initial_delay (nframes, unused)) == 0) {
2596 passthru (start_frame, end_frame, nframes, declick);
2602 Route::silent_roll (nframes_t nframes, sframes_t /*start_frame*/, sframes_t /*end_frame*/,
2603 bool /*can_record*/, bool /*rec_monitors_input*/)
2610 Route::toggle_monitor_input ()
2612 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
2613 i->ensure_monitor_input( ! i->monitoring_input());
2618 Route::has_external_redirects () const
2620 // FIXME: what about sends? - they don't return a signal back to ardour?
2622 boost::shared_ptr<const PortInsert> pi;
2624 for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
2626 if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*i)) != 0) {
2628 for (PortSet::const_iterator port = pi->output()->ports().begin(); port != pi->output()->ports().end(); ++port) {
2630 string port_name = port->name();
2631 string client_name = port_name.substr (0, port_name.find(':'));
2633 /* only say "yes" if the redirect is actually in use */
2635 if (client_name != "ardour" && pi->active()) {
2646 Route::flush_processors ()
2648 /* XXX shouldn't really try to take this lock, since
2649 this is called from the RT audio thread.
2652 Glib::RWLock::ReaderLock lm (_processor_lock);
2654 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2655 (*i)->deactivate ();
2661 Route::set_meter_point (MeterPoint p, void *src)
2663 /* CAN BE CALLED FROM PROCESS CONTEXT */
2665 if (_meter_point == p) {
2669 bool meter_was_visible_to_user = _meter->display_to_user ();
2672 Glib::RWLock::WriterLock lm (_processor_lock);
2674 if (p != MeterCustom) {
2675 // Move meter in the processors list to reflect the new position
2676 ProcessorList::iterator loc = find (_processors.begin(), _processors.end(), _meter);
2677 _processors.erase(loc);
2680 loc = _processors.begin();
2683 loc = find (_processors.begin(), _processors.end(), _amp);
2685 case MeterPostFader:
2686 loc = _processors.end();
2694 if (loc == _processors.begin()) {
2695 m_in = _input->n_ports();
2697 ProcessorList::iterator before = loc;
2699 m_in = (*before)->output_streams ();
2702 _meter->reflect_inputs (m_in);
2704 _processors.insert (loc, _meter);
2706 /* we do not need to reconfigure the processors, because the meter
2707 (a) is always ready to handle processor_max_streams
2708 (b) is always an N-in/N-out processor, and thus moving
2709 it doesn't require any changes to the other processors.
2712 _meter->set_display_to_user (false);
2716 // just make it visible and let the user move it
2718 _meter->set_display_to_user (true);
2723 meter_change (src); /* EMIT SIGNAL */
2725 bool const meter_visibly_changed = (_meter->display_to_user() != meter_was_visible_to_user);
2727 processors_changed (RouteProcessorChange (RouteProcessorChange::MeterPointChange, meter_visibly_changed)); /* EMIT SIGNAL */
2731 Route::put_control_outs_at (Placement p)
2733 if (!_control_outs) {
2738 Glib::RWLock::WriterLock lm (_processor_lock);
2739 ProcessorList as_it_was (_processors);
2740 // Move meter in the processors list
2741 ProcessorList::iterator loc = find(_processors.begin(), _processors.end(), _control_outs);
2742 _processors.erase(loc);
2746 loc = find(_processors.begin(), _processors.end(), _amp);
2747 if (loc != _processors.begin()) {
2752 loc = find(_processors.begin(), _processors.end(), _amp);
2753 assert (loc != _processors.end());
2758 _processors.insert(loc, _control_outs);
2760 if (configure_processors_unlocked (0)) {
2761 _processors = as_it_was;
2762 configure_processors_unlocked (0); // it worked before we tried to add it ...
2767 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
2768 _session.set_dirty ();
2772 Route::update_total_latency ()
2774 nframes_t old = _output->effective_latency();
2775 nframes_t own_latency = _output->user_latency();
2777 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2778 if ((*i)->active ()) {
2779 own_latency += (*i)->signal_latency ();
2783 DEBUG_TRACE (DEBUG::Latency, string_compose ("%1: internal redirect latency = %2\n", _name, own_latency));
2785 _output->set_port_latency (own_latency);
2787 if (_output->user_latency() == 0) {
2789 /* this (virtual) function is used for pure Routes,
2790 not derived classes like AudioTrack. this means
2791 that the data processed here comes from an input
2792 port, not prerecorded material, and therefore we
2793 have to take into account any input latency.
2796 own_latency += _input->signal_latency ();
2799 if (old != own_latency) {
2800 _output->set_latency_delay (own_latency);
2801 signal_latency_changed (); /* EMIT SIGNAL */
2804 DEBUG_TRACE (DEBUG::Latency, string_compose ("%1: input latency = %2 total = %3\n", _name, _input->signal_latency(), own_latency));
2806 return _output->effective_latency ();
2810 Route::set_user_latency (nframes_t nframes)
2812 _output->set_user_latency (nframes);
2813 _session.update_latency_compensation (false, false);
2817 Route::set_latency_delay (nframes_t longest_session_latency)
2819 nframes_t old = _initial_delay;
2821 if (_output->effective_latency() < longest_session_latency) {
2822 _initial_delay = longest_session_latency - _output->effective_latency();
2827 if (_initial_delay != old) {
2828 initial_delay_changed (); /* EMIT SIGNAL */
2831 if (_session.transport_stopped()) {
2832 _roll_delay = _initial_delay;
2837 Route::automation_snapshot (nframes_t now, bool force)
2839 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2840 (*i)->automation_snapshot (now, force);
2844 Route::SoloControllable::SoloControllable (std::string name, Route& r)
2845 : AutomationControl (r.session(), Evoral::Parameter (SoloAutomation),
2846 boost::shared_ptr<AutomationList>(), name)
2849 boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloAutomation)));
2854 Route::SoloControllable::set_value (float val)
2856 bool bval = ((val >= 0.5f) ? true: false);
2858 this is how it should be done
2860 boost::shared_ptr<RouteList> rl (new RouteList);
2861 rl->push_back (route);
2863 if (Config->get_solo_control_is_listen_control()) {
2864 _session.set_listen (rl, bval);
2866 _session.set_solo (rl, bval);
2869 route.set_solo (bval, this);
2874 Route::SoloControllable::get_value (void) const
2876 if (Config->get_solo_control_is_listen_control()) {
2877 return route.listening() ? 1.0f : 0.0f;
2879 return route.self_soloed() ? 1.0f : 0.0f;
2883 Route::MuteControllable::MuteControllable (std::string name, Route& r)
2884 : AutomationControl (r.session(), Evoral::Parameter (MuteAutomation),
2885 boost::shared_ptr<AutomationList>(), name)
2888 boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(MuteAutomation)));
2893 Route::MuteControllable::set_value (float val)
2895 bool bval = ((val >= 0.5f) ? true: false);
2897 this is how it should be done
2899 boost::shared_ptr<RouteList> rl (new RouteList);
2900 rl->push_back (route);
2901 _session.set_mute (rl, bval);
2903 route.set_mute (bval, this);
2908 Route::MuteControllable::get_value (void) const
2910 return route.muted() ? 1.0f : 0.0f;
2914 Route::set_block_size (nframes_t nframes)
2916 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2917 (*i)->set_block_size (nframes);
2920 _session.ensure_buffers (n_process_buffers ());
2924 Route::protect_automation ()
2926 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i)
2927 (*i)->protect_automation();
2931 Route::set_pending_declick (int declick)
2934 /* this call is not allowed to turn off a pending declick unless "force" is true */
2936 _pending_declick = declick;
2938 // cerr << _name << ": after setting to " << declick << " pending declick = " << _pending_declick << endl;
2940 _pending_declick = 0;
2945 /** Shift automation forwards from a particular place, thereby inserting time.
2946 * Adds undo commands for any shifts that are performed.
2948 * @param pos Position to start shifting from.
2949 * @param frames Amount to shift forwards by.
2953 Route::shift (nframes64_t /*pos*/, nframes64_t /*frames*/)
2955 #ifdef THIS_NEEDS_FIXING_FOR_V3
2957 /* gain automation */
2958 XMLNode &before = _gain_control->get_state ();
2959 _gain_control->shift (pos, frames);
2960 XMLNode &after = _gain_control->get_state ();
2961 _session.add_command (new MementoCommand<AutomationList> (_gain_automation_curve, &before, &after));
2963 /* pan automation */
2964 for (std::vector<StreamPanner*>::iterator i = _panner->begin (); i != _panner->end (); ++i) {
2965 Curve & c = (*i)->automation ();
2966 XMLNode &before = c.get_state ();
2967 c.shift (pos, frames);
2968 XMLNode &after = c.get_state ();
2969 _session.add_command (new MementoCommand<AutomationList> (c, &before, &after));
2972 /* redirect automation */
2974 Glib::RWLock::ReaderLock lm (redirect_lock);
2975 for (RedirectList::iterator i = _redirects.begin (); i != _redirects.end (); ++i) {
2978 (*i)->what_has_automation (a);
2980 for (set<uint32_t>::const_iterator j = a.begin (); j != a.end (); ++j) {
2981 AutomationList & al = (*i)->automation_list (*j);
2982 XMLNode &before = al.get_state ();
2983 al.shift (pos, frames);
2984 XMLNode &after = al.get_state ();
2985 _session.add_command (new MementoCommand<AutomationList> (al, &before, &after));
2995 Route::save_as_template (const string& path, const string& name)
2997 XMLNode& node (state (false));
3000 IO::set_name_in_state (*node.children().front(), name);
3002 tree.set_root (&node);
3003 return tree.write (path.c_str());
3008 Route::set_name (const string& str)
3014 name = Route::ensure_track_or_route_name (str, _session);
3015 SessionObject::set_name (name);
3017 ret = (_input->set_name(name) && _output->set_name(name));
3021 Glib::RWLock::ReaderLock lm (_processor_lock);
3023 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
3025 /* rename all I/O processors that have inputs or outputs */
3027 boost::shared_ptr<IOProcessor> iop = boost::dynamic_pointer_cast<IOProcessor> (*i);
3029 if (iop && (iop->output() || iop->input())) {
3030 if (!iop->set_name (name)) {
3041 boost::shared_ptr<Send>
3042 Route::internal_send_for (boost::shared_ptr<const Route> target) const
3044 Glib::RWLock::ReaderLock lm (_processor_lock);
3046 for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
3047 boost::shared_ptr<InternalSend> send;
3049 if ((send = boost::dynamic_pointer_cast<InternalSend>(*i)) != 0) {
3050 if (send->target_route() == target) {
3056 return boost::shared_ptr<Send>();
3060 Route::set_phase_invert (bool yn)
3062 if (_phase_invert != yn) {
3063 _phase_invert = 0xffff; // XXX all channels
3064 phase_invert_changed (); /* EMIT SIGNAL */
3069 Route::phase_invert () const
3071 return _phase_invert != 0;
3075 Route::set_denormal_protection (bool yn)
3077 if (_denormal_protection != yn) {
3078 _denormal_protection = yn;
3079 denormal_protection_changed (); /* EMIT SIGNAL */
3084 Route::denormal_protection () const
3086 return _denormal_protection;
3090 Route::set_active (bool yn)
3092 if (_active != yn) {
3094 _input->set_active (yn);
3095 _output->set_active (yn);
3096 active_changed (); // EMIT SIGNAL
3103 Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
3109 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
3111 boost::shared_ptr<Send> s;
3112 boost::shared_ptr<Return> r;
3114 if ((s = boost::dynamic_pointer_cast<Send> (*i)) != 0) {
3115 s->meter()->meter();
3116 } else if ((r = boost::dynamic_pointer_cast<Return> (*i)) != 0) {
3117 r->meter()->meter ();
3122 boost::shared_ptr<Panner>
3123 Route::panner() const
3126 return _main_outs->panner();
3129 boost::shared_ptr<AutomationControl>
3130 Route::gain_control() const
3133 return _amp->gain_control();
3136 boost::shared_ptr<AutomationControl>
3137 Route::get_control (const Evoral::Parameter& param)
3139 /* either we own the control or .... */
3141 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(data().control (param));
3145 /* maybe one of our processors does or ... */
3147 Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
3148 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
3149 if ((c = boost::dynamic_pointer_cast<AutomationControl>((*i)->data().control (param))) != 0) {
3157 /* nobody does so we'll make a new one */
3159 c = boost::dynamic_pointer_cast<AutomationControl>(control_factory(param));
3166 boost::shared_ptr<Processor>
3167 Route::nth_plugin (uint32_t n)
3169 Glib::RWLock::ReaderLock lm (_processor_lock);
3170 ProcessorList::iterator i;
3172 for (i = _processors.begin(); i != _processors.end(); ++i) {
3173 if (boost::dynamic_pointer_cast<PluginInsert> (*i)) {
3180 return boost::shared_ptr<Processor> ();
3183 boost::shared_ptr<Processor>
3184 Route::nth_send (uint32_t n)
3186 Glib::RWLock::ReaderLock lm (_processor_lock);
3187 ProcessorList::iterator i;
3189 for (i = _processors.begin(); i != _processors.end(); ++i) {
3190 cerr << "check " << (*i)->name() << endl;
3191 if (boost::dynamic_pointer_cast<Send> (*i)) {
3196 cerr << "\tnot a send\n";
3200 return boost::shared_ptr<Processor> ();