2 Copyright (C) 2000 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "pbd/xml++.h"
26 #include "pbd/enumwriter.h"
27 #include "pbd/memento_command.h"
28 #include "pbd/stacktrace.h"
29 #include "pbd/convert.h"
31 #include "evoral/Curve.hpp"
33 #include "ardour/amp.h"
34 #include "ardour/audio_port.h"
35 #include "ardour/audioengine.h"
36 #include "ardour/buffer.h"
37 #include "ardour/buffer_set.h"
38 #include "ardour/configuration.h"
39 #include "ardour/cycle_timer.h"
40 #include "ardour/debug.h"
41 #include "ardour/delivery.h"
42 #include "ardour/dB.h"
43 #include "ardour/internal_send.h"
44 #include "ardour/internal_return.h"
45 #include "ardour/ladspa_plugin.h"
46 #include "ardour/meter.h"
47 #include "ardour/mix.h"
48 #include "ardour/panner.h"
49 #include "ardour/plugin_insert.h"
50 #include "ardour/port.h"
51 #include "ardour/port_insert.h"
52 #include "ardour/processor.h"
53 #include "ardour/profile.h"
54 #include "ardour/route.h"
55 #include "ardour/route_group.h"
56 #include "ardour/send.h"
57 #include "ardour/session.h"
58 #include "ardour/timestamps.h"
59 #include "ardour/utils.h"
64 using namespace ARDOUR;
67 uint32_t Route::order_key_cnt = 0;
68 PBD::Signal1<void,string const&> Route::SyncOrderKeys;
69 PBD::Signal0<void> Route::RemoteControlIDChange;
71 Route::Route (Session& sess, string name, Flag flg, DataType default_type)
72 : SessionObject (sess, name)
73 , AutomatableControls (sess)
75 , _solo_control (new SoloControllable (X_("solo"), *this))
76 , _mute_control (new MuteControllable (X_("mute"), *this))
77 , _mute_master (new MuteMaster (sess, name))
78 , _default_type (default_type)
83 /* add standard processors other than amp (added by ::init()) */
85 _meter.reset (new PeakMeter (_session));
86 _meter->set_display_to_user (false);
87 add_processor (_meter, PostFader);
89 if (_flags & ControlOut) {
90 /* where we listen to tracks */
91 _intreturn.reset (new InternalReturn (_session));
92 add_processor (_intreturn, PreFader);
95 _main_outs.reset (new Delivery (_session, _output, _mute_master, _name, Delivery::Main));
96 add_processor (_main_outs, PostFader);
98 /* now that we have _meter, its safe to connect to this */
100 Metering::Meter.connect_same_thread (*this, (boost::bind (&Route::meter, this)));
103 Route::Route (Session& sess, const XMLNode& node, DataType default_type)
104 : SessionObject (sess, "toBeReset")
105 , AutomatableControls (sess)
106 , _solo_control (new SoloControllable (X_("solo"), *this))
107 , _mute_control (new MuteControllable (X_("mute"), *this))
108 , _mute_master (new MuteMaster (sess, "toBeReset"))
109 , _default_type (default_type)
113 _set_state (node, Stateful::loading_state_version, false);
115 /* now that we have _meter, its safe to connect to this */
117 Metering::Meter.connect_same_thread (*this, (boost::bind (&Route::meter, this)));
124 _soloed_by_others = 0;
128 processor_max_streams.reset();
130 order_keys[N_("signal")] = order_key_cnt++;
132 _meter_point = MeterPostFader;
135 _have_internal_generator = false;
136 _declickable = false;
137 _pending_declick = true;
138 _remote_control_id = 0;
139 _in_configure_processors = false;
140 _mute_points = MuteMaster::AllPoints;
143 _denormal_protection = false;
145 /* add standard controls */
147 _solo_control->set_flags (Controllable::Flag (_solo_control->flags() | Controllable::Toggle));
148 _mute_control->set_flags (Controllable::Flag (_solo_control->flags() | Controllable::Toggle));
150 add_control (_solo_control);
151 add_control (_mute_control);
153 /* input and output objects */
155 _input.reset (new IO (_session, _name, IO::Input, _default_type));
156 _output.reset (new IO (_session, _name, IO::Output, _default_type));
158 _input->changed.connect_same_thread (*this, boost::bind (&Route::input_change_handler, this, _1, _2));
159 _output->changed.connect_same_thread (*this, boost::bind (&Route::output_change_handler, this, _1, _2));
161 /* add amp processor */
163 _amp.reset (new Amp (_session, _mute_master));
164 add_processor (_amp, PostFader);
169 DEBUG_TRACE (DEBUG::Destruction, string_compose ("route %1 destructor\n", _name));
171 /* do this early so that we don't get incoming signals as we are going through destruction
176 /* don't use clear_processors here, as it depends on the session which may
177 be half-destroyed by now
180 Glib::RWLock::WriterLock lm (_processor_lock);
181 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
182 (*i)->drop_references ();
185 _processors.clear ();
189 Route::set_remote_control_id (uint32_t id, bool notify_class_listeners)
191 if (id != _remote_control_id) {
192 _remote_control_id = id;
193 RemoteControlIDChanged ();
194 if (notify_class_listeners) {
195 RemoteControlIDChange ();
201 Route::remote_control_id() const
203 return _remote_control_id;
207 Route::order_key (std::string const & name) const
209 OrderKeys::const_iterator i = order_keys.find (name);
210 if (i == order_keys.end()) {
218 Route::set_order_key (std::string const & name, long n)
220 order_keys[name] = n;
222 if (Config->get_sync_all_route_ordering()) {
223 for (OrderKeys::iterator x = order_keys.begin(); x != order_keys.end(); ++x) {
228 _session.set_dirty ();
231 /** Set all order keys to be the same as that for `base', if such a key
232 * exists in this route.
233 * @param base Base key.
236 Route::sync_order_keys (std::string const & base)
238 if (order_keys.empty()) {
242 OrderKeys::iterator i;
245 if ((i = order_keys.find (base)) == order_keys.end()) {
246 /* key doesn't exist, use the first existing key (during session initialization) */
247 i = order_keys.begin();
251 /* key exists - use it and reset all others (actually, itself included) */
253 i = order_keys.begin();
256 for (; i != order_keys.end(); ++i) {
262 Route::ensure_track_or_route_name(string name, Session &session)
264 string newname = name;
266 while (session.route_by_name (newname) != NULL) {
267 newname = bump_name_once (newname);
275 Route::inc_gain (gain_t fraction, void *src)
277 _amp->inc_gain (fraction, src);
281 Route::set_gain (gain_t val, void *src)
283 if (src != 0 && _route_group && src != _route_group && _route_group->is_active() && _route_group->is_gain()) {
285 if (_route_group->is_relative()) {
287 gain_t usable_gain = _amp->gain();
288 if (usable_gain < 0.000001f) {
289 usable_gain = 0.000001f;
293 if (delta < 0.000001f) {
297 delta -= usable_gain;
302 gain_t factor = delta / usable_gain;
305 factor = _route_group->get_max_factor(factor);
306 if (factor == 0.0f) {
307 _amp->gain_control()->Changed(); /* EMIT SIGNAL */
311 factor = _route_group->get_min_factor(factor);
312 if (factor == 0.0f) {
313 _amp->gain_control()->Changed(); /* EMIT SIGNAL */
318 _route_group->apply (&Route::inc_gain, factor, _route_group);
322 _route_group->apply (&Route::set_gain, val, _route_group);
328 if (val == _amp->gain()) {
332 _amp->set_gain (val, src);
335 /** Process this route for one (sub) cycle (process thread)
337 * @param bufs Scratch buffers to use for the signal path
338 * @param start_frame Initial transport frame
339 * @param end_frame Final transport frame
340 * @param nframes Number of frames to output (to ports)
342 * Note that (end_frame - start_frame) may not be equal to nframes when the
343 * transport speed isn't 1.0 (eg varispeed).
346 Route::process_output_buffers (BufferSet& bufs,
347 sframes_t start_frame, sframes_t end_frame, nframes_t nframes,
348 bool /*with_processors*/, int declick)
352 bufs.is_silent (false);
354 switch (Config->get_monitoring_model()) {
355 case HardwareMonitoring:
356 case ExternalMonitoring:
357 monitor = !record_enabled() || (_session.config.get_auto_input() && !_session.actively_recording());
364 declick = _pending_declick;
367 /* figure out if we're going to use gain automation */
368 _amp->setup_gain_automation (start_frame, end_frame, nframes);
371 /* tell main outs what to do about monitoring */
372 _main_outs->no_outs_cuz_we_no_monitor (!monitor);
375 /* -------------------------------------------------------------------------------------------
376 GLOBAL DECLICK (for transport changes etc.)
377 ----------------------------------------------------------------------------------------- */
380 Amp::apply_gain (bufs, nframes, 0.0, 1.0);
381 } else if (declick < 0) {
382 Amp::apply_gain (bufs, nframes, 1.0, 0.0);
385 _pending_declick = 0;
387 /* -------------------------------------------------------------------------------------------
388 DENORMAL CONTROL/PHASE INVERT
389 ----------------------------------------------------------------------------------------- */
395 if (_denormal_protection || Config->get_denormal_protection()) {
397 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i, ++chn) {
398 Sample* const sp = i->data();
400 if (_phase_invert & chn) {
401 for (nframes_t nx = 0; nx < nframes; ++nx) {
406 for (nframes_t nx = 0; nx < nframes; ++nx) {
414 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i, ++chn) {
415 Sample* const sp = i->data();
417 if (_phase_invert & chn) {
418 for (nframes_t nx = 0; nx < nframes; ++nx) {
427 if (_denormal_protection || Config->get_denormal_protection()) {
429 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
430 Sample* const sp = i->data();
431 for (nframes_t nx = 0; nx < nframes; ++nx) {
439 /* -------------------------------------------------------------------------------------------
441 ----------------------------------------------------------------------------------------- */
443 Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
446 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
448 if (bufs.count() != (*i)->input_streams()) {
449 cerr << _name << " bufs = " << bufs.count()
450 << " input for " << (*i)->name() << " = " << (*i)->input_streams()
453 assert (bufs.count() == (*i)->input_streams());
455 (*i)->run (bufs, start_frame, end_frame, nframes, *i != _processors.back());
456 bufs.set_count ((*i)->output_streams());
462 Route::n_process_buffers ()
464 return max (_input->n_ports(), processor_max_streams);
468 Route::passthru (sframes_t start_frame, sframes_t end_frame, nframes_t nframes, int declick)
470 BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers());
474 assert (bufs.available() >= _input->n_ports());
476 if (_input->n_ports() == ChanCount::ZERO) {
480 bufs.set_count (_input->n_ports());
482 if (is_control() && _session.listening()) {
484 /* control/monitor bus ignores input ports when something is
485 feeding the listen "stream". data will "arrive" into the
486 route from the intreturn processor element.
489 bufs.silence (nframes, 0);
493 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
495 BufferSet::iterator o = bufs.begin(*t);
496 PortSet& ports (_input->ports());
498 for (PortSet::iterator i = ports.begin(*t); i != ports.end(*t); ++i, ++o) {
499 o->read_from (i->get_buffer(nframes), nframes);
504 write_out_of_band_data (bufs, start_frame, end_frame, nframes);
505 process_output_buffers (bufs, start_frame, end_frame, nframes, true, declick);
509 Route::passthru_silence (sframes_t start_frame, sframes_t end_frame, nframes_t nframes, int declick)
511 BufferSet& bufs (_session.get_silent_buffers (n_process_buffers()));
512 bufs.set_count (_input->n_ports());
513 write_out_of_band_data (bufs, start_frame, end_frame, nframes);
514 process_output_buffers (bufs, start_frame, end_frame, nframes, true, declick);
518 Route::set_listen (bool yn, void* src)
521 if (yn != _control_outs->active()) {
523 _control_outs->set_solo_level (1);
524 _control_outs->activate ();
526 _control_outs->set_solo_level (0);
527 _control_outs->deactivate ();
530 listen_changed (src); /* EMIT SIGNAL */
536 Route::listening () const
539 return _control_outs->active ();
546 Route::set_solo_safe (bool yn, void *src)
548 if (_solo_safe != yn) {
550 solo_safe_changed (src);
555 Route::solo_safe() const
561 Route::set_solo (bool yn, void *src)
567 if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_solo()) {
568 _route_group->apply (&Route::set_solo, yn, _route_group);
572 if (self_soloed() != yn) {
574 set_delivery_solo ();
575 solo_changed (src); /* EMIT SIGNAL */
576 _solo_control->Changed (); /* EMIT SIGNAL */
581 Route::set_self_solo (bool yn)
587 Route::mod_solo_by_others (int32_t delta)
590 if (_soloed_by_others >= (uint32_t) delta) {
591 _soloed_by_others += delta;
593 _soloed_by_others = 0;
596 _soloed_by_others += delta;
599 set_delivery_solo ();
603 Route::set_delivery_solo ()
605 /* tell all delivery processors what the solo situation is, so that they keep
606 delivering even though Session::soloing() is true and they were not
610 Glib::RWLock::ReaderLock rm (_processor_lock);
611 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
612 boost::shared_ptr<Delivery> d;
614 if ((d = boost::dynamic_pointer_cast<Delivery> (*i)) != 0) {
615 d->set_solo_level (soloed ());
616 d->set_solo_isolated (solo_isolated());
622 Route::set_solo_isolated (bool yn, void *src)
624 if (is_master() || is_control() || is_hidden()) {
628 if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_solo()) {
629 _route_group->apply (&Route::set_solo_isolated, yn, _route_group);
633 /* forward propagate solo-isolate status to everything fed by this route, but not those via sends only */
635 boost::shared_ptr<RouteList> routes = _session.get_routes ();
636 for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
638 bool does_feed = feeds (*i, &sends_only);
640 if (does_feed && !sends_only) {
641 (*i)->set_solo_isolated (yn, (*i)->route_group());
645 bool changed = false;
648 if (_solo_isolated == 0) {
653 changed = (_solo_isolated == 1);
654 if (_solo_isolated > 0) {
660 set_delivery_solo ();
661 solo_isolated_changed (src);
666 Route::solo_isolated () const
668 return _solo_isolated > 0;
672 Route::set_mute_points (MuteMaster::MutePoint mp)
675 mute_points_changed (); /* EMIT SIGNAL */
677 if (_mute_master->muted()) {
678 _mute_master->mute_at (_mute_points);
679 mute_changed (this); /* EMIT SIGNAL */
684 Route::set_mute (bool yn, void *src)
686 if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_mute()) {
687 _route_group->apply (&Route::set_mute, yn, _route_group);
693 _mute_master->mute_at (_mute_points);
695 _mute_master->clear_mute ();
698 mute_changed (src); /* EMIT SIGNAL */
705 return _mute_master->muted ();
710 dump_processors(const string& name, const list<boost::shared_ptr<Processor> >& procs)
712 cerr << name << " {" << endl;
713 for (list<boost::shared_ptr<Processor> >::const_iterator p = procs.begin();
714 p != procs.end(); ++p) {
715 cerr << "\t" << (*p)->name() << " ID = " << (*p)->id() << endl;
722 Route::add_processor (boost::shared_ptr<Processor> processor, Placement placement, ProcessorStreams* err)
724 ProcessorList::iterator loc;
726 /* XXX this is not thread safe - we don't hold the lock across determining the iter
727 to add before and actually doing the insertion. dammit.
730 if (placement == PreFader) {
731 /* generic pre-fader: insert immediately before the amp */
732 loc = find (_processors.begin(), _processors.end(), _amp);
734 /* generic post-fader: insert right before the main outs */
735 loc = find (_processors.begin(), _processors.end(), _main_outs);
738 return add_processor (processor, loc, err);
742 /** Add a processor to the route.
743 * If @a iter is not NULL, it must point to an iterator in _processors and the new
744 * processor will be inserted immediately before this location. Otherwise,
745 * @a position is used.
748 Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::iterator iter, ProcessorStreams* err)
750 ChanCount old_pms = processor_max_streams;
752 if (!_session.engine().connected() || !processor) {
757 Glib::RWLock::WriterLock lm (_processor_lock);
759 boost::shared_ptr<PluginInsert> pi;
760 boost::shared_ptr<PortInsert> porti;
762 ProcessorList::iterator loc = find(_processors.begin(), _processors.end(), processor);
764 if (processor == _amp || processor == _meter || processor == _main_outs) {
765 // Ensure only one of these are in the list at any time
766 if (loc != _processors.end()) {
767 if (iter == loc) { // Already in place, do nothing
769 } else { // New position given, relocate
770 _processors.erase (loc);
775 if (loc != _processors.end()) {
776 cerr << "ERROR: Processor added to route twice!" << endl;
783 _processors.insert (loc, processor);
785 // Set up processor list channels. This will set processor->[input|output]_streams(),
786 // configure redirect ports properly, etc.
788 if (configure_processors_unlocked (err)) {
789 ProcessorList::iterator ploc = loc;
791 _processors.erase(ploc);
792 configure_processors_unlocked (0); // it worked before we tried to add it ...
793 cerr << "configure failed\n";
797 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(processor)) != 0) {
799 if (pi->natural_input_streams() == ChanCount::ZERO) {
800 /* generator plugin */
801 _have_internal_generator = true;
806 if (_control_outs != processor) {
807 // XXX: do we want to emit the signal here ? change call order.
808 processor->activate ();
811 processor->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false, false));
813 _output->set_user_latency (0);
816 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
822 Route::add_processor_from_xml (const XMLNode& node, ProcessorList::iterator iter)
824 const XMLProperty *prop;
826 if (node.name() != "Processor") {
831 if ((prop = node.property ("type")) != 0) {
833 boost::shared_ptr<Processor> processor;
835 if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
836 prop->value() == "lv2" ||
837 prop->value() == "vst" ||
838 prop->value() == "audiounit") {
840 processor.reset (new PluginInsert(_session, node));
842 } else if (prop->value() == "port") {
844 processor.reset (new PortInsert (_session, _mute_master, node));
846 } else if (prop->value() == "send") {
848 processor.reset (new Send (_session, _mute_master, node));
850 } else if (prop->value() == "meter") {
853 if (_meter->set_state (node, Stateful::loading_state_version)) {
860 _meter.reset (new PeakMeter (_session, node));
861 _meter->set_display_to_user (_meter_point == MeterCustom);
864 } else if (prop->value() == "amp") {
866 /* amp always exists */
869 if (processor->set_state (node, Stateful::loading_state_version)) {
872 /* never any reason to add it */
876 } else if (prop->value() == "intsend") {
878 processor.reset (new InternalSend (_session, _mute_master, node));
880 } else if (prop->value() == "intreturn") {
883 if (_intreturn->set_state (node, Stateful::loading_state_version)) {
889 _intreturn.reset (new InternalReturn (_session, node));
890 processor = _intreturn;
892 } else if (prop->value() == "main-outs") {
895 if (_main_outs->set_state (node, Stateful::loading_state_version)) {
902 _main_outs.reset (new Delivery (_session, _output, _mute_master, node));
903 processor = _main_outs;
906 error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
910 if (iter == _processors.end() && processor->display_to_user() && !_processors.empty()) {
911 /* check for invisible processors stacked at the end and leave them there */
912 ProcessorList::iterator p;
913 p = _processors.end();
915 while (!(*p)->display_to_user() && p != _processors.begin()) {
922 return (add_processor (processor, iter) == 0);
925 error << _("Processor XML node has no type property") << endmsg;
930 catch (failed_constructor &err) {
931 warning << _("processor could not be created. Ignored.") << endmsg;
938 Route::add_processor_from_xml_2X (const XMLNode& node, int version, ProcessorList::iterator iter)
940 const XMLProperty *prop;
943 boost::shared_ptr<Processor> processor;
945 if (node.name() == "Insert") {
947 if ((prop = node.property ("type")) != 0) {
949 if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
950 prop->value() == "lv2" ||
951 prop->value() == "vst" ||
952 prop->value() == "audiounit") {
954 processor.reset (new PluginInsert (_session, node));
958 processor.reset (new PortInsert (_session, _mute_master, node));
963 } else if (node.name() == "Send") {
965 processor.reset (new Send (_session, _mute_master, node, version));
969 error << string_compose(_("unknown Processor type \"%1\"; ignored"), node.name()) << endmsg;
973 if (iter == _processors.end() && processor->display_to_user() && !_processors.empty()) {
974 /* check for invisible processors stacked at the end and leave them there */
975 ProcessorList::iterator p;
976 p = _processors.end();
978 while (!(*p)->display_to_user() && p != _processors.begin()) {
985 return (add_processor (processor, iter) == 0);
988 catch (failed_constructor &err) {
989 warning << _("processor could not be created. Ignored.") << endmsg;
995 Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor> before, ProcessorStreams* err)
997 ProcessorList::iterator loc;
1000 loc = find(_processors.begin(), _processors.end(), before);
1002 /* nothing specified - at end but before main outs */
1003 loc = find (_processors.begin(), _processors.end(), _main_outs);
1006 return add_processors (others, loc, err);
1010 Route::add_processors (const ProcessorList& others, ProcessorList::iterator iter, ProcessorStreams* err)
1012 /* NOTE: this is intended to be used ONLY when copying
1013 processors from another Route. Hence the subtle
1014 differences between this and ::add_processor()
1017 ChanCount old_pms = processor_max_streams;
1019 if (!_session.engine().connected()) {
1023 if (others.empty()) {
1028 Glib::RWLock::WriterLock lm (_processor_lock);
1030 ChanCount potential_max_streams = ChanCount::max (_input->n_ports(), _output->n_ports());
1032 for (ProcessorList::const_iterator i = others.begin(); i != others.end(); ++i) {
1034 // Ensure meter only appears in the list once
1036 ProcessorList::iterator m = find(_processors.begin(), _processors.end(), *i);
1037 if (m != _processors.end()) {
1038 _processors.erase(m);
1042 boost::shared_ptr<PluginInsert> pi;
1044 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
1047 ChanCount m = max (pi->input_streams(), pi->output_streams());
1049 if (m > potential_max_streams) {
1050 potential_max_streams = m;
1054 ProcessorList::iterator inserted = _processors.insert (iter, *i);
1056 if ((*i)->active()) {
1060 if (configure_processors_unlocked (err)) {
1061 _processors.erase (inserted);
1062 configure_processors_unlocked (0); // it worked before we tried to add it ...
1066 (*i)->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false, false));
1069 _output->set_user_latency (0);
1072 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1078 Route::placement_range(Placement p, ProcessorList::iterator& start, ProcessorList::iterator& end)
1080 if (p == PreFader) {
1081 start = _processors.begin();
1082 end = find(_processors.begin(), _processors.end(), _amp);
1084 start = find(_processors.begin(), _processors.end(), _amp);
1086 end = _processors.end();
1090 /** Turn off all processors with a given placement
1091 * @param p Placement of processors to disable
1094 Route::disable_processors (Placement p)
1096 Glib::RWLock::ReaderLock lm (_processor_lock);
1098 ProcessorList::iterator start, end;
1099 placement_range(p, start, end);
1101 for (ProcessorList::iterator i = start; i != end; ++i) {
1102 (*i)->deactivate ();
1105 _session.set_dirty ();
1108 /** Turn off all redirects
1111 Route::disable_processors ()
1113 Glib::RWLock::ReaderLock lm (_processor_lock);
1115 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1116 (*i)->deactivate ();
1119 _session.set_dirty ();
1122 /** Turn off all redirects with a given placement
1123 * @param p Placement of redirects to disable
1126 Route::disable_plugins (Placement p)
1128 Glib::RWLock::ReaderLock lm (_processor_lock);
1130 ProcessorList::iterator start, end;
1131 placement_range(p, start, end);
1133 for (ProcessorList::iterator i = start; i != end; ++i) {
1134 if (boost::dynamic_pointer_cast<PluginInsert> (*i)) {
1135 (*i)->deactivate ();
1139 _session.set_dirty ();
1142 /** Turn off all plugins
1145 Route::disable_plugins ()
1147 Glib::RWLock::ReaderLock lm (_processor_lock);
1149 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1150 if (boost::dynamic_pointer_cast<PluginInsert> (*i)) {
1151 (*i)->deactivate ();
1155 _session.set_dirty ();
1160 Route::ab_plugins (bool forward)
1162 Glib::RWLock::ReaderLock lm (_processor_lock);
1166 /* forward = turn off all active redirects, and mark them so that the next time
1167 we go the other way, we will revert them
1170 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1171 if (!boost::dynamic_pointer_cast<PluginInsert> (*i)) {
1175 if ((*i)->active()) {
1176 (*i)->deactivate ();
1177 (*i)->set_next_ab_is_active (true);
1179 (*i)->set_next_ab_is_active (false);
1185 /* backward = if the redirect was marked to go active on the next ab, do so */
1187 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1189 if (!boost::dynamic_pointer_cast<PluginInsert> (*i)) {
1193 if ((*i)->get_next_ab_is_active()) {
1196 (*i)->deactivate ();
1201 _session.set_dirty ();
1205 /** Remove processors with a given placement.
1206 * @param p Placement of processors to remove.
1209 Route::clear_processors (Placement p)
1211 const ChanCount old_pms = processor_max_streams;
1213 if (!_session.engine().connected()) {
1217 bool already_deleting = _session.deletion_in_progress();
1218 if (!already_deleting) {
1219 _session.set_deletion_in_progress();
1223 Glib::RWLock::WriterLock lm (_processor_lock);
1224 ProcessorList new_list;
1225 ProcessorStreams err;
1226 bool seen_amp = false;
1228 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1234 if ((*i) == _amp || (*i) == _meter || (*i) == _main_outs) {
1236 /* you can't remove these */
1238 new_list.push_back (*i);
1245 new_list.push_back (*i);
1248 (*i)->drop_references ();
1256 (*i)->drop_references ();
1259 new_list.push_back (*i);
1266 _processors = new_list;
1267 configure_processors_unlocked (&err); // this can't fail
1270 processor_max_streams.reset();
1271 _have_internal_generator = false;
1272 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1274 if (!already_deleting) {
1275 _session.clear_deletion_in_progress();
1280 Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStreams* err)
1282 /* these can never be removed */
1284 if (processor == _amp || processor == _meter || processor == _main_outs) {
1288 ChanCount old_pms = processor_max_streams;
1290 if (!_session.engine().connected()) {
1294 processor_max_streams.reset();
1297 Glib::RWLock::WriterLock lm (_processor_lock);
1298 ProcessorList::iterator i;
1299 bool removed = false;
1301 for (i = _processors.begin(); i != _processors.end(); ) {
1302 if (*i == processor) {
1304 /* move along, see failure case for configure_processors()
1305 where we may need to reconfigure the processor.
1308 /* stop redirects that send signals to JACK ports
1309 from causing noise as a result of no longer being
1313 boost::shared_ptr<IOProcessor> iop;
1315 if ((iop = boost::dynamic_pointer_cast<IOProcessor> (*i)) != 0) {
1317 iop->input()->disconnect (this);
1319 if (iop->output()) {
1320 iop->output()->disconnect (this);
1324 i = _processors.erase (i);
1332 _output->set_user_latency (0);
1340 if (configure_processors_unlocked (err)) {
1341 /* get back to where we where */
1342 _processors.insert (i, processor);
1343 /* we know this will work, because it worked before :) */
1344 configure_processors_unlocked (0);
1348 _have_internal_generator = false;
1350 for (i = _processors.begin(); i != _processors.end(); ++i) {
1351 boost::shared_ptr<PluginInsert> pi;
1353 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
1354 if (pi->is_generator()) {
1355 _have_internal_generator = true;
1362 processor->drop_references ();
1363 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1369 Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams* err)
1371 ProcessorList deleted;
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 ProcessorList 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;
2369 if (route == _session.control_out()) {
2370 /* master never sends to control outs */
2373 listener.reset (new InternalSend (_session, _mute_master, route, (aux ? Delivery::Aux : Delivery::Listen)));
2377 listener.reset (new InternalSend (_session, _mute_master, route, (aux ? Delivery::Aux : Delivery::Listen)));
2378 if (route == _session.control_out()) {
2382 } catch (failed_constructor& err) {
2386 if (route == _session.control_out()) {
2387 _control_outs = listener;
2388 /* send to control/listen/monitor bus is active by default */
2389 listener->activate ();
2393 add_processor (listener, placement);
2399 Route::drop_listen (boost::shared_ptr<Route> route)
2401 ProcessorStreams err;
2402 ProcessorList::iterator tmp;
2404 Glib::RWLock::ReaderLock rl(_processor_lock);
2408 for (ProcessorList::iterator x = _processors.begin(); x != _processors.end(); ) {
2410 boost::shared_ptr<InternalSend> d = boost::dynamic_pointer_cast<InternalSend>(*x);
2412 if (d && d->target_route() == route) {
2414 remove_processor (*x, &err);
2417 /* list could have been demolished while we dropped the lock
2427 if (route == _session.control_out()) {
2428 _control_outs.reset ();
2433 Route::set_comment (string cmt, void *src)
2436 comment_changed (src);
2437 _session.set_dirty ();
2441 Route::feeds (boost::shared_ptr<Route> other, bool* only_send)
2443 DEBUG_TRACE (DEBUG::Graph, string_compose ("Feeds? %1\n", _name));
2445 if (_output->connected_to (other->input())) {
2446 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tdirect FEEDS %2\n", other->name()));
2455 for (ProcessorList::iterator r = _processors.begin(); r != _processors.end(); ++r) {
2457 boost::shared_ptr<IOProcessor> iop;
2459 if ((iop = boost::dynamic_pointer_cast<IOProcessor>(*r)) != 0) {
2460 if (iop->feeds (other)) {
2461 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tIOP %1 does feed %2\n", iop->name(), other->name()));
2467 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tIOP %1 does NOT feed %2\n", iop->name(), other->name()));
2470 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tPROC %1 is not an IOP\n", (*r)->name()));
2475 DEBUG_TRACE (DEBUG::Graph, string_compose ("\tdoes NOT feed %1\n", other->name()));
2480 Route::handle_transport_stopped (bool /*abort_ignored*/, bool did_locate, bool can_flush_processors)
2482 nframes_t now = _session.transport_frame();
2485 Glib::RWLock::ReaderLock lm (_processor_lock);
2488 automation_snapshot (now, true);
2491 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2493 if (Config->get_plugins_stop_with_transport() && can_flush_processors) {
2494 (*i)->deactivate ();
2498 (*i)->transport_stopped (now);
2502 _roll_delay = _initial_delay;
2506 Route::input_change_handler (IOChange change, void * /*src*/)
2508 if ((change & ConfigurationChanged)) {
2509 configure_processors (0);
2514 Route::output_change_handler (IOChange change, void * /*src*/)
2516 if ((change & ConfigurationChanged)) {
2518 /* XXX resize all listeners to match _main_outs? */
2520 // configure_processors (0);
2525 Route::pans_required () const
2527 if (n_outputs().n_audio() < 2) {
2531 return max (n_inputs ().n_audio(), processor_max_streams.n_audio());
2535 Route::no_roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame,
2536 bool session_state_changing, bool /*can_record*/, bool /*rec_monitors_input*/)
2538 if (n_outputs().n_total() == 0) {
2542 if (!_active || n_inputs() == ChanCount::ZERO) {
2546 if (session_state_changing) {
2547 if (_session.transport_speed() != 0.0f) {
2548 /* we're rolling but some state is changing (e.g. our diskstream contents)
2549 so we cannot use them. Be silent till this is over.
2551 XXX note the absurdity of ::no_roll() being called when we ARE rolling!
2556 /* we're really not rolling, so we're either delivery silence or actually
2557 monitoring, both of which are safe to do while session_state_changing is true.
2561 _amp->apply_gain_automation (false);
2562 passthru (start_frame, end_frame, nframes, 0);
2568 Route::check_initial_delay (nframes_t nframes, nframes_t& transport_frame)
2570 if (_roll_delay > nframes) {
2572 _roll_delay -= nframes;
2574 /* transport frame is not legal for caller to use */
2577 } else if (_roll_delay > 0) {
2579 nframes -= _roll_delay;
2580 silence (_roll_delay);
2581 /* we've written _roll_delay of samples into the
2582 output ports, so make a note of that for
2585 _main_outs->increment_output_offset (_roll_delay);
2586 transport_frame += _roll_delay;
2595 Route::roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame, int declick,
2596 bool /*can_record*/, bool /*rec_monitors_input*/)
2599 // automation snapshot can also be called from the non-rt context
2600 // and it uses the processor list, so we try to acquire the lock here
2601 Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
2604 automation_snapshot (_session.transport_frame(), false);
2608 if (n_outputs().n_total() == 0) {
2612 if (!_active || n_inputs().n_total() == 0) {
2617 nframes_t unused = 0;
2619 if ((nframes = check_initial_delay (nframes, unused)) == 0) {
2625 passthru (start_frame, end_frame, nframes, declick);
2631 Route::silent_roll (nframes_t nframes, sframes_t /*start_frame*/, sframes_t /*end_frame*/,
2632 bool /*can_record*/, bool /*rec_monitors_input*/)
2639 Route::toggle_monitor_input ()
2641 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
2642 i->ensure_monitor_input( ! i->monitoring_input());
2647 Route::has_external_redirects () const
2649 // FIXME: what about sends? - they don't return a signal back to ardour?
2651 boost::shared_ptr<const PortInsert> pi;
2653 for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
2655 if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*i)) != 0) {
2657 for (PortSet::const_iterator port = pi->output()->ports().begin(); port != pi->output()->ports().end(); ++port) {
2659 string port_name = port->name();
2660 string client_name = port_name.substr (0, port_name.find(':'));
2662 /* only say "yes" if the redirect is actually in use */
2664 if (client_name != "ardour" && pi->active()) {
2675 Route::flush_processors ()
2677 /* XXX shouldn't really try to take this lock, since
2678 this is called from the RT audio thread.
2681 Glib::RWLock::ReaderLock lm (_processor_lock);
2683 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2684 (*i)->deactivate ();
2690 Route::set_meter_point (MeterPoint p, void *src)
2692 /* CAN BE CALLED FROM PROCESS CONTEXT */
2694 if (_meter_point == p) {
2698 bool meter_was_visible_to_user = _meter->display_to_user ();
2701 Glib::RWLock::WriterLock lm (_processor_lock);
2703 if (p != MeterCustom) {
2704 // Move meter in the processors list to reflect the new position
2705 ProcessorList::iterator loc = find (_processors.begin(), _processors.end(), _meter);
2706 _processors.erase(loc);
2709 loc = _processors.begin();
2712 loc = find (_processors.begin(), _processors.end(), _amp);
2714 case MeterPostFader:
2715 loc = _processors.end();
2723 if (loc == _processors.begin()) {
2724 m_in = _input->n_ports();
2726 ProcessorList::iterator before = loc;
2728 m_in = (*before)->output_streams ();
2731 _meter->reflect_inputs (m_in);
2733 _processors.insert (loc, _meter);
2735 /* we do not need to reconfigure the processors, because the meter
2736 (a) is always ready to handle processor_max_streams
2737 (b) is always an N-in/N-out processor, and thus moving
2738 it doesn't require any changes to the other processors.
2741 _meter->set_display_to_user (false);
2745 // just make it visible and let the user move it
2747 _meter->set_display_to_user (true);
2752 meter_change (src); /* EMIT SIGNAL */
2754 bool const meter_visibly_changed = (_meter->display_to_user() != meter_was_visible_to_user);
2756 processors_changed (RouteProcessorChange (RouteProcessorChange::MeterPointChange, meter_visibly_changed)); /* EMIT SIGNAL */
2760 Route::put_control_outs_at (Placement p)
2762 if (!_control_outs) {
2767 Glib::RWLock::WriterLock lm (_processor_lock);
2768 ProcessorList as_it_was (_processors);
2769 // Move meter in the processors list
2770 ProcessorList::iterator loc = find(_processors.begin(), _processors.end(), _control_outs);
2771 _processors.erase(loc);
2775 loc = find(_processors.begin(), _processors.end(), _amp);
2776 if (loc != _processors.begin()) {
2781 loc = find(_processors.begin(), _processors.end(), _amp);
2782 assert (loc != _processors.end());
2787 _processors.insert(loc, _control_outs);
2789 if (configure_processors_unlocked (0)) {
2790 _processors = as_it_was;
2791 configure_processors_unlocked (0); // it worked before we tried to add it ...
2796 processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
2797 _session.set_dirty ();
2801 Route::update_total_latency ()
2803 nframes_t old = _output->effective_latency();
2804 nframes_t own_latency = _output->user_latency();
2806 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2807 if ((*i)->active ()) {
2808 own_latency += (*i)->signal_latency ();
2812 DEBUG_TRACE (DEBUG::Latency, string_compose ("%1: internal redirect latency = %2\n", _name, own_latency));
2814 _output->set_port_latency (own_latency);
2816 if (_output->user_latency() == 0) {
2818 /* this (virtual) function is used for pure Routes,
2819 not derived classes like AudioTrack. this means
2820 that the data processed here comes from an input
2821 port, not prerecorded material, and therefore we
2822 have to take into account any input latency.
2825 own_latency += _input->signal_latency ();
2828 if (old != own_latency) {
2829 _output->set_latency_delay (own_latency);
2830 signal_latency_changed (); /* EMIT SIGNAL */
2833 DEBUG_TRACE (DEBUG::Latency, string_compose ("%1: input latency = %2 total = %3\n", _name, _input->signal_latency(), own_latency));
2835 return _output->effective_latency ();
2839 Route::set_user_latency (nframes_t nframes)
2841 _output->set_user_latency (nframes);
2842 _session.update_latency_compensation (false, false);
2846 Route::set_latency_delay (nframes_t longest_session_latency)
2848 nframes_t old = _initial_delay;
2850 if (_output->effective_latency() < longest_session_latency) {
2851 _initial_delay = longest_session_latency - _output->effective_latency();
2856 if (_initial_delay != old) {
2857 initial_delay_changed (); /* EMIT SIGNAL */
2860 if (_session.transport_stopped()) {
2861 _roll_delay = _initial_delay;
2866 Route::automation_snapshot (nframes_t now, bool force)
2868 panner()->automation_snapshot (now, force);
2870 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2871 (*i)->automation_snapshot (now, force);
2875 Route::SoloControllable::SoloControllable (std::string name, Route& r)
2876 : AutomationControl (r.session(), Evoral::Parameter (SoloAutomation),
2877 boost::shared_ptr<AutomationList>(), name)
2880 boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloAutomation)));
2885 Route::SoloControllable::set_value (float val)
2887 bool bval = ((val >= 0.5f) ? true: false);
2889 this is how it should be done
2891 boost::shared_ptr<RouteList> rl (new RouteList);
2892 rl->push_back (route);
2894 if (Config->get_solo_control_is_listen_control()) {
2895 _session.set_listen (rl, bval);
2897 _session.set_solo (rl, bval);
2900 route.set_solo (bval, this);
2905 Route::SoloControllable::get_value (void) const
2907 if (Config->get_solo_control_is_listen_control()) {
2908 return route.listening() ? 1.0f : 0.0f;
2910 return route.self_soloed() ? 1.0f : 0.0f;
2914 Route::MuteControllable::MuteControllable (std::string name, Route& r)
2915 : AutomationControl (r.session(), Evoral::Parameter (MuteAutomation),
2916 boost::shared_ptr<AutomationList>(), name)
2919 boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(MuteAutomation)));
2924 Route::MuteControllable::set_value (float val)
2926 bool bval = ((val >= 0.5f) ? true: false);
2928 this is how it should be done
2930 boost::shared_ptr<RouteList> rl (new RouteList);
2931 rl->push_back (route);
2932 _session.set_mute (rl, bval);
2934 route.set_mute (bval, this);
2939 Route::MuteControllable::get_value (void) const
2941 return route.muted() ? 1.0f : 0.0f;
2945 Route::set_block_size (nframes_t nframes)
2947 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
2948 (*i)->set_block_size (nframes);
2951 _session.ensure_buffers (n_process_buffers ());
2955 Route::protect_automation ()
2957 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i)
2958 (*i)->protect_automation();
2962 Route::set_pending_declick (int declick)
2965 /* this call is not allowed to turn off a pending declick unless "force" is true */
2967 _pending_declick = declick;
2969 // cerr << _name << ": after setting to " << declick << " pending declick = " << _pending_declick << endl;
2971 _pending_declick = 0;
2976 /** Shift automation forwards from a particular place, thereby inserting time.
2977 * Adds undo commands for any shifts that are performed.
2979 * @param pos Position to start shifting from.
2980 * @param frames Amount to shift forwards by.
2984 Route::shift (nframes64_t /*pos*/, nframes64_t /*frames*/)
2986 #ifdef THIS_NEEDS_FIXING_FOR_V3
2988 /* gain automation */
2989 XMLNode &before = _gain_control->get_state ();
2990 _gain_control->shift (pos, frames);
2991 XMLNode &after = _gain_control->get_state ();
2992 _session.add_command (new MementoCommand<AutomationList> (_gain_automation_curve, &before, &after));
2994 /* pan automation */
2995 for (std::vector<StreamPanner*>::iterator i = _panner->begin (); i != _panner->end (); ++i) {
2996 Curve & c = (*i)->automation ();
2997 XMLNode &before = c.get_state ();
2998 c.shift (pos, frames);
2999 XMLNode &after = c.get_state ();
3000 _session.add_command (new MementoCommand<AutomationList> (c, &before, &after));
3003 /* redirect automation */
3005 Glib::RWLock::ReaderLock lm (redirect_lock);
3006 for (RedirectList::iterator i = _redirects.begin (); i != _redirects.end (); ++i) {
3009 (*i)->what_has_automation (a);
3011 for (set<uint32_t>::const_iterator j = a.begin (); j != a.end (); ++j) {
3012 AutomationList & al = (*i)->automation_list (*j);
3013 XMLNode &before = al.get_state ();
3014 al.shift (pos, frames);
3015 XMLNode &after = al.get_state ();
3016 _session.add_command (new MementoCommand<AutomationList> (al, &before, &after));
3026 Route::save_as_template (const string& path, const string& name)
3028 XMLNode& node (state (false));
3031 IO::set_name_in_state (*node.children().front(), name);
3033 tree.set_root (&node);
3034 return tree.write (path.c_str());
3039 Route::set_name (const string& str)
3045 name = Route::ensure_track_or_route_name (str, _session);
3046 SessionObject::set_name (name);
3048 ret = (_input->set_name(name) && _output->set_name(name));
3052 Glib::RWLock::ReaderLock lm (_processor_lock);
3054 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
3056 /* rename all I/O processors that have inputs or outputs */
3058 boost::shared_ptr<IOProcessor> iop = boost::dynamic_pointer_cast<IOProcessor> (*i);
3060 if (iop && (iop->output() || iop->input())) {
3061 if (!iop->set_name (name)) {
3072 boost::shared_ptr<Send>
3073 Route::internal_send_for (boost::shared_ptr<const Route> target) const
3075 Glib::RWLock::ReaderLock lm (_processor_lock);
3077 for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
3078 boost::shared_ptr<InternalSend> send;
3080 if ((send = boost::dynamic_pointer_cast<InternalSend>(*i)) != 0) {
3081 if (send->target_route() == target) {
3087 return boost::shared_ptr<Send>();
3091 Route::set_phase_invert (bool yn)
3093 if (_phase_invert != yn) {
3094 _phase_invert = 0xffff; // XXX all channels
3095 phase_invert_changed (); /* EMIT SIGNAL */
3100 Route::phase_invert () const
3102 return _phase_invert != 0;
3106 Route::set_denormal_protection (bool yn)
3108 if (_denormal_protection != yn) {
3109 _denormal_protection = yn;
3110 denormal_protection_changed (); /* EMIT SIGNAL */
3115 Route::denormal_protection () const
3117 return _denormal_protection;
3121 Route::set_active (bool yn)
3123 if (_active != yn) {
3125 _input->set_active (yn);
3126 _output->set_active (yn);
3127 active_changed (); // EMIT SIGNAL
3134 Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
3140 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
3142 boost::shared_ptr<Send> s;
3143 boost::shared_ptr<Return> r;
3145 if ((s = boost::dynamic_pointer_cast<Send> (*i)) != 0) {
3146 s->meter()->meter();
3147 } else if ((r = boost::dynamic_pointer_cast<Return> (*i)) != 0) {
3148 r->meter()->meter ();
3153 boost::shared_ptr<Panner>
3154 Route::panner() const
3156 return _main_outs->panner();
3159 boost::shared_ptr<AutomationControl>
3160 Route::gain_control() const
3162 return _amp->gain_control();
3165 boost::shared_ptr<AutomationControl>
3166 Route::get_control (const Evoral::Parameter& param)
3168 /* either we own the control or .... */
3170 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(control (param));
3174 /* maybe one of our processors does or ... */
3176 Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
3177 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
3178 if ((c = boost::dynamic_pointer_cast<AutomationControl>((*i)->control (param))) != 0) {
3186 /* nobody does so we'll make a new one */
3188 c = boost::dynamic_pointer_cast<AutomationControl>(control_factory(param));
3195 boost::shared_ptr<Processor>
3196 Route::nth_plugin (uint32_t n)
3198 Glib::RWLock::ReaderLock lm (_processor_lock);
3199 ProcessorList::iterator i;
3201 for (i = _processors.begin(); i != _processors.end(); ++i) {
3202 if (boost::dynamic_pointer_cast<PluginInsert> (*i)) {
3209 return boost::shared_ptr<Processor> ();
3212 boost::shared_ptr<Processor>
3213 Route::nth_send (uint32_t n)
3215 Glib::RWLock::ReaderLock lm (_processor_lock);
3216 ProcessorList::iterator i;
3218 for (i = _processors.begin(); i != _processors.end(); ++i) {
3219 cerr << "check " << (*i)->name() << endl;
3220 if (boost::dynamic_pointer_cast<Send> (*i)) {
3225 cerr << "\tnot a send\n";
3229 return boost::shared_ptr<Processor> ();