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)
81 cerr << "New route with n=" << name << " has name = " << _name.val() << endl;
84 /* add standard processors other than amp (added by ::init()) */
86 _meter.reset (new PeakMeter (_session));
87 _meter->set_display_to_user (false);
88 add_processor (_meter, PostFader);
90 if (_flags & ControlOut) {
91 /* where we listen to tracks */
92 _intreturn.reset (new InternalReturn (_session));
93 add_processor (_intreturn, PreFader);
96 _main_outs.reset (new Delivery (_session, _output, _mute_master, _name, Delivery::Main));
97 add_processor (_main_outs, PostFader);
99 /* now that we have _meter, its safe to connect to this */
101 Metering::Meter.connect_same_thread (*this, (boost::bind (&Route::meter, this)));
104 Route::Route (Session& sess, const XMLNode& node, DataType default_type)
105 : SessionObject (sess, "toBeReset")
106 , AutomatableControls (sess)
107 , _solo_control (new SoloControllable (X_("solo"), *this))
108 , _mute_control (new MuteControllable (X_("mute"), *this))
109 , _mute_master (new MuteMaster (sess, "toBeReset"))
110 , _default_type (default_type)
114 _set_state (node, Stateful::loading_state_version, false);
116 /* now that we have _meter, its safe to connect to this */
118 Metering::Meter.connect_same_thread (*this, (boost::bind (&Route::meter, this)));
125 _soloed_by_others = 0;
129 processor_max_streams.reset();
131 order_keys[N_("signal")] = order_key_cnt++;
133 _meter_point = MeterPostFader;
136 _have_internal_generator = false;
137 _declickable = false;
138 _pending_declick = true;
139 _remote_control_id = 0;
140 _in_configure_processors = false;
141 _mute_points = MuteMaster::AllPoints;
144 _denormal_protection = false;
146 /* add standard controls */
148 _solo_control->set_flags (Controllable::Flag (_solo_control->flags() | Controllable::Toggle));
149 _mute_control->set_flags (Controllable::Flag (_solo_control->flags() | Controllable::Toggle));
151 add_control (_solo_control);
152 add_control (_mute_control);
154 /* input and output objects */
156 _input.reset (new IO (_session, _name, IO::Input, _default_type));
157 _output.reset (new IO (_session, _name, IO::Output, _default_type));
159 _input->changed.connect_same_thread (*this, boost::bind (&Route::input_change_handler, this, _1, _2));
160 _output->changed.connect_same_thread (*this, boost::bind (&Route::output_change_handler, this, _1, _2));
162 /* add amp processor */
164 _amp.reset (new Amp (_session, _mute_master));
165 add_processor (_amp, PostFader);
170 DEBUG_TRACE (DEBUG::Destruction, string_compose ("route %1 destructor\n", _name));
172 /* do this early so that we don't get incoming signals as we are going through destruction
177 /* don't use clear_processors here, as it depends on the session which may
178 be half-destroyed by now
181 Glib::RWLock::WriterLock lm (_processor_lock);
182 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
183 (*i)->drop_references ();
186 _processors.clear ();
190 Route::set_remote_control_id (uint32_t id, bool notify_class_listeners)
192 if (id != _remote_control_id) {
193 _remote_control_id = id;
194 RemoteControlIDChanged ();
195 if (notify_class_listeners) {
196 RemoteControlIDChange ();
202 Route::remote_control_id() const
204 return _remote_control_id;
208 Route::order_key (std::string const & name) const
210 OrderKeys::const_iterator i = order_keys.find (name);
211 if (i == order_keys.end()) {
219 Route::set_order_key (std::string const & name, long n)
221 order_keys[name] = n;
223 if (Config->get_sync_all_route_ordering()) {
224 for (OrderKeys::iterator x = order_keys.begin(); x != order_keys.end(); ++x) {
229 _session.set_dirty ();
232 /** Set all order keys to be the same as that for `base', if such a key
233 * exists in this route.
234 * @param base Base key.
237 Route::sync_order_keys (std::string const & base)
239 if (order_keys.empty()) {
243 OrderKeys::iterator i;
246 if ((i = order_keys.find (base)) == order_keys.end()) {
247 /* key doesn't exist, use the first existing key (during session initialization) */
248 i = order_keys.begin();
252 /* key exists - use it and reset all others (actually, itself included) */
254 i = order_keys.begin();
257 for (; i != order_keys.end(); ++i) {
263 Route::ensure_track_or_route_name(string name, Session &session)
265 string newname = name;
267 while (session.route_by_name (newname) != NULL) {
268 newname = bump_name_once (newname);
276 Route::inc_gain (gain_t fraction, void *src)
278 _amp->inc_gain (fraction, src);
282 Route::set_gain (gain_t val, void *src)
284 if (src != 0 && _route_group && src != _route_group && _route_group->active_property (RouteGroup::Gain)) {
286 if (_route_group->is_relative()) {
288 gain_t usable_gain = _amp->gain();
289 if (usable_gain < 0.000001f) {
290 usable_gain = 0.000001f;
294 if (delta < 0.000001f) {
298 delta -= usable_gain;
303 gain_t factor = delta / usable_gain;
306 factor = _route_group->get_max_factor(factor);
307 if (factor == 0.0f) {
308 _amp->gain_control()->Changed(); /* EMIT SIGNAL */
312 factor = _route_group->get_min_factor(factor);
313 if (factor == 0.0f) {
314 _amp->gain_control()->Changed(); /* EMIT SIGNAL */
319 _route_group->apply (&Route::inc_gain, factor, _route_group);
323 _route_group->apply (&Route::set_gain, val, _route_group);
329 if (val == _amp->gain()) {
333 _amp->set_gain (val, src);
336 /** Process this route for one (sub) cycle (process thread)
338 * @param bufs Scratch buffers to use for the signal path
339 * @param start_frame Initial transport frame
340 * @param end_frame Final transport frame
341 * @param nframes Number of frames to output (to ports)
343 * Note that (end_frame - start_frame) may not be equal to nframes when the
344 * transport speed isn't 1.0 (eg varispeed).
347 Route::process_output_buffers (BufferSet& bufs,
348 sframes_t start_frame, sframes_t end_frame, nframes_t nframes,
349 bool /*with_processors*/, int declick)
353 bufs.is_silent (false);
355 switch (Config->get_monitoring_model()) {
356 case HardwareMonitoring:
357 case ExternalMonitoring:
358 monitor = !record_enabled() || (_session.config.get_auto_input() && !_session.actively_recording());
365 declick = _pending_declick;
368 /* figure out if we're going to use gain automation */
369 _amp->setup_gain_automation (start_frame, end_frame, nframes);
372 /* tell main outs what to do about monitoring */
373 _main_outs->no_outs_cuz_we_no_monitor (!monitor);
376 /* -------------------------------------------------------------------------------------------
377 GLOBAL DECLICK (for transport changes etc.)
378 ----------------------------------------------------------------------------------------- */
381 Amp::apply_gain (bufs, nframes, 0.0, 1.0);
382 } else if (declick < 0) {
383 Amp::apply_gain (bufs, nframes, 1.0, 0.0);
386 _pending_declick = 0;
388 /* -------------------------------------------------------------------------------------------
389 DENORMAL CONTROL/PHASE INVERT
390 ----------------------------------------------------------------------------------------- */
396 if (_denormal_protection || Config->get_denormal_protection()) {
398 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i, ++chn) {
399 Sample* const sp = i->data();
401 if (_phase_invert & chn) {
402 for (nframes_t nx = 0; nx < nframes; ++nx) {
407 for (nframes_t nx = 0; nx < nframes; ++nx) {
415 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i, ++chn) {
416 Sample* const sp = i->data();
418 if (_phase_invert & chn) {
419 for (nframes_t nx = 0; nx < nframes; ++nx) {
428 if (_denormal_protection || Config->get_denormal_protection()) {
430 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
431 Sample* const sp = i->data();
432 for (nframes_t nx = 0; nx < nframes; ++nx) {
440 /* -------------------------------------------------------------------------------------------
442 ----------------------------------------------------------------------------------------- */
444 Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
447 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
449 if (bufs.count() != (*i)->input_streams()) {
450 cerr << _name << " bufs = " << bufs.count()
451 << " input for " << (*i)->name() << " = " << (*i)->input_streams()
454 assert (bufs.count() == (*i)->input_streams());
456 (*i)->run (bufs, start_frame, end_frame, nframes, *i != _processors.back());
457 bufs.set_count ((*i)->output_streams());
463 Route::n_process_buffers ()
465 return max (_input->n_ports(), processor_max_streams);
469 Route::passthru (sframes_t start_frame, sframes_t end_frame, nframes_t nframes, int declick)
471 BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers());
475 assert (bufs.available() >= _input->n_ports());
477 if (_input->n_ports() == ChanCount::ZERO) {
481 bufs.set_count (_input->n_ports());
483 if (is_control() && _session.listening()) {
485 /* control/monitor bus ignores input ports when something is
486 feeding the listen "stream". data will "arrive" into the
487 route from the intreturn processor element.
490 bufs.silence (nframes, 0);
494 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
496 BufferSet::iterator o = bufs.begin(*t);
497 PortSet& ports (_input->ports());
499 for (PortSet::iterator i = ports.begin(*t); i != ports.end(*t); ++i, ++o) {
500 o->read_from (i->get_buffer(nframes), nframes);
505 write_out_of_band_data (bufs, start_frame, end_frame, nframes);
506 process_output_buffers (bufs, start_frame, end_frame, nframes, true, declick);
510 Route::passthru_silence (sframes_t start_frame, sframes_t end_frame, nframes_t nframes, int declick)
512 BufferSet& bufs (_session.get_silent_buffers (n_process_buffers()));
513 bufs.set_count (_input->n_ports());
514 write_out_of_band_data (bufs, start_frame, end_frame, nframes);
515 process_output_buffers (bufs, start_frame, end_frame, nframes, true, declick);
519 Route::set_listen (bool yn, void* src)
522 if (yn != _control_outs->active()) {
524 _control_outs->activate ();
526 _control_outs->deactivate ();
529 listen_changed (src); /* EMIT SIGNAL */
535 Route::listening () const
538 return _control_outs->active ();
545 Route::set_solo_safe (bool yn, void *src)
547 if (_solo_safe != yn) {
549 solo_safe_changed (src);
554 Route::solo_safe() const
560 Route::set_solo (bool yn, void *src)
566 if (_route_group && src != _route_group && _route_group->active_property (RouteGroup::Solo)) {
567 _route_group->apply (&Route::set_solo, yn, _route_group);
571 if (self_soloed() != yn) {
573 set_delivery_solo ();
574 solo_changed (src); /* EMIT SIGNAL */
575 _solo_control->Changed (); /* EMIT SIGNAL */
580 Route::set_self_solo (bool yn)
586 Route::mod_solo_by_others (int32_t delta)
589 if (_soloed_by_others >= (uint32_t) delta) {
590 _soloed_by_others += delta;
592 _soloed_by_others = 0;
595 _soloed_by_others += delta;
598 set_delivery_solo ();
602 Route::set_delivery_solo ()
604 /* tell all delivery processors what the solo situation is, so that they keep
605 delivering even though Session::soloing() is true and they were not
609 Glib::RWLock::ReaderLock rm (_processor_lock);
610 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
611 boost::shared_ptr<Delivery> d;
613 if ((d = boost::dynamic_pointer_cast<Delivery> (*i)) != 0) {
614 d->set_solo_level (soloed ());
615 d->set_solo_isolated (solo_isolated());
621 Route::set_solo_isolated (bool yn, void *src)
623 if (is_master() || is_control() || is_hidden()) {
627 if (_route_group && src != _route_group && _route_group->active_property (RouteGroup::Solo)) {
628 _route_group->apply (&Route::set_solo_isolated, yn, _route_group);
632 /* forward propagate solo-isolate status to everything fed by this route, but not those via sends only */
634 boost::shared_ptr<RouteList> routes = _session.get_routes ();
635 for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
637 bool does_feed = feeds (*i, &sends_only);
639 if (does_feed && !sends_only) {
640 (*i)->set_solo_isolated (yn, (*i)->route_group());
644 bool changed = false;
647 if (_solo_isolated == 0) {
652 changed = (_solo_isolated == 1);
653 if (_solo_isolated > 0) {
659 set_delivery_solo ();
660 solo_isolated_changed (src);
665 Route::solo_isolated () const
667 return _solo_isolated > 0;
671 Route::set_mute_points (MuteMaster::MutePoint mp)
674 mute_points_changed (); /* EMIT SIGNAL */
676 if (_mute_master->muted()) {
677 _mute_master->mute_at (_mute_points);
678 mute_changed (this); /* EMIT SIGNAL */
683 Route::set_mute (bool yn, void *src)
685 if (_route_group && src != _route_group && _route_group->active_property (RouteGroup::Mute)) {
686 _route_group->apply (&Route::set_mute, yn, _route_group);
692 _mute_master->mute_at (_mute_points);
694 _mute_master->clear_mute ();
697 mute_changed (src); /* EMIT SIGNAL */
704 return _mute_master->muted ();
709 dump_processors(const string& name, const list<boost::shared_ptr<Processor> >& procs)
711 cerr << name << " {" << endl;
712 for (list<boost::shared_ptr<Processor> >::const_iterator p = procs.begin();
713 p != procs.end(); ++p) {
714 cerr << "\t" << (*p)->name() << " ID = " << (*p)->id() << endl;
721 Route::add_processor (boost::shared_ptr<Processor> processor, Placement placement, ProcessorStreams* err)
723 ProcessorList::iterator loc;
725 /* XXX this is not thread safe - we don't hold the lock across determining the iter
726 to add before and actually doing the insertion. dammit.
729 if (placement == PreFader) {
730 /* generic pre-fader: insert immediately before the amp */
731 loc = find (_processors.begin(), _processors.end(), _amp);
733 /* generic post-fader: insert right before the main outs */
734 loc = find (_processors.begin(), _processors.end(), _main_outs);
737 return add_processor (processor, loc, err);
741 /** Add a processor to the route.
742 * If @a iter is not NULL, it must point to an iterator in _processors and the new
743 * processor will be inserted immediately before this location. Otherwise,
744 * @a position is used.
747 Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::iterator iter, ProcessorStreams* err)
749 ChanCount old_pms = processor_max_streams;
751 if (!_session.engine().connected() || !processor) {
756 Glib::RWLock::WriterLock lm (_processor_lock);
758 boost::shared_ptr<PluginInsert> pi;
759 boost::shared_ptr<PortInsert> porti;
761 ProcessorList::iterator loc = find(_processors.begin(), _processors.end(), processor);
763 if (processor == _amp || processor == _meter || processor == _main_outs) {
764 // Ensure only one of these are in the list at any time
765 if (loc != _processors.end()) {
766 if (iter == loc) { // Already in place, do nothing
768 } else { // New position given, relocate
769 _processors.erase (loc);
774 if (loc != _processors.end()) {
775 cerr << "ERROR: Processor added to route twice!" << endl;
782 _processors.insert (loc, processor);
784 // Set up processor list channels. This will set processor->[input|output]_streams(),
785 // configure redirect ports properly, etc.
787 if (configure_processors_unlocked (err)) {
788 ProcessorList::iterator ploc = loc;
790 _processors.erase(ploc);
791 configure_processors_unlocked (0); // it worked before we tried to add it ...
792 cerr << "configure failed\n";
796 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(processor)) != 0) {
798 if (pi->natural_input_streams() == ChanCount::ZERO) {
799 /* generator plugin */
800 _have_internal_generator = true;
805 if (_control_outs != processor) {
806 // XXX: do we want to emit the signal here ? change call order.
807 processor->activate ();
810 processor->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false, false));
812 _output->set_user_latency (0);
815 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
821 Route::add_processor_from_xml (const XMLNode& node, ProcessorList::iterator iter)
823 const XMLProperty *prop;
825 if (node.name() != "Processor") {
830 if ((prop = node.property ("type")) != 0) {
832 boost::shared_ptr<Processor> processor;
834 if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
835 prop->value() == "lv2" ||
836 prop->value() == "vst" ||
837 prop->value() == "audiounit") {
839 processor.reset (new PluginInsert(_session, node));
841 } else if (prop->value() == "port") {
843 processor.reset (new PortInsert (_session, _mute_master, node));
845 } else if (prop->value() == "send") {
847 processor.reset (new Send (_session, _mute_master, node));
849 } else if (prop->value() == "meter") {
852 if (_meter->set_state (node, Stateful::loading_state_version)) {
859 _meter.reset (new PeakMeter (_session, node));
860 _meter->set_display_to_user (_meter_point == MeterCustom);
863 } else if (prop->value() == "amp") {
865 /* amp always exists */
868 if (processor->set_state (node, Stateful::loading_state_version)) {
871 /* never any reason to add it */
875 } else if (prop->value() == "intsend") {
877 processor.reset (new InternalSend (_session, _mute_master, node));
879 } else if (prop->value() == "intreturn") {
882 if (_intreturn->set_state (node, Stateful::loading_state_version)) {
888 _intreturn.reset (new InternalReturn (_session, node));
889 processor = _intreturn;
891 } else if (prop->value() == "main-outs") {
894 if (_main_outs->set_state (node, Stateful::loading_state_version)) {
901 _main_outs.reset (new Delivery (_session, _output, _mute_master, node));
902 processor = _main_outs;
905 error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
909 if (iter == _processors.end() && processor->display_to_user() && !_processors.empty()) {
910 /* check for invisible processors stacked at the end and leave them there */
911 ProcessorList::iterator p;
912 p = _processors.end();
914 while (!(*p)->display_to_user() && p != _processors.begin()) {
921 return (add_processor (processor, iter) == 0);
924 error << _("Processor XML node has no type property") << endmsg;
929 catch (failed_constructor &err) {
930 warning << _("processor could not be created. Ignored.") << endmsg;
937 Route::add_processor_from_xml_2X (const XMLNode& node, int version, ProcessorList::iterator iter)
939 const XMLProperty *prop;
942 boost::shared_ptr<Processor> processor;
944 if (node.name() == "Insert") {
946 if ((prop = node.property ("type")) != 0) {
948 if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
949 prop->value() == "lv2" ||
950 prop->value() == "vst" ||
951 prop->value() == "audiounit") {
953 processor.reset (new PluginInsert (_session, node));
957 processor.reset (new PortInsert (_session, _mute_master, node));
962 } else if (node.name() == "Send") {
964 processor.reset (new Send (_session, _mute_master, node, version));
968 error << string_compose(_("unknown Processor type \"%1\"; ignored"), node.name()) << endmsg;
972 if (iter == _processors.end() && processor->display_to_user() && !_processors.empty()) {
973 /* check for invisible processors stacked at the end and leave them there */
974 ProcessorList::iterator p;
975 p = _processors.end();
977 while (!(*p)->display_to_user() && p != _processors.begin()) {
984 return (add_processor (processor, iter) == 0);
987 catch (failed_constructor &err) {
988 warning << _("processor could not be created. Ignored.") << endmsg;
994 Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor> before, ProcessorStreams* err)
996 ProcessorList::iterator loc;
999 loc = find(_processors.begin(), _processors.end(), before);
1001 /* nothing specified - at end but before main outs */
1002 loc = find (_processors.begin(), _processors.end(), _main_outs);
1005 return add_processors (others, loc, err);
1009 Route::add_processors (const ProcessorList& others, ProcessorList::iterator iter, ProcessorStreams* err)
1011 /* NOTE: this is intended to be used ONLY when copying
1012 processors from another Route. Hence the subtle
1013 differences between this and ::add_processor()
1016 ChanCount old_pms = processor_max_streams;
1018 if (!_session.engine().connected()) {
1022 if (others.empty()) {
1027 Glib::RWLock::WriterLock lm (_processor_lock);
1029 ChanCount potential_max_streams = ChanCount::max (_input->n_ports(), _output->n_ports());
1031 for (ProcessorList::const_iterator i = others.begin(); i != others.end(); ++i) {
1033 // Ensure meter only appears in the list once
1035 ProcessorList::iterator m = find(_processors.begin(), _processors.end(), *i);
1036 if (m != _processors.end()) {
1037 _processors.erase(m);
1041 boost::shared_ptr<PluginInsert> pi;
1043 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
1046 ChanCount m = max (pi->input_streams(), pi->output_streams());
1048 if (m > potential_max_streams) {
1049 potential_max_streams = m;
1053 ProcessorList::iterator inserted = _processors.insert (iter, *i);
1055 if ((*i)->active()) {
1059 if (configure_processors_unlocked (err)) {
1060 _processors.erase (inserted);
1061 configure_processors_unlocked (0); // it worked before we tried to add it ...
1065 (*i)->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false, false));
1068 _output->set_user_latency (0);
1071 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1077 Route::placement_range(Placement p, ProcessorList::iterator& start, ProcessorList::iterator& end)
1079 if (p == PreFader) {
1080 start = _processors.begin();
1081 end = find(_processors.begin(), _processors.end(), _amp);
1083 start = find(_processors.begin(), _processors.end(), _amp);
1085 end = _processors.end();
1089 /** Turn off all processors with a given placement
1090 * @param p Placement of processors to disable
1093 Route::disable_processors (Placement p)
1095 Glib::RWLock::ReaderLock lm (_processor_lock);
1097 ProcessorList::iterator start, end;
1098 placement_range(p, start, end);
1100 for (ProcessorList::iterator i = start; i != end; ++i) {
1101 (*i)->deactivate ();
1104 _session.set_dirty ();
1107 /** Turn off all redirects
1110 Route::disable_processors ()
1112 Glib::RWLock::ReaderLock lm (_processor_lock);
1114 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1115 (*i)->deactivate ();
1118 _session.set_dirty ();
1121 /** Turn off all redirects with a given placement
1122 * @param p Placement of redirects to disable
1125 Route::disable_plugins (Placement p)
1127 Glib::RWLock::ReaderLock lm (_processor_lock);
1129 ProcessorList::iterator start, end;
1130 placement_range(p, start, end);
1132 for (ProcessorList::iterator i = start; i != end; ++i) {
1133 if (boost::dynamic_pointer_cast<PluginInsert> (*i)) {
1134 (*i)->deactivate ();
1138 _session.set_dirty ();
1141 /** Turn off all plugins
1144 Route::disable_plugins ()
1146 Glib::RWLock::ReaderLock lm (_processor_lock);
1148 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1149 if (boost::dynamic_pointer_cast<PluginInsert> (*i)) {
1150 (*i)->deactivate ();
1154 _session.set_dirty ();
1159 Route::ab_plugins (bool forward)
1161 Glib::RWLock::ReaderLock lm (_processor_lock);
1165 /* forward = turn off all active redirects, and mark them so that the next time
1166 we go the other way, we will revert them
1169 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1170 if (!boost::dynamic_pointer_cast<PluginInsert> (*i)) {
1174 if ((*i)->active()) {
1175 (*i)->deactivate ();
1176 (*i)->set_next_ab_is_active (true);
1178 (*i)->set_next_ab_is_active (false);
1184 /* backward = if the redirect was marked to go active on the next ab, do so */
1186 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1188 if (!boost::dynamic_pointer_cast<PluginInsert> (*i)) {
1192 if ((*i)->get_next_ab_is_active()) {
1195 (*i)->deactivate ();
1200 _session.set_dirty ();
1204 /** Remove processors with a given placement.
1205 * @param p Placement of processors to remove.
1208 Route::clear_processors (Placement p)
1210 const ChanCount old_pms = processor_max_streams;
1212 if (!_session.engine().connected()) {
1216 bool already_deleting = _session.deletion_in_progress();
1217 if (!already_deleting) {
1218 _session.set_deletion_in_progress();
1222 Glib::RWLock::WriterLock lm (_processor_lock);
1223 ProcessorList new_list;
1224 ProcessorStreams err;
1225 bool seen_amp = false;
1227 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1233 if ((*i) == _amp || (*i) == _meter || (*i) == _main_outs) {
1235 /* you can't remove these */
1237 new_list.push_back (*i);
1244 new_list.push_back (*i);
1247 (*i)->drop_references ();
1255 (*i)->drop_references ();
1258 new_list.push_back (*i);
1265 _processors = new_list;
1266 configure_processors_unlocked (&err); // this can't fail
1269 processor_max_streams.reset();
1270 _have_internal_generator = false;
1271 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1273 if (!already_deleting) {
1274 _session.clear_deletion_in_progress();
1279 Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStreams* err)
1281 /* these can never be removed */
1283 if (processor == _amp || processor == _meter || processor == _main_outs) {
1287 ChanCount old_pms = processor_max_streams;
1289 if (!_session.engine().connected()) {
1293 processor_max_streams.reset();
1296 Glib::RWLock::WriterLock lm (_processor_lock);
1297 ProcessorList::iterator i;
1298 bool removed = false;
1300 for (i = _processors.begin(); i != _processors.end(); ) {
1301 if (*i == processor) {
1303 /* move along, see failure case for configure_processors()
1304 where we may need to reconfigure the processor.
1307 /* stop redirects that send signals to JACK ports
1308 from causing noise as a result of no longer being
1312 boost::shared_ptr<IOProcessor> iop;
1314 if ((iop = boost::dynamic_pointer_cast<IOProcessor> (*i)) != 0) {
1316 iop->input()->disconnect (this);
1318 if (iop->output()) {
1319 iop->output()->disconnect (this);
1323 i = _processors.erase (i);
1331 _output->set_user_latency (0);
1339 if (configure_processors_unlocked (err)) {
1340 /* get back to where we where */
1341 _processors.insert (i, processor);
1342 /* we know this will work, because it worked before :) */
1343 configure_processors_unlocked (0);
1347 _have_internal_generator = false;
1349 for (i = _processors.begin(); i != _processors.end(); ++i) {
1350 boost::shared_ptr<PluginInsert> pi;
1352 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
1353 if (pi->is_generator()) {
1354 _have_internal_generator = true;
1361 processor->drop_references ();
1362 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1368 Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams* err)
1370 ProcessorList deleted;
1371 ProcessorList as_we_were;
1373 if (!_session.engine().connected()) {
1377 processor_max_streams.reset();
1380 Glib::RWLock::WriterLock lm (_processor_lock);
1381 ProcessorList::iterator i;
1382 boost::shared_ptr<Processor> processor;
1384 as_we_were = _processors;
1386 for (i = _processors.begin(); i != _processors.end(); ) {
1390 /* these can never be removed */
1392 if (processor == _amp || processor == _meter || processor == _main_outs) {
1397 /* see if its in the list of processors to delete */
1399 if (find (to_be_deleted.begin(), to_be_deleted.end(), processor) == to_be_deleted.end()) {
1404 /* stop IOProcessors that send to JACK ports
1405 from causing noise as a result of no longer being
1409 boost::shared_ptr<IOProcessor> iop;
1411 if ((iop = boost::dynamic_pointer_cast<IOProcessor> (processor)) != 0) {
1415 deleted.push_back (processor);
1416 i = _processors.erase (i);
1419 if (deleted.empty()) {
1420 /* none of those in the requested list were found */
1424 _output->set_user_latency (0);
1426 if (configure_processors_unlocked (err)) {
1427 /* get back to where we where */
1428 _processors = as_we_were;
1429 /* we know this will work, because it worked before :) */
1430 configure_processors_unlocked (0);
1434 _have_internal_generator = false;
1436 for (i = _processors.begin(); i != _processors.end(); ++i) {
1437 boost::shared_ptr<PluginInsert> pi;
1439 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
1440 if (pi->is_generator()) {
1441 _have_internal_generator = true;
1448 /* now try to do what we need to so that those that were removed will be deleted */
1450 for (ProcessorList::iterator i = deleted.begin(); i != deleted.end(); ++i) {
1451 (*i)->drop_references ();
1454 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1461 Route::configure_processors (ProcessorStreams* err)
1463 if (!_in_configure_processors) {
1464 Glib::RWLock::WriterLock lm (_processor_lock);
1465 return configure_processors_unlocked (err);
1470 /** Configure the input/output configuration of each processor in the processors list.
1471 * Return 0 on success, otherwise configuration is impossible.
1474 Route::configure_processors_unlocked (ProcessorStreams* err)
1476 if (_in_configure_processors) {
1480 _in_configure_processors = true;
1482 // Check each processor in order to see if we can configure as requested
1483 ChanCount in = _input->n_ports ();
1485 list< pair<ChanCount,ChanCount> > configuration;
1488 DEBUG_TRACE (DEBUG::Processors, string_compose ("%1: configure processors\n", _name));
1490 DEBUG_TRACE (DEBUG::Processors, "{\n");
1491 for (list<boost::shared_ptr<Processor> >::const_iterator p = _processors.begin(); p != _processors.end(); ++p) {
1492 DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1 ID = %2\n", (*p)->name(), (*p)->id()));
1494 DEBUG_TRACE (DEBUG::Processors, "}\n");
1497 for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++index) {
1499 if ((*p)->can_support_io_configuration(in, out)) {
1500 DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1in = %2 out = %3\n",(*p)->name(), in, out));
1501 configuration.push_back(make_pair(in, out));
1508 _in_configure_processors = false;
1513 // We can, so configure everything
1514 list< pair<ChanCount,ChanCount> >::iterator c = configuration.begin();
1515 for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++c) {
1516 (*p)->configure_io(c->first, c->second);
1517 processor_max_streams = ChanCount::max(processor_max_streams, c->first);
1518 processor_max_streams = ChanCount::max(processor_max_streams, c->second);
1523 _meter->reset_max_channels (processor_max_streams);
1526 /* make sure we have sufficient scratch buffers to cope with the new processor
1528 _session.ensure_buffers (n_process_buffers ());
1530 _in_configure_processors = false;
1535 Route::all_processors_flip ()
1537 Glib::RWLock::ReaderLock lm (_processor_lock);
1539 if (_processors.empty()) {
1543 bool first_is_on = _processors.front()->active();
1545 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1547 (*i)->deactivate ();
1553 _session.set_dirty ();
1556 /** Set all processors with a given placement to a given active state.
1557 * @param p Placement of processors to change.
1558 * @param state New active state for those processors.
1561 Route::all_processors_active (Placement p, bool state)
1563 Glib::RWLock::ReaderLock lm (_processor_lock);
1565 if (_processors.empty()) {
1568 ProcessorList::iterator start, end;
1569 placement_range(p, start, end);
1571 bool before_amp = true;
1572 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1577 if (p == PreFader && before_amp) {
1581 (*i)->deactivate ();
1586 _session.set_dirty ();
1590 Route::processor_is_prefader (boost::shared_ptr<Processor> p)
1592 bool pre_fader = true;
1593 Glib::RWLock::ReaderLock lm (_processor_lock);
1595 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1597 /* semantic note: if p == amp, we want to return true, so test
1598 for equality before checking if this is the amp
1615 Route::reorder_processors (const ProcessorList& new_order, ProcessorStreams* err)
1617 /* "new_order" is an ordered list of processors to be positioned according to "placement".
1618 NOTE: all processors in "new_order" MUST be marked as display_to_user(). There maybe additional
1619 processors in the current actual processor list that are hidden. Any visible processors
1620 in the current list but not in "new_order" will be assumed to be deleted.
1624 Glib::RWLock::WriterLock lm (_processor_lock);
1625 ChanCount old_pms = processor_max_streams;
1626 ProcessorList::iterator oiter;
1627 ProcessorList::const_iterator niter;
1628 ProcessorList as_it_was_before = _processors;
1629 ProcessorList as_it_will_be;
1631 oiter = _processors.begin();
1632 niter = new_order.begin();
1634 while (niter != new_order.end()) {
1636 /* if the next processor in the old list is invisible (i.e. should not be in the new order)
1637 then append it to the temp list.
1639 Otherwise, see if the next processor in the old list is in the new list. if not,
1640 its been deleted. If its there, append it to the temp list.
1643 if (oiter == _processors.end()) {
1645 /* no more elements in the old list, so just stick the rest of
1646 the new order onto the temp list.
1649 as_it_will_be.insert (as_it_will_be.end(), niter, new_order.end());
1650 while (niter != new_order.end()) {
1657 if (!(*oiter)->display_to_user()) {
1659 as_it_will_be.push_back (*oiter);
1663 /* visible processor: check that its in the new order */
1665 if (find (new_order.begin(), new_order.end(), (*oiter)) == new_order.end()) {
1666 /* deleted: do nothing, shared_ptr<> will clean up */
1668 /* ignore this one, and add the next item from the new order instead */
1669 as_it_will_be.push_back (*niter);
1674 /* now remove from old order - its taken care of no matter what */
1675 oiter = _processors.erase (oiter);
1680 _processors.insert (oiter, as_it_will_be.begin(), as_it_will_be.end());
1682 if (configure_processors_unlocked (err)) {
1683 _processors = as_it_was_before;
1684 processor_max_streams = old_pms;
1689 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1701 Route::get_template()
1703 return state(false);
1707 Route::state(bool full_state)
1709 XMLNode *node = new XMLNode("Route");
1710 ProcessorList::iterator i;
1713 id().print (buf, sizeof (buf));
1714 node->add_property("id", buf);
1715 node->add_property ("name", _name);
1716 node->add_property("default-type", _default_type.to_string());
1719 node->add_property("flags", enum_2_string (_flags));
1722 node->add_property("active", _active?"yes":"no");
1723 node->add_property("phase-invert", _phase_invert?"yes":"no");
1724 node->add_property("denormal-protection", _denormal_protection?"yes":"no");
1725 node->add_property("meter-point", enum_2_string (_meter_point));
1728 node->add_property("route-group", _route_group->name());
1731 string order_string;
1732 OrderKeys::iterator x = order_keys.begin();
1734 while (x != order_keys.end()) {
1735 order_string += string ((*x).first);
1736 order_string += '=';
1737 snprintf (buf, sizeof(buf), "%ld", (*x).second);
1738 order_string += buf;
1742 if (x == order_keys.end()) {
1746 order_string += ':';
1748 node->add_property ("order-keys", order_string);
1749 node->add_property ("self-solo", (_self_solo ? "yes" : "no"));
1750 snprintf (buf, sizeof (buf), "%d", _soloed_by_others);
1751 node->add_property ("soloed-by-others", buf);
1753 node->add_child_nocopy (_input->state (full_state));
1754 node->add_child_nocopy (_output->state (full_state));
1755 node->add_child_nocopy (_solo_control->get_state ());
1756 node->add_child_nocopy (_mute_master->get_state ());
1758 XMLNode* remote_control_node = new XMLNode (X_("RemoteControl"));
1759 snprintf (buf, sizeof (buf), "%d", _remote_control_id);
1760 remote_control_node->add_property (X_("id"), buf);
1761 node->add_child_nocopy (*remote_control_node);
1763 if (_comment.length()) {
1764 XMLNode *cmt = node->add_child ("Comment");
1765 cmt->add_content (_comment);
1768 for (i = _processors.begin(); i != _processors.end(); ++i) {
1769 node->add_child_nocopy((*i)->state (full_state));
1773 node->add_child_copy (*_extra_xml);
1780 Route::set_state (const XMLNode& node, int version)
1782 return _set_state (node, version, true);
1786 Route::_set_state (const XMLNode& node, int version, bool /*call_base*/)
1788 if (version < 3000) {
1789 return _set_state_2X (node, version);
1793 XMLNodeConstIterator niter;
1795 XMLPropertyList plist;
1796 const XMLProperty *prop;
1798 if (node.name() != "Route"){
1799 error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
1803 if ((prop = node.property (X_("name"))) != 0) {
1804 Route::set_name (prop->value());
1807 if ((prop = node.property ("id")) != 0) {
1808 _id = prop->value ();
1811 if ((prop = node.property (X_("flags"))) != 0) {
1812 _flags = Flag (string_2_enum (prop->value(), _flags));
1817 /* add all processors (except amp, which is always present) */
1819 nlist = node.children();
1820 XMLNode processor_state (X_("processor_state"));
1822 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1826 if (child->name() == IO::state_node_name) {
1827 if ((prop = child->property (X_("direction"))) == 0) {
1831 if (prop->value() == "Input") {
1832 _input->set_state (*child, version);
1833 } else if (prop->value() == "Output") {
1834 _output->set_state (*child, version);
1838 if (child->name() == X_("Processor")) {
1839 processor_state.add_child_copy (*child);
1843 set_processor_state (processor_state);
1845 if ((prop = node.property ("self-solo")) != 0) {
1846 set_self_solo (string_is_affirmative (prop->value()));
1849 if ((prop = node.property ("soloed-by-others")) != 0) {
1850 _soloed_by_others = 0; // needed for mod_solo_by_others () to work
1851 mod_solo_by_others (atoi (prop->value()));
1854 if ((prop = node.property ("solo-isolated")) != 0) {
1855 set_solo_isolated (string_is_affirmative (prop->value()), this);
1858 if ((prop = node.property (X_("phase-invert"))) != 0) {
1859 set_phase_invert (string_is_affirmative (prop->value()));
1862 if ((prop = node.property (X_("denormal-protection"))) != 0) {
1863 set_denormal_protection (string_is_affirmative (prop->value()));
1866 if ((prop = node.property (X_("active"))) != 0) {
1867 bool yn = string_is_affirmative (prop->value());
1868 _active = !yn; // force switch
1872 if ((prop = node.property (X_("meter-point"))) != 0) {
1873 _meter_point = MeterPoint (string_2_enum (prop->value (), _meter_point));
1875 _meter->set_display_to_user (_meter_point == MeterCustom);
1879 if ((prop = node.property (X_("order-keys"))) != 0) {
1883 string::size_type colon, equal;
1884 string remaining = prop->value();
1886 while (remaining.length()) {
1888 if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
1889 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1892 if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) {
1893 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1896 set_order_key (remaining.substr (0, equal), n);
1900 colon = remaining.find_first_of (':');
1902 if (colon != string::npos) {
1903 remaining = remaining.substr (colon+1);
1910 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1913 if (child->name() == X_("Comment")) {
1915 /* XXX this is a terrible API design in libxml++ */
1917 XMLNode *cmt = *(child->children().begin());
1918 _comment = cmt->content();
1920 } else if (child->name() == X_("Extra")) {
1922 _extra_xml = new XMLNode (*child);
1924 } else if (child->name() == X_("Controllable") && (prop = child->property("name")) != 0) {
1926 if (prop->value() == "solo") {
1927 _solo_control->set_state (*child, version);
1928 _session.add_controllable (_solo_control);
1931 } else if (child->name() == X_("RemoteControl")) {
1932 if ((prop = child->property (X_("id"))) != 0) {
1934 sscanf (prop->value().c_str(), "%d", &x);
1935 set_remote_control_id (x);
1938 } else if (child->name() == X_("MuteMaster")) {
1939 _mute_master->set_state (*child, version);
1947 Route::_set_state_2X (const XMLNode& node, int version)
1950 XMLNodeConstIterator niter;
1952 XMLPropertyList plist;
1953 const XMLProperty *prop;
1955 /* 2X things which still remain to be handled:
1958 * mute-affects-pre-fader
1959 * mute-affects-post-fader
1960 * mute-affects-control-outs
1961 * mute-affects-main-outs
1966 if (node.name() != "Route") {
1967 error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
1971 if ((prop = node.property (X_("flags"))) != 0) {
1972 _flags = Flag (string_2_enum (prop->value(), _flags));
1977 /* add standard processors */
1979 _meter.reset (new PeakMeter (_session));
1980 add_processor (_meter, PreFader);
1982 if (_flags & ControlOut) {
1983 /* where we listen to tracks */
1984 _intreturn.reset (new InternalReturn (_session));
1985 add_processor (_intreturn, PreFader);
1988 _main_outs.reset (new Delivery (_session, _output, _mute_master, _name, Delivery::Main));
1989 add_processor (_main_outs, PostFader);
1993 nlist = node.children ();
1994 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1998 if (child->name() == IO::state_node_name) {
2000 /* there is a note in IO::set_state_2X() about why we have to call
2004 _input->set_state_2X (*child, version, true);
2005 _output->set_state_2X (*child, version, false);
2007 if ((prop = child->property (X_("name"))) != 0) {
2008 set_name (prop->value ());
2011 if ((prop = child->property (X_("id"))) != 0) {
2012 _id = prop->value ();
2015 if ((prop = child->property (X_("active"))) != 0) {
2016 bool yn = string_is_affirmative (prop->value());
2017 _active = !yn; // force switch
2025 if ((prop = node.property (X_("phase-invert"))) != 0) {
2026 set_phase_invert (string_is_affirmative (prop->value()));
2029 if ((prop = node.property (X_("denormal-protection"))) != 0) {
2030 set_denormal_protection (string_is_affirmative (prop->value()));
2033 if ((prop = node.property (X_("soloed"))) != 0) {
2034 bool yn = string_is_affirmative (prop->value());
2036 /* XXX force reset of solo status */
2038 set_solo (yn, this);
2041 if ((prop = node.property (X_("meter-point"))) != 0) {
2042 _meter_point = MeterPoint (string_2_enum (prop->value (), _meter_point));
2045 /* do not carry over edit/mix groups from 2.X because (a) its hard (b) they
2046 don't mean the same thing.
2049 if ((prop = node.property (X_("order-keys"))) != 0) {
2053 string::size_type colon, equal;
2054 string remaining = prop->value();
2056 while (remaining.length()) {
2058 if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
2059 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
2062 if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) {
2063 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
2066 set_order_key (remaining.substr (0, equal), n);
2070 colon = remaining.find_first_of (':');
2072 if (colon != string::npos) {
2073 remaining = remaining.substr (colon+1);
2080 XMLNodeList redirect_nodes;
2082 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
2086 if (child->name() == X_("Send") || child->name() == X_("Insert")) {
2087 redirect_nodes.push_back(child);
2092 set_processor_state_2X (redirect_nodes, version);
2094 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
2097 if (child->name() == X_("Comment")) {
2099 /* XXX this is a terrible API design in libxml++ */
2101 XMLNode *cmt = *(child->children().begin());
2102 _comment = cmt->content();
2104 } else if (child->name() == X_("Extra")) {
2106 _extra_xml = new XMLNode (*child);
2108 } else if (child->name() == X_("Controllable") && (prop = child->property("name")) != 0) {
2110 if (prop->value() == "solo") {
2111 _solo_control->set_state (*child, version);
2112 _session.add_controllable (_solo_control);
2115 } else if (child->name() == X_("RemoteControl")) {
2116 if ((prop = child->property (X_("id"))) != 0) {
2118 sscanf (prop->value().c_str(), "%d", &x);
2119 set_remote_control_id (x);
2129 Route::get_processor_state ()
2131 XMLNode* root = new XMLNode (X_("redirects"));
2132 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2133 root->add_child_nocopy ((*i)->state (true));
2140 Route::set_processor_state_2X (XMLNodeList const & nList, int version)
2142 /* We don't bother removing existing processors not in nList, as this
2143 method will only be called when creating a Route from scratch, not
2144 for undo purposes. Just put processors in at the appropriate place
2148 for (XMLNodeConstIterator i = nList.begin(); i != nList.end(); ++i) {
2149 add_processor_from_xml_2X (**i, version, _processors.begin ());
2154 Route::set_processor_state (const XMLNode& node)
2156 const XMLNodeList &nlist = node.children();
2157 XMLNodeConstIterator niter;
2158 ProcessorList::iterator i, o;
2160 // Iterate through existing processors, remove those which are not in the state list
2162 for (i = _processors.begin(); i != _processors.end(); ) {
2164 /* leave amp alone, always */
2171 ProcessorList::iterator tmp = i;
2174 bool processorInStateList = false;
2176 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2178 XMLProperty* id_prop = (*niter)->property(X_("id"));
2180 if (id_prop && (*i)->id() == id_prop->value()) {
2181 processorInStateList = true;
2186 if (!processorInStateList) {
2187 remove_processor (*i);
2193 // Iterate through state list and make sure all processors are on the track and in the correct order,
2194 // set the state of existing processors according to the new state on the same go
2196 i = _processors.begin();
2198 for (niter = nlist.begin(); niter != nlist.end(); ++niter, ++i) {
2200 XMLProperty* prop = (*niter)->property ("type");
2204 // Check whether the next processor in the list is the right one,
2205 // except for "amp" which is always there and may not have the
2206 // old ID since it is always created anew in every Route
2208 if (prop->value() != "amp") {
2209 while (o != _processors.end()) {
2210 XMLProperty* id_prop = (*niter)->property(X_("id"));
2211 if (id_prop && (*o)->id() == id_prop->value()) {
2219 // If the processor (*niter) is not on the route,
2220 // create it and move it to the correct location
2222 if (o == _processors.end()) {
2224 if (add_processor_from_xml (**niter, i)) {
2225 --i; // move iterator to the newly inserted processor
2227 cerr << "Error restoring route: unable to restore processor" << endl;
2232 // Otherwise, the processor already exists; just
2233 // ensure it is at the location provided in the XML state
2236 boost::shared_ptr<Processor> tmp = (*o);
2237 _processors.erase (o); // remove the old copy
2238 _processors.insert (i, tmp); // insert the processor at the correct location
2239 --i; // move iterator to the correct processor
2242 // and make it (just) so
2244 (*i)->set_state (**niter, Stateful::current_state_version);
2248 /* note: there is no configure_processors() call because we figure that
2249 the XML state represents a working signal route.
2252 processors_changed (RouteProcessorChange ());
2256 Route::curve_reallocate ()
2258 // _gain_automation_curve.finish_resize ();
2259 // _pan_automation_curve.finish_resize ();
2263 Route::silence (nframes_t nframes)
2267 _output->silence (nframes);
2270 Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
2273 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2274 boost::shared_ptr<PluginInsert> pi;
2276 if (!_active && (pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
2277 // skip plugins, they don't need anything when we're not active
2281 (*i)->silence (nframes);
2284 if (nframes == _session.get_block_size()) {
2294 Route::add_internal_return ()
2297 _intreturn.reset (new InternalReturn (_session));
2298 add_processor (_intreturn, PreFader);
2303 Route::get_return_buffer () const
2305 Glib::RWLock::ReaderLock rm (_processor_lock);
2307 for (ProcessorList::const_iterator x = _processors.begin(); x != _processors.end(); ++x) {
2308 boost::shared_ptr<InternalReturn> d = boost::dynamic_pointer_cast<InternalReturn>(*x);
2311 BufferSet* bs = d->get_buffers ();
2320 Route::release_return_buffer () const
2322 Glib::RWLock::ReaderLock rm (_processor_lock);
2324 for (ProcessorList::const_iterator x = _processors.begin(); x != _processors.end(); ++x) {
2325 boost::shared_ptr<InternalReturn> d = boost::dynamic_pointer_cast<InternalReturn>(*x);
2328 return d->release_buffers ();
2334 Route::listen_via (boost::shared_ptr<Route> route, Placement placement, bool /*active*/, bool aux)
2336 vector<string> ports;
2337 vector<string>::const_iterator i;
2340 Glib::RWLock::ReaderLock rm (_processor_lock);
2342 for (ProcessorList::iterator x = _processors.begin(); x != _processors.end(); ++x) {
2344 boost::shared_ptr<InternalSend> d = boost::dynamic_pointer_cast<InternalSend>(*x);
2346 if (d && d->target_route() == route) {
2348 /* if the target is the control outs, then make sure
2349 we take note of which i-send is doing that.
2352 if (route == _session.control_out()) {
2353 _control_outs = boost::dynamic_pointer_cast<Delivery>(d);
2356 /* already listening via the specified IO: do nothing */
2363 boost::shared_ptr<InternalSend> listener;
2366 listener.reset (new InternalSend (_session, _mute_master, route, (aux ? Delivery::Aux : Delivery::Listen)));
2368 } catch (failed_constructor& err) {
2372 if (route == _session.control_out()) {
2373 _control_outs = listener;
2376 add_processor (listener, placement);
2382 Route::drop_listen (boost::shared_ptr<Route> route)
2384 ProcessorStreams err;
2385 ProcessorList::iterator tmp;
2387 Glib::RWLock::ReaderLock rl(_processor_lock);
2391 for (ProcessorList::iterator x = _processors.begin(); x != _processors.end(); ) {
2393 boost::shared_ptr<InternalSend> d = boost::dynamic_pointer_cast<InternalSend>(*x);
2395 if (d && d->target_route() == route) {
2397 remove_processor (*x, &err);
2400 /* list could have been demolished while we dropped the lock
2410 if (route == _session.control_out()) {
2411 _control_outs.reset ();
2416 Route::set_comment (string cmt, void *src)
2419 comment_changed (src);
2420 _session.set_dirty ();
2424 Route::feeds (boost::shared_ptr<Route> other, bool* only_send)
2426 DEBUG_TRACE (DEBUG::Graph, string_compose ("Feeds? %1\n", _name));
2428 if (_output->connected_to (other->input())) {
2429 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tdirect FEEDS %2\n", other->name()));
2438 for (ProcessorList::iterator r = _processors.begin(); r != _processors.end(); r++) {
2440 boost::shared_ptr<IOProcessor> iop;
2442 if ((iop = boost::dynamic_pointer_cast<IOProcessor>(*r)) != 0) {
2443 if (iop->feeds (other)) {
2444 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tIOP %1 does feed %2\n", iop->name(), other->name()));
2450 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tIOP %1 does NOT feed %2\n", iop->name(), other->name()));
2453 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tPROC %1 is not an IOP\n", (*r)->name()));
2458 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tdoes NOT feed %1\n", other->name()));
2463 Route::handle_transport_stopped (bool /*abort_ignored*/, bool did_locate, bool can_flush_processors)
2465 nframes_t now = _session.transport_frame();
2468 Glib::RWLock::ReaderLock lm (_processor_lock);
2471 automation_snapshot (now, true);
2474 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2476 if (Config->get_plugins_stop_with_transport() && can_flush_processors) {
2477 (*i)->deactivate ();
2481 (*i)->transport_stopped (now);
2485 _roll_delay = _initial_delay;
2489 Route::input_change_handler (IOChange change, void * /*src*/)
2491 if ((change & ConfigurationChanged)) {
2492 configure_processors (0);
2497 Route::output_change_handler (IOChange change, void * /*src*/)
2499 if ((change & ConfigurationChanged)) {
2501 /* XXX resize all listeners to match _main_outs? */
2503 // configure_processors (0);
2508 Route::pans_required () const
2510 if (n_outputs().n_audio() < 2) {
2514 return max (n_inputs ().n_audio(), processor_max_streams.n_audio());
2518 Route::no_roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame,
2519 bool session_state_changing, bool /*can_record*/, bool /*rec_monitors_input*/)
2521 if (n_outputs().n_total() == 0) {
2525 if (!_active || n_inputs() == ChanCount::ZERO) {
2529 if (session_state_changing) {
2530 if (_session.transport_speed() != 0.0f) {
2531 /* we're rolling but some state is changing (e.g. our diskstream contents)
2532 so we cannot use them. Be silent till this is over.
2534 XXX note the absurdity of ::no_roll() being called when we ARE rolling!
2539 /* we're really not rolling, so we're either delivery silence or actually
2540 monitoring, both of which are safe to do while session_state_changing is true.
2544 _amp->apply_gain_automation (false);
2545 passthru (start_frame, end_frame, nframes, 0);
2551 Route::check_initial_delay (nframes_t nframes, nframes_t& transport_frame)
2553 if (_roll_delay > nframes) {
2555 _roll_delay -= nframes;
2557 /* transport frame is not legal for caller to use */
2560 } else if (_roll_delay > 0) {
2562 nframes -= _roll_delay;
2563 silence (_roll_delay);
2564 /* we've written _roll_delay of samples into the
2565 output ports, so make a note of that for
2568 _main_outs->increment_output_offset (_roll_delay);
2569 transport_frame += _roll_delay;
2578 Route::roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame, int declick,
2579 bool /*can_record*/, bool /*rec_monitors_input*/)
2582 // automation snapshot can also be called from the non-rt context
2583 // and it uses the processor list, so we try to acquire the lock here
2584 Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
2587 automation_snapshot (_session.transport_frame(), false);
2591 if (n_outputs().n_total() == 0) {
2595 if (!_active || n_inputs().n_total() == 0) {
2600 nframes_t unused = 0;
2602 if ((nframes = check_initial_delay (nframes, unused)) == 0) {
2608 passthru (start_frame, end_frame, nframes, declick);
2614 Route::silent_roll (nframes_t nframes, sframes_t /*start_frame*/, sframes_t /*end_frame*/,
2615 bool /*can_record*/, bool /*rec_monitors_input*/)
2622 Route::toggle_monitor_input ()
2624 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
2625 i->ensure_monitor_input( ! i->monitoring_input());
2630 Route::has_external_redirects () const
2632 // FIXME: what about sends? - they don't return a signal back to ardour?
2634 boost::shared_ptr<const PortInsert> pi;
2636 for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
2638 if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*i)) != 0) {
2640 for (PortSet::const_iterator port = pi->output()->ports().begin(); port != pi->output()->ports().end(); ++port) {
2642 string port_name = port->name();
2643 string client_name = port_name.substr (0, port_name.find(':'));
2645 /* only say "yes" if the redirect is actually in use */
2647 if (client_name != "ardour" && pi->active()) {
2658 Route::flush_processors ()
2660 /* XXX shouldn't really try to take this lock, since
2661 this is called from the RT audio thread.
2664 Glib::RWLock::ReaderLock lm (_processor_lock);
2666 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2667 (*i)->deactivate ();
2673 Route::set_meter_point (MeterPoint p, void *src)
2675 /* CAN BE CALLED FROM PROCESS CONTEXT */
2677 if (_meter_point == p) {
2681 bool meter_was_visible_to_user = _meter->display_to_user ();
2684 Glib::RWLock::WriterLock lm (_processor_lock);
2686 if (p != MeterCustom) {
2687 // Move meter in the processors list to reflect the new position
2688 ProcessorList::iterator loc = find (_processors.begin(), _processors.end(), _meter);
2689 _processors.erase(loc);
2692 loc = _processors.begin();
2695 loc = find (_processors.begin(), _processors.end(), _amp);
2697 case MeterPostFader:
2698 loc = _processors.end();
2706 if (loc == _processors.begin()) {
2707 m_in = _input->n_ports();
2709 ProcessorList::iterator before = loc;
2711 m_in = (*before)->output_streams ();
2714 _meter->reflect_inputs (m_in);
2716 _processors.insert (loc, _meter);
2718 /* we do not need to reconfigure the processors, because the meter
2719 (a) is always ready to handle processor_max_streams
2720 (b) is always an N-in/N-out processor, and thus moving
2721 it doesn't require any changes to the other processors.
2724 _meter->set_display_to_user (false);
2728 // just make it visible and let the user move it
2730 _meter->set_display_to_user (true);
2735 meter_change (src); /* EMIT SIGNAL */
2737 bool const meter_visibly_changed = (_meter->display_to_user() != meter_was_visible_to_user);
2739 processors_changed (RouteProcessorChange (RouteProcessorChange::MeterPointChange, meter_visibly_changed)); /* EMIT SIGNAL */
2743 Route::put_control_outs_at (Placement p)
2745 if (!_control_outs) {
2750 Glib::RWLock::WriterLock lm (_processor_lock);
2751 ProcessorList as_it_was (_processors);
2752 // Move meter in the processors list
2753 ProcessorList::iterator loc = find(_processors.begin(), _processors.end(), _control_outs);
2754 _processors.erase(loc);
2758 loc = find(_processors.begin(), _processors.end(), _amp);
2759 if (loc != _processors.begin()) {
2764 loc = find(_processors.begin(), _processors.end(), _amp);
2765 assert (loc != _processors.end());
2770 _processors.insert(loc, _control_outs);
2772 if (configure_processors_unlocked (0)) {
2773 _processors = as_it_was;
2774 configure_processors_unlocked (0); // it worked before we tried to add it ...
2779 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
2780 _session.set_dirty ();
2784 Route::update_total_latency ()
2786 nframes_t old = _output->effective_latency();
2787 nframes_t own_latency = _output->user_latency();
2789 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2790 if ((*i)->active ()) {
2791 own_latency += (*i)->signal_latency ();
2795 DEBUG_TRACE (DEBUG::Latency, string_compose ("%1: internal redirect latency = %2\n", _name, own_latency));
2797 _output->set_port_latency (own_latency);
2799 if (_output->user_latency() == 0) {
2801 /* this (virtual) function is used for pure Routes,
2802 not derived classes like AudioTrack. this means
2803 that the data processed here comes from an input
2804 port, not prerecorded material, and therefore we
2805 have to take into account any input latency.
2808 own_latency += _input->signal_latency ();
2811 if (old != own_latency) {
2812 _output->set_latency_delay (own_latency);
2813 signal_latency_changed (); /* EMIT SIGNAL */
2816 DEBUG_TRACE (DEBUG::Latency, string_compose ("%1: input latency = %2 total = %3\n", _name, _input->signal_latency(), own_latency));
2818 return _output->effective_latency ();
2822 Route::set_user_latency (nframes_t nframes)
2824 _output->set_user_latency (nframes);
2825 _session.update_latency_compensation (false, false);
2829 Route::set_latency_delay (nframes_t longest_session_latency)
2831 nframes_t old = _initial_delay;
2833 if (_output->effective_latency() < longest_session_latency) {
2834 _initial_delay = longest_session_latency - _output->effective_latency();
2839 if (_initial_delay != old) {
2840 initial_delay_changed (); /* EMIT SIGNAL */
2843 if (_session.transport_stopped()) {
2844 _roll_delay = _initial_delay;
2849 Route::automation_snapshot (nframes_t now, bool force)
2851 panner()->automation_snapshot (now, force);
2853 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2854 (*i)->automation_snapshot (now, force);
2858 Route::SoloControllable::SoloControllable (std::string name, Route& r)
2859 : AutomationControl (r.session(), Evoral::Parameter (SoloAutomation),
2860 boost::shared_ptr<AutomationList>(), name)
2863 boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloAutomation)));
2868 Route::SoloControllable::set_value (float val)
2870 bool bval = ((val >= 0.5f) ? true: false);
2872 this is how it should be done
2874 boost::shared_ptr<RouteList> rl (new RouteList);
2875 rl->push_back (route);
2877 if (Config->get_solo_control_is_listen_control()) {
2878 _session.set_listen (rl, bval);
2880 _session.set_solo (rl, bval);
2883 route.set_solo (bval, this);
2888 Route::SoloControllable::get_value (void) const
2890 if (Config->get_solo_control_is_listen_control()) {
2891 return route.listening() ? 1.0f : 0.0f;
2893 return route.self_soloed() ? 1.0f : 0.0f;
2897 Route::MuteControllable::MuteControllable (std::string name, Route& r)
2898 : AutomationControl (r.session(), Evoral::Parameter (MuteAutomation),
2899 boost::shared_ptr<AutomationList>(), name)
2902 boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(MuteAutomation)));
2907 Route::MuteControllable::set_value (float val)
2909 bool bval = ((val >= 0.5f) ? true: false);
2911 this is how it should be done
2913 boost::shared_ptr<RouteList> rl (new RouteList);
2914 rl->push_back (route);
2915 _session.set_mute (rl, bval);
2917 route.set_mute (bval, this);
2922 Route::MuteControllable::get_value (void) const
2924 return route.muted() ? 1.0f : 0.0f;
2928 Route::set_block_size (nframes_t nframes)
2930 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2931 (*i)->set_block_size (nframes);
2934 _session.ensure_buffers (n_process_buffers ());
2938 Route::protect_automation ()
2940 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i)
2941 (*i)->protect_automation();
2945 Route::set_pending_declick (int declick)
2948 /* this call is not allowed to turn off a pending declick unless "force" is true */
2950 _pending_declick = declick;
2952 // cerr << _name << ": after setting to " << declick << " pending declick = " << _pending_declick << endl;
2954 _pending_declick = 0;
2959 /** Shift automation forwards from a particular place, thereby inserting time.
2960 * Adds undo commands for any shifts that are performed.
2962 * @param pos Position to start shifting from.
2963 * @param frames Amount to shift forwards by.
2967 Route::shift (nframes64_t /*pos*/, nframes64_t /*frames*/)
2969 #ifdef THIS_NEEDS_FIXING_FOR_V3
2971 /* gain automation */
2972 XMLNode &before = _gain_control->get_state ();
2973 _gain_control->shift (pos, frames);
2974 XMLNode &after = _gain_control->get_state ();
2975 _session.add_command (new MementoCommand<AutomationList> (_gain_automation_curve, &before, &after));
2977 /* pan automation */
2978 for (std::vector<StreamPanner*>::iterator i = _panner->begin (); i != _panner->end (); ++i) {
2979 Curve & c = (*i)->automation ();
2980 XMLNode &before = c.get_state ();
2981 c.shift (pos, frames);
2982 XMLNode &after = c.get_state ();
2983 _session.add_command (new MementoCommand<AutomationList> (c, &before, &after));
2986 /* redirect automation */
2988 Glib::RWLock::ReaderLock lm (redirect_lock);
2989 for (RedirectList::iterator i = _redirects.begin (); i != _redirects.end (); ++i) {
2992 (*i)->what_has_automation (a);
2994 for (set<uint32_t>::const_iterator j = a.begin (); j != a.end (); ++j) {
2995 AutomationList & al = (*i)->automation_list (*j);
2996 XMLNode &before = al.get_state ();
2997 al.shift (pos, frames);
2998 XMLNode &after = al.get_state ();
2999 _session.add_command (new MementoCommand<AutomationList> (al, &before, &after));
3009 Route::save_as_template (const string& path, const string& name)
3011 XMLNode& node (state (false));
3014 IO::set_name_in_state (*node.children().front(), name);
3016 tree.set_root (&node);
3017 return tree.write (path.c_str());
3022 Route::set_name (const string& str)
3028 name = Route::ensure_track_or_route_name (str, _session);
3029 SessionObject::set_name (name);
3031 ret = (_input->set_name(name) && _output->set_name(name));
3035 Glib::RWLock::ReaderLock lm (_processor_lock);
3037 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
3039 /* rename all I/O processors that have inputs or outputs */
3041 boost::shared_ptr<IOProcessor> iop = boost::dynamic_pointer_cast<IOProcessor> (*i);
3043 if (iop && (iop->output() || iop->input())) {
3044 if (!iop->set_name (name)) {
3055 boost::shared_ptr<Send>
3056 Route::internal_send_for (boost::shared_ptr<const Route> target) const
3058 Glib::RWLock::ReaderLock lm (_processor_lock);
3060 for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
3061 boost::shared_ptr<InternalSend> send;
3063 if ((send = boost::dynamic_pointer_cast<InternalSend>(*i)) != 0) {
3064 if (send->target_route() == target) {
3070 return boost::shared_ptr<Send>();
3074 Route::set_phase_invert (bool yn)
3076 if (_phase_invert != yn) {
3077 _phase_invert = 0xffff; // XXX all channels
3078 phase_invert_changed (); /* EMIT SIGNAL */
3083 Route::phase_invert () const
3085 return _phase_invert != 0;
3089 Route::set_denormal_protection (bool yn)
3091 if (_denormal_protection != yn) {
3092 _denormal_protection = yn;
3093 denormal_protection_changed (); /* EMIT SIGNAL */
3098 Route::denormal_protection () const
3100 return _denormal_protection;
3104 Route::set_active (bool yn)
3106 if (_active != yn) {
3108 _input->set_active (yn);
3109 _output->set_active (yn);
3110 active_changed (); // EMIT SIGNAL
3117 Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
3123 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
3125 boost::shared_ptr<Send> s;
3126 boost::shared_ptr<Return> r;
3128 if ((s = boost::dynamic_pointer_cast<Send> (*i)) != 0) {
3129 s->meter()->meter();
3130 } else if ((r = boost::dynamic_pointer_cast<Return> (*i)) != 0) {
3131 r->meter()->meter ();
3136 boost::shared_ptr<Panner>
3137 Route::panner() const
3139 return _main_outs->panner();
3142 boost::shared_ptr<AutomationControl>
3143 Route::gain_control() const
3145 return _amp->gain_control();
3148 boost::shared_ptr<AutomationControl>
3149 Route::get_control (const Evoral::Parameter& param)
3151 /* either we own the control or .... */
3153 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(control (param));
3157 /* maybe one of our processors does or ... */
3159 Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
3160 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
3161 if ((c = boost::dynamic_pointer_cast<AutomationControl>((*i)->control (param))) != 0) {
3169 /* nobody does so we'll make a new one */
3171 c = boost::dynamic_pointer_cast<AutomationControl>(control_factory(param));
3178 boost::shared_ptr<Processor>
3179 Route::nth_plugin (uint32_t n)
3181 Glib::RWLock::ReaderLock lm (_processor_lock);
3182 ProcessorList::iterator i;
3184 for (i = _processors.begin(); i != _processors.end(); ++i) {
3185 if (boost::dynamic_pointer_cast<PluginInsert> (*i)) {
3192 return boost::shared_ptr<Processor> ();
3195 boost::shared_ptr<Processor>
3196 Route::nth_send (uint32_t n)
3198 Glib::RWLock::ReaderLock lm (_processor_lock);
3199 ProcessorList::iterator i;
3201 for (i = _processors.begin(); i != _processors.end(); ++i) {
3202 cerr << "check " << (*i)->name() << endl;
3203 if (boost::dynamic_pointer_cast<Send> (*i)) {
3208 cerr << "\tnot a send\n";
3212 return boost::shared_ptr<Processor> ();