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->is_active() && _route_group->is_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->is_active() && _route_group->is_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->is_active() && _route_group->is_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->is_active() && _route_group->is_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;
1372 if (!_session.engine().connected()) {
1376 processor_max_streams.reset();
1379 Glib::RWLock::WriterLock lm (_processor_lock);
1380 ProcessorList::iterator i;
1381 boost::shared_ptr<Processor> processor;
1383 ProcessorList as_we_were = _processors;
1385 for (i = _processors.begin(); i != _processors.end(); ) {
1389 /* these can never be removed */
1391 if (processor == _amp || processor == _meter || processor == _main_outs) {
1396 /* see if its in the list of processors to delete */
1398 if (find (to_be_deleted.begin(), to_be_deleted.end(), processor) == to_be_deleted.end()) {
1403 /* stop IOProcessors that send to JACK ports
1404 from causing noise as a result of no longer being
1408 boost::shared_ptr<IOProcessor> iop;
1410 if ((iop = boost::dynamic_pointer_cast<IOProcessor> (processor)) != 0) {
1414 deleted.push_back (processor);
1415 i = _processors.erase (i);
1418 if (deleted.empty()) {
1419 /* none of those in the requested list were found */
1423 _output->set_user_latency (0);
1425 if (configure_processors_unlocked (err)) {
1426 /* get back to where we where */
1427 _processors = as_we_were;
1428 /* we know this will work, because it worked before :) */
1429 configure_processors_unlocked (0);
1433 _have_internal_generator = false;
1435 for (i = _processors.begin(); i != _processors.end(); ++i) {
1436 boost::shared_ptr<PluginInsert> pi;
1438 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
1439 if (pi->is_generator()) {
1440 _have_internal_generator = true;
1447 /* now try to do what we need to so that those that were removed will be deleted */
1449 for (ProcessorList::iterator i = deleted.begin(); i != deleted.end(); ++i) {
1450 (*i)->drop_references ();
1453 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1460 Route::configure_processors (ProcessorStreams* err)
1462 if (!_in_configure_processors) {
1463 Glib::RWLock::WriterLock lm (_processor_lock);
1464 return configure_processors_unlocked (err);
1469 /** Configure the input/output configuration of each processor in the processors list.
1470 * Return 0 on success, otherwise configuration is impossible.
1473 Route::configure_processors_unlocked (ProcessorStreams* err)
1475 if (_in_configure_processors) {
1479 _in_configure_processors = true;
1481 // Check each processor in order to see if we can configure as requested
1482 ChanCount in = _input->n_ports ();
1484 list< pair<ChanCount,ChanCount> > configuration;
1487 DEBUG_TRACE (DEBUG::Processors, string_compose ("%1: configure processors\n", _name));
1489 DEBUG_TRACE (DEBUG::Processors, "{\n");
1490 for (list<boost::shared_ptr<Processor> >::const_iterator p = _processors.begin(); p != _processors.end(); ++p) {
1491 DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1 ID = %2\n", (*p)->name(), (*p)->id()));
1493 DEBUG_TRACE (DEBUG::Processors, "}\n");
1496 for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++index) {
1498 if ((*p)->can_support_io_configuration(in, out)) {
1499 DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1in = %2 out = %3\n",(*p)->name(), in, out));
1500 configuration.push_back(make_pair(in, out));
1507 _in_configure_processors = false;
1512 // We can, so configure everything
1513 list< pair<ChanCount,ChanCount> >::iterator c = configuration.begin();
1514 for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++c) {
1515 (*p)->configure_io(c->first, c->second);
1516 processor_max_streams = ChanCount::max(processor_max_streams, c->first);
1517 processor_max_streams = ChanCount::max(processor_max_streams, c->second);
1522 _meter->reset_max_channels (processor_max_streams);
1525 /* make sure we have sufficient scratch buffers to cope with the new processor
1527 _session.ensure_buffers (n_process_buffers ());
1529 _in_configure_processors = false;
1534 Route::all_processors_flip ()
1536 Glib::RWLock::ReaderLock lm (_processor_lock);
1538 if (_processors.empty()) {
1542 bool first_is_on = _processors.front()->active();
1544 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1546 (*i)->deactivate ();
1552 _session.set_dirty ();
1555 /** Set all processors with a given placement to a given active state.
1556 * @param p Placement of processors to change.
1557 * @param state New active state for those processors.
1560 Route::all_processors_active (Placement p, bool state)
1562 Glib::RWLock::ReaderLock lm (_processor_lock);
1564 if (_processors.empty()) {
1567 ProcessorList::iterator start, end;
1568 placement_range(p, start, end);
1570 bool before_amp = true;
1571 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1576 if (p == PreFader && before_amp) {
1580 (*i)->deactivate ();
1585 _session.set_dirty ();
1589 Route::processor_is_prefader (boost::shared_ptr<Processor> p)
1591 bool pre_fader = true;
1592 Glib::RWLock::ReaderLock lm (_processor_lock);
1594 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1596 /* semantic note: if p == amp, we want to return true, so test
1597 for equality before checking if this is the amp
1614 Route::reorder_processors (const ProcessorList& new_order, ProcessorStreams* err)
1616 /* "new_order" is an ordered list of processors to be positioned according to "placement".
1617 NOTE: all processors in "new_order" MUST be marked as display_to_user(). There maybe additional
1618 processors in the current actual processor list that are hidden. Any visible processors
1619 in the current list but not in "new_order" will be assumed to be deleted.
1623 Glib::RWLock::WriterLock lm (_processor_lock);
1624 ChanCount old_pms = processor_max_streams;
1625 ProcessorList::iterator oiter;
1626 ProcessorList::const_iterator niter;
1627 ProcessorList as_it_was_before = _processors;
1628 ProcessorList as_it_will_be;
1630 oiter = _processors.begin();
1631 niter = new_order.begin();
1633 while (niter != new_order.end()) {
1635 /* if the next processor in the old list is invisible (i.e. should not be in the new order)
1636 then append it to the temp list.
1638 Otherwise, see if the next processor in the old list is in the new list. if not,
1639 its been deleted. If its there, append it to the temp list.
1642 if (oiter == _processors.end()) {
1644 /* no more elements in the old list, so just stick the rest of
1645 the new order onto the temp list.
1648 as_it_will_be.insert (as_it_will_be.end(), niter, new_order.end());
1649 while (niter != new_order.end()) {
1656 if (!(*oiter)->display_to_user()) {
1658 as_it_will_be.push_back (*oiter);
1662 /* visible processor: check that its in the new order */
1664 if (find (new_order.begin(), new_order.end(), (*oiter)) == new_order.end()) {
1665 /* deleted: do nothing, shared_ptr<> will clean up */
1667 /* ignore this one, and add the next item from the new order instead */
1668 as_it_will_be.push_back (*niter);
1673 /* now remove from old order - its taken care of no matter what */
1674 oiter = _processors.erase (oiter);
1679 _processors.insert (oiter, as_it_will_be.begin(), as_it_will_be.end());
1681 if (configure_processors_unlocked (err)) {
1682 _processors = as_it_was_before;
1683 processor_max_streams = old_pms;
1688 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1700 Route::get_template()
1702 return state(false);
1706 Route::state(bool full_state)
1708 XMLNode *node = new XMLNode("Route");
1709 ProcessorList::iterator i;
1712 id().print (buf, sizeof (buf));
1713 node->add_property("id", buf);
1714 node->add_property ("name", _name);
1715 node->add_property("default-type", _default_type.to_string());
1718 node->add_property("flags", enum_2_string (_flags));
1721 node->add_property("active", _active?"yes":"no");
1722 node->add_property("phase-invert", _phase_invert?"yes":"no");
1723 node->add_property("denormal-protection", _denormal_protection?"yes":"no");
1724 node->add_property("meter-point", enum_2_string (_meter_point));
1727 node->add_property("route-group", _route_group->name());
1730 string order_string;
1731 OrderKeys::iterator x = order_keys.begin();
1733 while (x != order_keys.end()) {
1734 order_string += string ((*x).first);
1735 order_string += '=';
1736 snprintf (buf, sizeof(buf), "%ld", (*x).second);
1737 order_string += buf;
1741 if (x == order_keys.end()) {
1745 order_string += ':';
1747 node->add_property ("order-keys", order_string);
1748 node->add_property ("self-solo", (_self_solo ? "yes" : "no"));
1749 snprintf (buf, sizeof (buf), "%d", _soloed_by_others);
1750 node->add_property ("soloed-by-others", buf);
1752 node->add_child_nocopy (_input->state (full_state));
1753 node->add_child_nocopy (_output->state (full_state));
1754 node->add_child_nocopy (_solo_control->get_state ());
1755 node->add_child_nocopy (_mute_master->get_state ());
1757 XMLNode* remote_control_node = new XMLNode (X_("RemoteControl"));
1758 snprintf (buf, sizeof (buf), "%d", _remote_control_id);
1759 remote_control_node->add_property (X_("id"), buf);
1760 node->add_child_nocopy (*remote_control_node);
1762 if (_comment.length()) {
1763 XMLNode *cmt = node->add_child ("Comment");
1764 cmt->add_content (_comment);
1767 for (i = _processors.begin(); i != _processors.end(); ++i) {
1768 node->add_child_nocopy((*i)->state (full_state));
1772 node->add_child_copy (*_extra_xml);
1779 Route::set_state (const XMLNode& node, int version)
1781 return _set_state (node, version, true);
1785 Route::_set_state (const XMLNode& node, int version, bool /*call_base*/)
1787 if (version < 3000) {
1788 return _set_state_2X (node, version);
1792 XMLNodeConstIterator niter;
1794 XMLPropertyList plist;
1795 const XMLProperty *prop;
1797 if (node.name() != "Route"){
1798 error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
1802 if ((prop = node.property (X_("name"))) != 0) {
1803 Route::set_name (prop->value());
1806 if ((prop = node.property ("id")) != 0) {
1807 _id = prop->value ();
1810 if ((prop = node.property (X_("flags"))) != 0) {
1811 _flags = Flag (string_2_enum (prop->value(), _flags));
1816 /* add all processors (except amp, which is always present) */
1818 nlist = node.children();
1819 XMLNode processor_state (X_("processor_state"));
1821 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1825 if (child->name() == IO::state_node_name) {
1826 if ((prop = child->property (X_("direction"))) == 0) {
1830 if (prop->value() == "Input") {
1831 _input->set_state (*child, version);
1832 } else if (prop->value() == "Output") {
1833 _output->set_state (*child, version);
1837 if (child->name() == X_("Processor")) {
1838 processor_state.add_child_copy (*child);
1842 set_processor_state (processor_state);
1844 if ((prop = node.property ("self-solo")) != 0) {
1845 set_self_solo (string_is_affirmative (prop->value()));
1848 if ((prop = node.property ("soloed-by-others")) != 0) {
1849 _soloed_by_others = 0; // needed for mod_solo_by_others () to work
1850 mod_solo_by_others (atoi (prop->value()));
1853 if ((prop = node.property ("solo-isolated")) != 0) {
1854 set_solo_isolated (string_is_affirmative (prop->value()), this);
1857 if ((prop = node.property (X_("phase-invert"))) != 0) {
1858 set_phase_invert (string_is_affirmative (prop->value()));
1861 if ((prop = node.property (X_("denormal-protection"))) != 0) {
1862 set_denormal_protection (string_is_affirmative (prop->value()));
1865 if ((prop = node.property (X_("active"))) != 0) {
1866 bool yn = string_is_affirmative (prop->value());
1867 _active = !yn; // force switch
1871 if ((prop = node.property (X_("meter-point"))) != 0) {
1872 _meter_point = MeterPoint (string_2_enum (prop->value (), _meter_point));
1874 _meter->set_display_to_user (_meter_point == MeterCustom);
1878 if ((prop = node.property (X_("order-keys"))) != 0) {
1882 string::size_type colon, equal;
1883 string remaining = prop->value();
1885 while (remaining.length()) {
1887 if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
1888 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1891 if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) {
1892 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1895 set_order_key (remaining.substr (0, equal), n);
1899 colon = remaining.find_first_of (':');
1901 if (colon != string::npos) {
1902 remaining = remaining.substr (colon+1);
1909 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1912 if (child->name() == X_("Comment")) {
1914 /* XXX this is a terrible API design in libxml++ */
1916 XMLNode *cmt = *(child->children().begin());
1917 _comment = cmt->content();
1919 } else if (child->name() == X_("Extra")) {
1921 _extra_xml = new XMLNode (*child);
1923 } else if (child->name() == X_("Controllable") && (prop = child->property("name")) != 0) {
1925 if (prop->value() == "solo") {
1926 _solo_control->set_state (*child, version);
1927 _session.add_controllable (_solo_control);
1930 } else if (child->name() == X_("RemoteControl")) {
1931 if ((prop = child->property (X_("id"))) != 0) {
1933 sscanf (prop->value().c_str(), "%d", &x);
1934 set_remote_control_id (x);
1937 } else if (child->name() == X_("MuteMaster")) {
1938 _mute_master->set_state (*child, version);
1946 Route::_set_state_2X (const XMLNode& node, int version)
1949 XMLNodeConstIterator niter;
1951 XMLPropertyList plist;
1952 const XMLProperty *prop;
1954 /* 2X things which still remain to be handled:
1957 * mute-affects-pre-fader
1958 * mute-affects-post-fader
1959 * mute-affects-control-outs
1960 * mute-affects-main-outs
1965 if (node.name() != "Route") {
1966 error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
1970 if ((prop = node.property (X_("flags"))) != 0) {
1971 _flags = Flag (string_2_enum (prop->value(), _flags));
1976 /* add standard processors */
1978 _meter.reset (new PeakMeter (_session));
1979 add_processor (_meter, PreFader);
1981 if (_flags & ControlOut) {
1982 /* where we listen to tracks */
1983 _intreturn.reset (new InternalReturn (_session));
1984 add_processor (_intreturn, PreFader);
1987 _main_outs.reset (new Delivery (_session, _output, _mute_master, _name, Delivery::Main));
1988 add_processor (_main_outs, PostFader);
1992 nlist = node.children ();
1993 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1997 if (child->name() == IO::state_node_name) {
1999 /* there is a note in IO::set_state_2X() about why we have to call
2003 _input->set_state_2X (*child, version, true);
2004 _output->set_state_2X (*child, version, false);
2006 if ((prop = child->property (X_("name"))) != 0) {
2007 set_name (prop->value ());
2010 if ((prop = child->property (X_("id"))) != 0) {
2011 _id = prop->value ();
2014 if ((prop = child->property (X_("active"))) != 0) {
2015 bool yn = string_is_affirmative (prop->value());
2016 _active = !yn; // force switch
2024 if ((prop = node.property (X_("phase-invert"))) != 0) {
2025 set_phase_invert (string_is_affirmative (prop->value()));
2028 if ((prop = node.property (X_("denormal-protection"))) != 0) {
2029 set_denormal_protection (string_is_affirmative (prop->value()));
2032 if ((prop = node.property (X_("soloed"))) != 0) {
2033 bool yn = string_is_affirmative (prop->value());
2035 /* XXX force reset of solo status */
2037 set_solo (yn, this);
2040 if ((prop = node.property (X_("meter-point"))) != 0) {
2041 _meter_point = MeterPoint (string_2_enum (prop->value (), _meter_point));
2044 /* do not carry over edit/mix groups from 2.X because (a) its hard (b) they
2045 don't mean the same thing.
2048 if ((prop = node.property (X_("order-keys"))) != 0) {
2052 string::size_type colon, equal;
2053 string remaining = prop->value();
2055 while (remaining.length()) {
2057 if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
2058 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
2061 if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) {
2062 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
2065 set_order_key (remaining.substr (0, equal), n);
2069 colon = remaining.find_first_of (':');
2071 if (colon != string::npos) {
2072 remaining = remaining.substr (colon+1);
2079 XMLNodeList redirect_nodes;
2081 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
2085 if (child->name() == X_("Send") || child->name() == X_("Insert")) {
2086 redirect_nodes.push_back(child);
2091 set_processor_state_2X (redirect_nodes, version);
2093 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
2096 if (child->name() == X_("Comment")) {
2098 /* XXX this is a terrible API design in libxml++ */
2100 XMLNode *cmt = *(child->children().begin());
2101 _comment = cmt->content();
2103 } else if (child->name() == X_("Extra")) {
2105 _extra_xml = new XMLNode (*child);
2107 } else if (child->name() == X_("Controllable") && (prop = child->property("name")) != 0) {
2109 if (prop->value() == "solo") {
2110 _solo_control->set_state (*child, version);
2111 _session.add_controllable (_solo_control);
2114 } else if (child->name() == X_("RemoteControl")) {
2115 if ((prop = child->property (X_("id"))) != 0) {
2117 sscanf (prop->value().c_str(), "%d", &x);
2118 set_remote_control_id (x);
2128 Route::get_processor_state ()
2130 XMLNode* root = new XMLNode (X_("redirects"));
2131 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2132 root->add_child_nocopy ((*i)->state (true));
2139 Route::set_processor_state_2X (XMLNodeList const & nList, int version)
2141 /* We don't bother removing existing processors not in nList, as this
2142 method will only be called when creating a Route from scratch, not
2143 for undo purposes. Just put processors in at the appropriate place
2147 for (XMLNodeConstIterator i = nList.begin(); i != nList.end(); ++i) {
2148 add_processor_from_xml_2X (**i, version, _processors.begin ());
2153 Route::set_processor_state (const XMLNode& node)
2155 const XMLNodeList &nlist = node.children();
2156 XMLNodeConstIterator niter;
2157 ProcessorList::iterator i, o;
2159 // Iterate through existing processors, remove those which are not in the state list
2161 for (i = _processors.begin(); i != _processors.end(); ) {
2163 /* leave amp alone, always */
2170 ProcessorList::iterator tmp = i;
2173 bool processorInStateList = false;
2175 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2177 XMLProperty* id_prop = (*niter)->property(X_("id"));
2179 if (id_prop && (*i)->id() == id_prop->value()) {
2180 processorInStateList = true;
2185 if (!processorInStateList) {
2186 remove_processor (*i);
2192 // Iterate through state list and make sure all processors are on the track and in the correct order,
2193 // set the state of existing processors according to the new state on the same go
2195 i = _processors.begin();
2197 for (niter = nlist.begin(); niter != nlist.end(); ++niter, ++i) {
2199 XMLProperty* prop = (*niter)->property ("type");
2203 // Check whether the next processor in the list is the right one,
2204 // except for "amp" which is always there and may not have the
2205 // old ID since it is always created anew in every Route
2207 if (prop->value() != "amp") {
2208 while (o != _processors.end()) {
2209 XMLProperty* id_prop = (*niter)->property(X_("id"));
2210 if (id_prop && (*o)->id() == id_prop->value()) {
2218 // If the processor (*niter) is not on the route,
2219 // create it and move it to the correct location
2221 if (o == _processors.end()) {
2223 if (add_processor_from_xml (**niter, i)) {
2224 --i; // move iterator to the newly inserted processor
2226 cerr << "Error restoring route: unable to restore processor" << endl;
2231 // Otherwise, the processor already exists; just
2232 // ensure it is at the location provided in the XML state
2235 boost::shared_ptr<Processor> tmp = (*o);
2236 _processors.erase (o); // remove the old copy
2237 _processors.insert (i, tmp); // insert the processor at the correct location
2238 --i; // move iterator to the correct processor
2241 // and make it (just) so
2243 (*i)->set_state (**niter, Stateful::current_state_version);
2247 /* note: there is no configure_processors() call because we figure that
2248 the XML state represents a working signal route.
2251 processors_changed (RouteProcessorChange ());
2255 Route::curve_reallocate ()
2257 // _gain_automation_curve.finish_resize ();
2258 // _pan_automation_curve.finish_resize ();
2262 Route::silence (nframes_t nframes)
2266 _output->silence (nframes);
2269 Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
2272 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2273 boost::shared_ptr<PluginInsert> pi;
2275 if (!_active && (pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
2276 // skip plugins, they don't need anything when we're not active
2280 (*i)->silence (nframes);
2283 if (nframes == _session.get_block_size()) {
2293 Route::add_internal_return ()
2296 _intreturn.reset (new InternalReturn (_session));
2297 add_processor (_intreturn, PreFader);
2302 Route::get_return_buffer () const
2304 Glib::RWLock::ReaderLock rm (_processor_lock);
2306 for (ProcessorList::const_iterator x = _processors.begin(); x != _processors.end(); ++x) {
2307 boost::shared_ptr<InternalReturn> d = boost::dynamic_pointer_cast<InternalReturn>(*x);
2310 BufferSet* bs = d->get_buffers ();
2319 Route::release_return_buffer () const
2321 Glib::RWLock::ReaderLock rm (_processor_lock);
2323 for (ProcessorList::const_iterator x = _processors.begin(); x != _processors.end(); ++x) {
2324 boost::shared_ptr<InternalReturn> d = boost::dynamic_pointer_cast<InternalReturn>(*x);
2327 return d->release_buffers ();
2333 Route::listen_via (boost::shared_ptr<Route> route, Placement placement, bool /*active*/, bool aux)
2335 vector<string> ports;
2336 vector<string>::const_iterator i;
2339 Glib::RWLock::ReaderLock rm (_processor_lock);
2341 for (ProcessorList::iterator x = _processors.begin(); x != _processors.end(); ++x) {
2343 boost::shared_ptr<InternalSend> d = boost::dynamic_pointer_cast<InternalSend>(*x);
2345 if (d && d->target_route() == route) {
2347 /* if the target is the control outs, then make sure
2348 we take note of which i-send is doing that.
2351 if (route == _session.control_out()) {
2352 _control_outs = boost::dynamic_pointer_cast<Delivery>(d);
2355 /* already listening via the specified IO: do nothing */
2362 boost::shared_ptr<InternalSend> listener;
2365 listener.reset (new InternalSend (_session, _mute_master, route, (aux ? Delivery::Aux : Delivery::Listen)));
2367 } catch (failed_constructor& err) {
2371 if (route == _session.control_out()) {
2372 _control_outs = listener;
2375 add_processor (listener, placement);
2381 Route::drop_listen (boost::shared_ptr<Route> route)
2383 ProcessorStreams err;
2384 ProcessorList::iterator tmp;
2386 Glib::RWLock::ReaderLock rl(_processor_lock);
2390 for (ProcessorList::iterator x = _processors.begin(); x != _processors.end(); ) {
2392 boost::shared_ptr<InternalSend> d = boost::dynamic_pointer_cast<InternalSend>(*x);
2394 if (d && d->target_route() == route) {
2396 remove_processor (*x, &err);
2399 /* list could have been demolished while we dropped the lock
2409 if (route == _session.control_out()) {
2410 _control_outs.reset ();
2415 Route::set_comment (string cmt, void *src)
2418 comment_changed (src);
2419 _session.set_dirty ();
2423 Route::feeds (boost::shared_ptr<Route> other, bool* only_send)
2425 DEBUG_TRACE (DEBUG::Graph, string_compose ("Feeds? %1\n", _name));
2427 if (_output->connected_to (other->input())) {
2428 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tdirect FEEDS %2\n", other->name()));
2437 for (ProcessorList::iterator r = _processors.begin(); r != _processors.end(); ++r) {
2439 boost::shared_ptr<IOProcessor> iop;
2441 if ((iop = boost::dynamic_pointer_cast<IOProcessor>(*r)) != 0) {
2442 if (iop->feeds (other)) {
2443 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tIOP %1 does feed %2\n", iop->name(), other->name()));
2449 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tIOP %1 does NOT feed %2\n", iop->name(), other->name()));
2452 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tPROC %1 is not an IOP\n", (*r)->name()));
2457 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tdoes NOT feed %1\n", other->name()));
2462 Route::handle_transport_stopped (bool /*abort_ignored*/, bool did_locate, bool can_flush_processors)
2464 nframes_t now = _session.transport_frame();
2467 Glib::RWLock::ReaderLock lm (_processor_lock);
2470 automation_snapshot (now, true);
2473 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2475 if (Config->get_plugins_stop_with_transport() && can_flush_processors) {
2476 (*i)->deactivate ();
2480 (*i)->transport_stopped (now);
2484 _roll_delay = _initial_delay;
2488 Route::input_change_handler (IOChange change, void * /*src*/)
2490 if ((change & ConfigurationChanged)) {
2491 configure_processors (0);
2496 Route::output_change_handler (IOChange change, void * /*src*/)
2498 if ((change & ConfigurationChanged)) {
2500 /* XXX resize all listeners to match _main_outs? */
2502 // configure_processors (0);
2507 Route::pans_required () const
2509 if (n_outputs().n_audio() < 2) {
2513 return max (n_inputs ().n_audio(), processor_max_streams.n_audio());
2517 Route::no_roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame,
2518 bool session_state_changing, bool /*can_record*/, bool /*rec_monitors_input*/)
2520 if (n_outputs().n_total() == 0) {
2524 if (!_active || n_inputs() == ChanCount::ZERO) {
2528 if (session_state_changing) {
2529 if (_session.transport_speed() != 0.0f) {
2530 /* we're rolling but some state is changing (e.g. our diskstream contents)
2531 so we cannot use them. Be silent till this is over.
2533 XXX note the absurdity of ::no_roll() being called when we ARE rolling!
2538 /* we're really not rolling, so we're either delivery silence or actually
2539 monitoring, both of which are safe to do while session_state_changing is true.
2543 _amp->apply_gain_automation (false);
2544 passthru (start_frame, end_frame, nframes, 0);
2550 Route::check_initial_delay (nframes_t nframes, nframes_t& transport_frame)
2552 if (_roll_delay > nframes) {
2554 _roll_delay -= nframes;
2556 /* transport frame is not legal for caller to use */
2559 } else if (_roll_delay > 0) {
2561 nframes -= _roll_delay;
2562 silence (_roll_delay);
2563 /* we've written _roll_delay of samples into the
2564 output ports, so make a note of that for
2567 _main_outs->increment_output_offset (_roll_delay);
2568 transport_frame += _roll_delay;
2577 Route::roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame, int declick,
2578 bool /*can_record*/, bool /*rec_monitors_input*/)
2581 // automation snapshot can also be called from the non-rt context
2582 // and it uses the processor list, so we try to acquire the lock here
2583 Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
2586 automation_snapshot (_session.transport_frame(), false);
2590 if (n_outputs().n_total() == 0) {
2594 if (!_active || n_inputs().n_total() == 0) {
2599 nframes_t unused = 0;
2601 if ((nframes = check_initial_delay (nframes, unused)) == 0) {
2607 passthru (start_frame, end_frame, nframes, declick);
2613 Route::silent_roll (nframes_t nframes, sframes_t /*start_frame*/, sframes_t /*end_frame*/,
2614 bool /*can_record*/, bool /*rec_monitors_input*/)
2621 Route::toggle_monitor_input ()
2623 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
2624 i->ensure_monitor_input( ! i->monitoring_input());
2629 Route::has_external_redirects () const
2631 // FIXME: what about sends? - they don't return a signal back to ardour?
2633 boost::shared_ptr<const PortInsert> pi;
2635 for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
2637 if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*i)) != 0) {
2639 for (PortSet::const_iterator port = pi->output()->ports().begin(); port != pi->output()->ports().end(); ++port) {
2641 string port_name = port->name();
2642 string client_name = port_name.substr (0, port_name.find(':'));
2644 /* only say "yes" if the redirect is actually in use */
2646 if (client_name != "ardour" && pi->active()) {
2657 Route::flush_processors ()
2659 /* XXX shouldn't really try to take this lock, since
2660 this is called from the RT audio thread.
2663 Glib::RWLock::ReaderLock lm (_processor_lock);
2665 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2666 (*i)->deactivate ();
2672 Route::set_meter_point (MeterPoint p, void *src)
2674 /* CAN BE CALLED FROM PROCESS CONTEXT */
2676 if (_meter_point == p) {
2680 bool meter_was_visible_to_user = _meter->display_to_user ();
2683 Glib::RWLock::WriterLock lm (_processor_lock);
2685 if (p != MeterCustom) {
2686 // Move meter in the processors list to reflect the new position
2687 ProcessorList::iterator loc = find (_processors.begin(), _processors.end(), _meter);
2688 _processors.erase(loc);
2691 loc = _processors.begin();
2694 loc = find (_processors.begin(), _processors.end(), _amp);
2696 case MeterPostFader:
2697 loc = _processors.end();
2705 if (loc == _processors.begin()) {
2706 m_in = _input->n_ports();
2708 ProcessorList::iterator before = loc;
2710 m_in = (*before)->output_streams ();
2713 _meter->reflect_inputs (m_in);
2715 _processors.insert (loc, _meter);
2717 /* we do not need to reconfigure the processors, because the meter
2718 (a) is always ready to handle processor_max_streams
2719 (b) is always an N-in/N-out processor, and thus moving
2720 it doesn't require any changes to the other processors.
2723 _meter->set_display_to_user (false);
2727 // just make it visible and let the user move it
2729 _meter->set_display_to_user (true);
2734 meter_change (src); /* EMIT SIGNAL */
2736 bool const meter_visibly_changed = (_meter->display_to_user() != meter_was_visible_to_user);
2738 processors_changed (RouteProcessorChange (RouteProcessorChange::MeterPointChange, meter_visibly_changed)); /* EMIT SIGNAL */
2742 Route::put_control_outs_at (Placement p)
2744 if (!_control_outs) {
2749 Glib::RWLock::WriterLock lm (_processor_lock);
2750 ProcessorList as_it_was (_processors);
2751 // Move meter in the processors list
2752 ProcessorList::iterator loc = find(_processors.begin(), _processors.end(), _control_outs);
2753 _processors.erase(loc);
2757 loc = find(_processors.begin(), _processors.end(), _amp);
2758 if (loc != _processors.begin()) {
2763 loc = find(_processors.begin(), _processors.end(), _amp);
2764 assert (loc != _processors.end());
2769 _processors.insert(loc, _control_outs);
2771 if (configure_processors_unlocked (0)) {
2772 _processors = as_it_was;
2773 configure_processors_unlocked (0); // it worked before we tried to add it ...
2778 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
2779 _session.set_dirty ();
2783 Route::update_total_latency ()
2785 nframes_t old = _output->effective_latency();
2786 nframes_t own_latency = _output->user_latency();
2788 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2789 if ((*i)->active ()) {
2790 own_latency += (*i)->signal_latency ();
2794 DEBUG_TRACE (DEBUG::Latency, string_compose ("%1: internal redirect latency = %2\n", _name, own_latency));
2796 _output->set_port_latency (own_latency);
2798 if (_output->user_latency() == 0) {
2800 /* this (virtual) function is used for pure Routes,
2801 not derived classes like AudioTrack. this means
2802 that the data processed here comes from an input
2803 port, not prerecorded material, and therefore we
2804 have to take into account any input latency.
2807 own_latency += _input->signal_latency ();
2810 if (old != own_latency) {
2811 _output->set_latency_delay (own_latency);
2812 signal_latency_changed (); /* EMIT SIGNAL */
2815 DEBUG_TRACE (DEBUG::Latency, string_compose ("%1: input latency = %2 total = %3\n", _name, _input->signal_latency(), own_latency));
2817 return _output->effective_latency ();
2821 Route::set_user_latency (nframes_t nframes)
2823 _output->set_user_latency (nframes);
2824 _session.update_latency_compensation (false, false);
2828 Route::set_latency_delay (nframes_t longest_session_latency)
2830 nframes_t old = _initial_delay;
2832 if (_output->effective_latency() < longest_session_latency) {
2833 _initial_delay = longest_session_latency - _output->effective_latency();
2838 if (_initial_delay != old) {
2839 initial_delay_changed (); /* EMIT SIGNAL */
2842 if (_session.transport_stopped()) {
2843 _roll_delay = _initial_delay;
2848 Route::automation_snapshot (nframes_t now, bool force)
2850 panner()->automation_snapshot (now, force);
2852 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2853 (*i)->automation_snapshot (now, force);
2857 Route::SoloControllable::SoloControllable (std::string name, Route& r)
2858 : AutomationControl (r.session(), Evoral::Parameter (SoloAutomation),
2859 boost::shared_ptr<AutomationList>(), name)
2862 boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloAutomation)));
2867 Route::SoloControllable::set_value (float val)
2869 bool bval = ((val >= 0.5f) ? true: false);
2871 this is how it should be done
2873 boost::shared_ptr<RouteList> rl (new RouteList);
2874 rl->push_back (route);
2876 if (Config->get_solo_control_is_listen_control()) {
2877 _session.set_listen (rl, bval);
2879 _session.set_solo (rl, bval);
2882 route.set_solo (bval, this);
2887 Route::SoloControllable::get_value (void) const
2889 if (Config->get_solo_control_is_listen_control()) {
2890 return route.listening() ? 1.0f : 0.0f;
2892 return route.self_soloed() ? 1.0f : 0.0f;
2896 Route::MuteControllable::MuteControllable (std::string name, Route& r)
2897 : AutomationControl (r.session(), Evoral::Parameter (MuteAutomation),
2898 boost::shared_ptr<AutomationList>(), name)
2901 boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(MuteAutomation)));
2906 Route::MuteControllable::set_value (float val)
2908 bool bval = ((val >= 0.5f) ? true: false);
2910 this is how it should be done
2912 boost::shared_ptr<RouteList> rl (new RouteList);
2913 rl->push_back (route);
2914 _session.set_mute (rl, bval);
2916 route.set_mute (bval, this);
2921 Route::MuteControllable::get_value (void) const
2923 return route.muted() ? 1.0f : 0.0f;
2927 Route::set_block_size (nframes_t nframes)
2929 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2930 (*i)->set_block_size (nframes);
2933 _session.ensure_buffers (n_process_buffers ());
2937 Route::protect_automation ()
2939 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i)
2940 (*i)->protect_automation();
2944 Route::set_pending_declick (int declick)
2947 /* this call is not allowed to turn off a pending declick unless "force" is true */
2949 _pending_declick = declick;
2951 // cerr << _name << ": after setting to " << declick << " pending declick = " << _pending_declick << endl;
2953 _pending_declick = 0;
2958 /** Shift automation forwards from a particular place, thereby inserting time.
2959 * Adds undo commands for any shifts that are performed.
2961 * @param pos Position to start shifting from.
2962 * @param frames Amount to shift forwards by.
2966 Route::shift (nframes64_t /*pos*/, nframes64_t /*frames*/)
2968 #ifdef THIS_NEEDS_FIXING_FOR_V3
2970 /* gain automation */
2971 XMLNode &before = _gain_control->get_state ();
2972 _gain_control->shift (pos, frames);
2973 XMLNode &after = _gain_control->get_state ();
2974 _session.add_command (new MementoCommand<AutomationList> (_gain_automation_curve, &before, &after));
2976 /* pan automation */
2977 for (std::vector<StreamPanner*>::iterator i = _panner->begin (); i != _panner->end (); ++i) {
2978 Curve & c = (*i)->automation ();
2979 XMLNode &before = c.get_state ();
2980 c.shift (pos, frames);
2981 XMLNode &after = c.get_state ();
2982 _session.add_command (new MementoCommand<AutomationList> (c, &before, &after));
2985 /* redirect automation */
2987 Glib::RWLock::ReaderLock lm (redirect_lock);
2988 for (RedirectList::iterator i = _redirects.begin (); i != _redirects.end (); ++i) {
2991 (*i)->what_has_automation (a);
2993 for (set<uint32_t>::const_iterator j = a.begin (); j != a.end (); ++j) {
2994 AutomationList & al = (*i)->automation_list (*j);
2995 XMLNode &before = al.get_state ();
2996 al.shift (pos, frames);
2997 XMLNode &after = al.get_state ();
2998 _session.add_command (new MementoCommand<AutomationList> (al, &before, &after));
3008 Route::save_as_template (const string& path, const string& name)
3010 XMLNode& node (state (false));
3013 IO::set_name_in_state (*node.children().front(), name);
3015 tree.set_root (&node);
3016 return tree.write (path.c_str());
3021 Route::set_name (const string& str)
3027 name = Route::ensure_track_or_route_name (str, _session);
3028 SessionObject::set_name (name);
3030 ret = (_input->set_name(name) && _output->set_name(name));
3034 Glib::RWLock::ReaderLock lm (_processor_lock);
3036 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
3038 /* rename all I/O processors that have inputs or outputs */
3040 boost::shared_ptr<IOProcessor> iop = boost::dynamic_pointer_cast<IOProcessor> (*i);
3042 if (iop && (iop->output() || iop->input())) {
3043 if (!iop->set_name (name)) {
3054 boost::shared_ptr<Send>
3055 Route::internal_send_for (boost::shared_ptr<const Route> target) const
3057 Glib::RWLock::ReaderLock lm (_processor_lock);
3059 for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
3060 boost::shared_ptr<InternalSend> send;
3062 if ((send = boost::dynamic_pointer_cast<InternalSend>(*i)) != 0) {
3063 if (send->target_route() == target) {
3069 return boost::shared_ptr<Send>();
3073 Route::set_phase_invert (bool yn)
3075 if (_phase_invert != yn) {
3076 _phase_invert = 0xffff; // XXX all channels
3077 phase_invert_changed (); /* EMIT SIGNAL */
3082 Route::phase_invert () const
3084 return _phase_invert != 0;
3088 Route::set_denormal_protection (bool yn)
3090 if (_denormal_protection != yn) {
3091 _denormal_protection = yn;
3092 denormal_protection_changed (); /* EMIT SIGNAL */
3097 Route::denormal_protection () const
3099 return _denormal_protection;
3103 Route::set_active (bool yn)
3105 if (_active != yn) {
3107 _input->set_active (yn);
3108 _output->set_active (yn);
3109 active_changed (); // EMIT SIGNAL
3116 Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
3122 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
3124 boost::shared_ptr<Send> s;
3125 boost::shared_ptr<Return> r;
3127 if ((s = boost::dynamic_pointer_cast<Send> (*i)) != 0) {
3128 s->meter()->meter();
3129 } else if ((r = boost::dynamic_pointer_cast<Return> (*i)) != 0) {
3130 r->meter()->meter ();
3135 boost::shared_ptr<Panner>
3136 Route::panner() const
3138 return _main_outs->panner();
3141 boost::shared_ptr<AutomationControl>
3142 Route::gain_control() const
3144 return _amp->gain_control();
3147 boost::shared_ptr<AutomationControl>
3148 Route::get_control (const Evoral::Parameter& param)
3150 /* either we own the control or .... */
3152 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(control (param));
3156 /* maybe one of our processors does or ... */
3158 Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
3159 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
3160 if ((c = boost::dynamic_pointer_cast<AutomationControl>((*i)->control (param))) != 0) {
3168 /* nobody does so we'll make a new one */
3170 c = boost::dynamic_pointer_cast<AutomationControl>(control_factory(param));
3177 boost::shared_ptr<Processor>
3178 Route::nth_plugin (uint32_t n)
3180 Glib::RWLock::ReaderLock lm (_processor_lock);
3181 ProcessorList::iterator i;
3183 for (i = _processors.begin(); i != _processors.end(); ++i) {
3184 if (boost::dynamic_pointer_cast<PluginInsert> (*i)) {
3191 return boost::shared_ptr<Processor> ();
3194 boost::shared_ptr<Processor>
3195 Route::nth_send (uint32_t n)
3197 Glib::RWLock::ReaderLock lm (_processor_lock);
3198 ProcessorList::iterator i;
3200 for (i = _processors.begin(); i != _processors.end(); ++i) {
3201 cerr << "check " << (*i)->name() << endl;
3202 if (boost::dynamic_pointer_cast<Send> (*i)) {
3207 cerr << "\tnot a send\n";
3211 return boost::shared_ptr<Processor> ();