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.
24 #include <sigc++/bind.h>
25 #include <pbd/xml++.h>
26 #include <pbd/enumwriter.h>
28 #include <ardour/timestamps.h>
29 #include <ardour/audioengine.h>
30 #include <ardour/route.h>
31 #include <ardour/buffer.h>
32 #include <ardour/insert.h>
33 #include <ardour/send.h>
34 #include <ardour/session.h>
35 #include <ardour/utils.h>
36 #include <ardour/configuration.h>
37 #include <ardour/cycle_timer.h>
38 #include <ardour/route_group.h>
39 #include <ardour/port.h>
40 #include <ardour/audio_port.h>
41 #include <ardour/ladspa_plugin.h>
42 #include <ardour/panner.h>
43 #include <ardour/dB.h>
44 #include <ardour/mix.h>
45 #include <ardour/amp.h>
46 #include <ardour/meter.h>
47 #include <ardour/buffer_set.h>
51 using namespace ARDOUR;
54 uint32_t Route::order_key_cnt = 0;
57 Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg, DataType default_type)
58 : IO (sess, name, input_min, input_max, output_min, output_max, default_type),
60 _solo_control (X_("solo"), *this, ToggleControllable::SoloControl),
61 _mute_control (X_("mute"), *this, ToggleControllable::MuteControl)
66 Route::Route (Session& sess, const XMLNode& node, DataType default_type)
67 : IO (sess, *node.child ("IO"), default_type),
68 _solo_control (X_("solo"), *this, ToggleControllable::SoloControl),
69 _mute_control (X_("mute"), *this, ToggleControllable::MuteControl)
72 _set_state (node, false);
78 redirect_max_outs.reset();
82 _phase_invert = false;
83 order_keys[strdup (N_("signal"))] = order_key_cnt++;
86 _meter_point = MeterPostFader;
90 _have_internal_generator = false;
92 _pending_declick = true;
93 _remote_control_id = 0;
98 _mute_affects_pre_fader = Config->get_mute_affects_pre_fader();
99 _mute_affects_post_fader = Config->get_mute_affects_post_fader();
100 _mute_affects_control_outs = Config->get_mute_affects_control_outs();
101 _mute_affects_main_outs = Config->get_mute_affects_main_outs();
104 desired_solo_gain = 1.0;
106 desired_mute_gain = 1.0;
110 input_changed.connect (mem_fun (this, &Route::input_change_handler));
111 output_changed.connect (mem_fun (this, &Route::output_change_handler));
116 clear_redirects (PreFader, this);
117 clear_redirects (PostFader, this);
119 for (OrderKeys::iterator i = order_keys.begin(); i != order_keys.end(); ++i) {
120 free ((void*)(i->first));
124 delete _control_outs;
129 Route::set_remote_control_id (uint32_t id)
131 if (id != _remote_control_id) {
132 _remote_control_id = id;
133 RemoteControlIDChanged ();
138 Route::remote_control_id() const
140 return _remote_control_id;
144 Route::order_key (const char* name) const
146 OrderKeys::const_iterator i;
148 for (i = order_keys.begin(); i != order_keys.end(); ++i) {
149 if (!strcmp (name, i->first)) {
158 Route::set_order_key (const char* name, long n)
160 order_keys[strdup(name)] = n;
161 _session.set_dirty ();
165 Route::inc_gain (gain_t fraction, void *src)
167 IO::inc_gain (fraction, src);
171 Route::set_gain (gain_t val, void *src)
173 if (src != 0 && _mix_group && src != _mix_group && _mix_group->is_active()) {
175 if (_mix_group->is_relative()) {
178 gain_t usable_gain = gain();
179 if (usable_gain < 0.000001f) {
180 usable_gain=0.000001f;
184 if (delta < 0.000001f) {
188 delta -= usable_gain;
190 if (delta == 0.0f) return;
192 gain_t factor = delta / usable_gain;
195 factor = _mix_group->get_max_factor(factor);
196 if (factor == 0.0f) {
201 factor = _mix_group->get_min_factor(factor);
202 if (factor == 0.0f) {
208 _mix_group->apply (&Route::inc_gain, factor, _mix_group);
212 _mix_group->apply (&Route::set_gain, val, _mix_group);
222 IO::set_gain (val, src);
225 /** Process this route for one (sub) cycle (process thread)
227 * @param bufs Scratch buffers to use for the signal path
228 * @param start_frame Initial transport frame
229 * @param end_frame Final transport frame
230 * @param nframes Number of frames to output (to ports)
231 * @param offset Output offset (of port buffers, for split cycles)
233 * Note that (end_frame - start_frame) may not be equal to nframes when the
234 * transport speed isn't 1.0 (eg varispeed).
237 Route::process_output_buffers (BufferSet& bufs,
238 nframes_t start_frame, nframes_t end_frame,
239 nframes_t nframes, nframes_t offset, bool with_redirects, int declick,
242 // This is definitely very audio-only for now
243 assert(_default_type == DataType::AUDIO);
245 RedirectList::iterator i;
246 bool post_fader_work = false;
247 bool mute_declick_applied = false;
253 gain_t* gab = _session.gain_automation_buffer();
255 switch (Config->get_monitoring_model()) {
256 case HardwareMonitoring:
257 case ExternalMonitoring:
264 declick = _pending_declick;
267 Glib::Mutex::Lock cm (control_outs_lock, Glib::TRY_LOCK);
277 Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK);
280 dmg = desired_mute_gain;
281 dsg = desired_solo_gain;
290 /* ----------------------------------------------------------------------------------------------------
291 GLOBAL DECLICK (for transport changes etc.)
292 -------------------------------------------------------------------------------------------------- */
295 Amp::run (bufs, nframes, 0.0, 1.0, false);
296 _pending_declick = 0;
297 } else if (declick < 0) {
298 Amp::run (bufs, nframes, 1.0, 0.0, false);
299 _pending_declick = 0;
302 /* no global declick */
304 if (solo_gain != dsg) {
305 Amp::run (bufs, nframes, solo_gain, dsg, false);
311 /* ----------------------------------------------------------------------------------------------------
312 INPUT METERING & MONITORING
313 -------------------------------------------------------------------------------------------------- */
315 if (meter && (_meter_point == MeterInput)) {
316 _meter->run(bufs, nframes);
319 if (!_soloed && _mute_affects_pre_fader && (mute_gain != dmg)) {
320 Amp::run (bufs, nframes, mute_gain, dmg, false);
322 mute_declick_applied = true;
325 if ((_meter_point == MeterInput) && co) {
327 solo_audible = dsg > 0;
328 mute_audible = dmg > 0;// || !_mute_affects_pre_fader;
330 if ( // muted by solo of another track
334 // muted by mute of this track
338 // rec-enabled but not s/w monitoring
340 // TODO: this is probably wrong
342 (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording()))
346 co->silence (nframes, offset);
350 co->deliver_output (bufs, start_frame, end_frame, nframes, offset);
355 /* ---------------------------------------------------------------------------------------------------
357 -------------------------------------------------------------------------------------------------- */
359 /* FIXME: Somewhere in these loops is where bufs.count() should go from n_inputs() to redirect_max_outs()
360 * (if they differ). Something explicit needs to be done here to make sure the list of redirects will
361 * give us what we need (possibly by inserting transparent 'translators' into the list to make it work) */
363 if (with_redirects) {
364 Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK);
366 if (mute_gain > 0 || !_mute_affects_pre_fader) {
367 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
368 switch ((*i)->placement()) {
370 (*i)->run (bufs, start_frame, end_frame, nframes, offset);
373 post_fader_work = true;
378 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
379 switch ((*i)->placement()) {
381 (*i)->silence (nframes, offset);
384 post_fader_work = true;
392 // FIXME: for now, just hope the redirects list did what it was supposed to
393 bufs.set_count(n_process_buffers());
396 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_post_fader) {
397 Amp::run (bufs, nframes, mute_gain, dmg, false);
399 mute_declick_applied = true;
402 /* ----------------------------------------------------------------------------------------------------
403 PRE-FADER METERING & MONITORING
404 -------------------------------------------------------------------------------------------------- */
406 if (meter && (_meter_point == MeterPreFader)) {
407 _meter->run(bufs, nframes);
411 if ((_meter_point == MeterPreFader) && co) {
413 solo_audible = dsg > 0;
414 mute_audible = dmg > 0 || !_mute_affects_pre_fader;
416 if ( // muted by solo of another track
420 // muted by mute of this track
424 // rec-enabled but not s/w monitoring
426 (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording()))
430 co->silence (nframes, offset);
434 co->deliver_output (bufs, start_frame, end_frame, nframes, offset);
439 /* ----------------------------------------------------------------------------------------------------
441 -------------------------------------------------------------------------------------------------- */
443 /* if not recording or recording and requiring any monitor signal, then apply gain */
445 if ( // not recording
447 !(record_enabled() && _session.actively_recording()) ||
451 // h/w monitoring not in use
453 (!Config->get_monitoring_model() == HardwareMonitoring &&
455 // AND software monitoring required
457 Config->get_monitoring_model() == SoftwareMonitoring)) {
459 if (apply_gain_automation) {
462 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
463 Sample* const sp = i->data(nframes);
465 for (nframes_t nx = 0; nx < nframes; ++nx) {
470 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
471 Sample* const sp = i->data(nframes);
473 for (nframes_t nx = 0; nx < nframes; ++nx) {
479 if (apply_gain_automation && _session.transport_rolling() && nframes > 0) {
480 _effective_gain = gab[nframes-1];
485 /* manual (scalar) gain */
489 Amp::run (bufs, nframes, _gain, dg, _phase_invert);
492 } else if (_gain != 0 && (_phase_invert || _gain != 1.0)) {
494 /* no need to interpolate current gain value,
495 but its non-unity, so apply it. if the gain
496 is zero, do nothing because we'll ship silence
508 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
509 Sample* const sp = i->data(nframes);
510 Session::apply_gain_to_buffer(sp,nframes,this_gain);
513 } else if (_gain == 0) {
514 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
522 /* actively recording, no monitoring required; leave buffers as-is to save CPU cycles */
526 /* ----------------------------------------------------------------------------------------------------
528 -------------------------------------------------------------------------------------------------- */
530 /* note that post_fader_work cannot be true unless with_redirects was also true, so don't test both */
532 if (post_fader_work) {
534 Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK);
536 if (mute_gain > 0 || !_mute_affects_post_fader) {
537 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
538 switch ((*i)->placement()) {
542 (*i)->run (bufs, start_frame, end_frame, nframes, offset);
547 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
548 switch ((*i)->placement()) {
552 (*i)->silence (nframes, offset);
560 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_control_outs) {
561 Amp::run (bufs, nframes, mute_gain, dmg, false);
563 mute_declick_applied = true;
566 /* ----------------------------------------------------------------------------------------------------
568 -------------------------------------------------------------------------------------------------- */
570 if ((_meter_point == MeterPostFader) && co) {
572 solo_audible = solo_gain > 0;
573 mute_audible = dmg > 0 || !_mute_affects_control_outs;
575 if ( // silent anyway
577 (_gain == 0 && !apply_gain_automation) ||
579 // muted by solo of another track
583 // muted by mute of this track
587 // recording but not s/w monitoring
589 (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording()))
593 co->silence (nframes, offset);
597 co->deliver_output (bufs, start_frame, end_frame, nframes, offset);
601 /* ----------------------------------------------------------------------
603 ----------------------------------------------------------------------*/
605 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_main_outs) {
606 Amp::run (bufs, nframes, mute_gain, dmg, false);
608 mute_declick_applied = true;
611 /* ----------------------------------------------------------------------------------------------------
613 -------------------------------------------------------------------------------------------------- */
615 solo_audible = dsg > 0;
616 mute_audible = dmg > 0 || !_mute_affects_main_outs;
618 if (n_outputs().get(_default_type) == 0) {
622 } else if (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording())) {
624 IO::silence (nframes, offset);
628 if ( // silent anyway
630 (_gain == 0 && !apply_gain_automation) ||
632 // muted by solo of another track, but not using control outs for solo
634 (!solo_audible && (Config->get_solo_model() != SoloBus)) ||
636 // muted by mute of this track
642 /* don't use Route::silence() here, because that causes
643 all outputs (sends, port inserts, etc. to be silent).
646 if (_meter_point == MeterPostFader) {
647 peak_meter().reset();
650 IO::silence (nframes, offset);
654 deliver_output(bufs, start_frame, end_frame, nframes, offset);
660 /* ----------------------------------------------------------------------------------------------------
662 -------------------------------------------------------------------------------------------------- */
664 if (meter && (_meter_point == MeterPostFader)) {
665 if ((_gain == 0 && !apply_gain_automation) || dmg == 0) {
668 _meter->run(output_buffers(), nframes, offset);
674 Route::n_process_buffers ()
676 return max (n_inputs(), redirect_max_outs);
680 Route::passthru (nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset, int declick, bool meter_first)
682 BufferSet& bufs = _session.get_scratch_buffers(n_process_buffers());
686 collect_input (bufs, nframes, offset);
688 #define meter_stream meter_first
691 _meter->run(bufs, nframes);
692 meter_stream = false;
697 process_output_buffers (bufs, start_frame, end_frame, nframes, offset, true, declick, meter_stream);
703 Route::passthru_silence (jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset, int declick, bool meter)
705 process_output_buffers (_session.get_silent_buffers (n_process_buffers()), start_frame, end_frame, nframes, offset, true, declick, meter);
709 Route::set_solo (bool yn, void *src)
715 if (_mix_group && src != _mix_group && _mix_group->is_active()) {
716 _mix_group->apply (&Route::set_solo, yn, _mix_group);
722 solo_changed (src); /* EMIT SIGNAL */
723 _solo_control.Changed (); /* EMIT SIGNAL */
728 Route::set_solo_mute (bool yn)
730 Glib::Mutex::Lock lm (declick_lock);
732 /* Called by Session in response to another Route being soloed.
735 desired_solo_gain = (yn?0.0:1.0);
739 Route::set_solo_safe (bool yn, void *src)
741 if (_solo_safe != yn) {
743 solo_safe_changed (src); /* EMIT SIGNAL */
748 Route::set_mute (bool yn, void *src)
751 if (_mix_group && src != _mix_group && _mix_group->is_active()) {
752 _mix_group->apply (&Route::set_mute, yn, _mix_group);
758 mute_changed (src); /* EMIT SIGNAL */
760 _mute_control.Changed (); /* EMIT SIGNAL */
762 Glib::Mutex::Lock lm (declick_lock);
763 desired_mute_gain = (yn?0.0f:1.0f);
768 Route::add_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
770 ChanCount old_rmo = redirect_max_outs;
772 if (!_session.engine().connected()) {
777 Glib::RWLock::WriterLock lm (redirect_lock);
779 boost::shared_ptr<PluginInsert> pi;
780 boost::shared_ptr<PortInsert> porti;
782 redirect->set_default_type(_default_type);
784 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(redirect)) != 0) {
787 if (pi->input_streams() == ChanCount::ZERO) {
788 /* generator plugin */
789 _have_internal_generator = true;
792 } else if ((porti = boost::dynamic_pointer_cast<PortInsert>(redirect)) != 0) {
794 /* force new port inserts to start out with an i/o configuration
795 that matches this route's i/o configuration.
797 the "inputs" for the port are supposed to match the output
800 the "outputs" of the route should match the inputs of this
801 route. XXX shouldn't they match the number of active signal
802 streams at the point of insertion?
804 // FIXME: (yes, they should)
806 porti->ensure_io (n_outputs (), n_inputs(), false, this);
809 // Ensure peak vector sizes before the plugin is activated
810 ChanCount potential_max_streams = max(redirect->input_streams(), redirect->output_streams());
811 _meter->setup(potential_max_streams);
813 _redirects.push_back (redirect);
815 if (_reset_plugin_counts (err_streams)) {
816 _redirects.pop_back ();
817 _reset_plugin_counts (0); // it worked before we tried to add it ...
821 redirect->activate ();
822 redirect->active_changed.connect (mem_fun (*this, &Route::redirect_active_proxy));
825 if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
830 redirects_changed (src); /* EMIT SIGNAL */
835 Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_streams)
837 ChanCount old_rmo = redirect_max_outs;
839 if (!_session.engine().connected()) {
844 Glib::RWLock::WriterLock lm (redirect_lock);
846 RedirectList::iterator existing_end = _redirects.end();
849 ChanCount potential_max_streams;
851 for (RedirectList::const_iterator i = others.begin(); i != others.end(); ++i) {
853 boost::shared_ptr<PluginInsert> pi;
855 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
858 ChanCount m = max(pi->input_streams(), pi->output_streams());
859 if (m > potential_max_streams)
860 potential_max_streams = m;
863 // Ensure peak vector sizes before the plugin is activated
864 _meter->setup(potential_max_streams);
866 _redirects.push_back (*i);
868 if (_reset_plugin_counts (err_streams)) {
870 _redirects.erase (existing_end, _redirects.end());
871 _reset_plugin_counts (0); // it worked before we tried to add it ...
876 (*i)->active_changed.connect (mem_fun (*this, &Route::redirect_active_proxy));
880 if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
884 redirects_changed (src); /* EMIT SIGNAL */
888 /** Remove redirects with a given placement.
889 * @param p Placement of redirects to remove.
892 Route::clear_redirects (Placement p, void *src)
894 const ChanCount old_rmo = redirect_max_outs;
896 if (!_session.engine().connected()) {
901 Glib::RWLock::WriterLock lm (redirect_lock);
902 RedirectList new_list;
904 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
905 if ((*i)->placement() == p) {
906 /* it's the placement we want to get rid of */
907 (*i)->drop_references ();
909 /* it's a different placement, so keep it */
910 new_list.push_back (*i);
914 _redirects = new_list;
917 /* FIXME: can't see how this test can ever fire */
918 if (redirect_max_outs != old_rmo) {
922 redirect_max_outs.reset();
923 _have_internal_generator = false;
924 redirects_changed (src); /* EMIT SIGNAL */
928 Route::remove_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
930 ChanCount old_rmo = redirect_max_outs;
932 if (!_session.engine().connected()) {
936 redirect_max_outs.reset();
939 Glib::RWLock::WriterLock lm (redirect_lock);
940 RedirectList::iterator i;
941 bool removed = false;
943 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
944 if (*i == redirect) {
946 RedirectList::iterator tmp;
948 /* move along, see failure case for reset_plugin_counts()
949 where we may need to reinsert the redirect.
955 /* stop redirects that send signals to JACK ports
956 from causing noise as a result of no longer being
960 boost::shared_ptr<Send> send;
961 boost::shared_ptr<PortInsert> port_insert;
963 if ((send = boost::dynamic_pointer_cast<Send> (*i)) != 0) {
964 send->disconnect_inputs (this);
965 send->disconnect_outputs (this);
966 } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (*i)) != 0) {
967 port_insert->disconnect_inputs (this);
968 port_insert->disconnect_outputs (this);
971 _redirects.erase (i);
984 if (_reset_plugin_counts (err_streams)) {
985 /* get back to where we where */
986 _redirects.insert (i, redirect);
987 /* we know this will work, because it worked before :) */
988 _reset_plugin_counts (0);
994 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
995 boost::shared_ptr<PluginInsert> pi;
997 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
998 if (pi->is_generator()) {
1004 _have_internal_generator = foo;
1007 if (old_rmo != redirect_max_outs) {
1011 redirect->drop_references ();
1013 redirects_changed (src); /* EMIT SIGNAL */
1018 Route::reset_plugin_counts (uint32_t* lpc)
1020 Glib::RWLock::WriterLock lm (redirect_lock);
1021 return _reset_plugin_counts (lpc);
1026 Route::_reset_plugin_counts (uint32_t* err_streams)
1028 RedirectList::iterator r;
1031 map<Placement,list<InsertCount> > insert_map;
1032 nframes_t initial_streams;
1034 redirect_max_outs.reset();
1038 /* divide inserts up by placement so we get the signal flow
1039 properly modelled. we need to do this because the _redirects
1040 list is not sorted by placement, and because other reasons may
1041 exist now or in the future for this separate treatment.
1044 for (r = _redirects.begin(); r != _redirects.end(); ++r) {
1046 boost::shared_ptr<Insert> insert;
1048 /* do this here in case we bomb out before we get to the end of
1052 redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs);
1054 if ((insert = boost::dynamic_pointer_cast<Insert>(*r)) != 0) {
1056 insert_map[insert->placement()].push_back (InsertCount (insert));
1058 /* reset plugin counts back to one for now so
1059 that we have a predictable, controlled
1060 state to try to configure.
1063 boost::shared_ptr<PluginInsert> pi;
1065 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(insert)) != 0) {
1069 } else if (boost::dynamic_pointer_cast<Send> (*r) != 0) {
1082 /* Now process each placement in order, checking to see if we
1083 can really do what has been requested.
1088 if (check_some_plugin_counts (insert_map[PreFader], n_inputs ().get(_default_type), err_streams)) {
1092 /* figure out the streams that will feed into PreFader */
1094 if (!insert_map[PreFader].empty()) {
1095 InsertCount& ic (insert_map[PreFader].back());
1096 initial_streams = ic.insert->compute_output_streams (ic.cnt);
1098 initial_streams = n_inputs ().get(_default_type);
1103 if (check_some_plugin_counts (insert_map[PostFader], initial_streams, err_streams)) {
1107 /* OK, everything can be set up correctly, so lets do it */
1109 apply_some_plugin_counts (insert_map[PreFader]);
1110 apply_some_plugin_counts (insert_map[PostFader]);
1112 /* recompute max outs of any redirect */
1116 redirect_max_outs.reset();
1117 RedirectList::iterator prev = _redirects.end();
1119 for (r = _redirects.begin(); r != _redirects.end(); prev = r, ++r) {
1120 boost::shared_ptr<Send> s;
1122 if ((s = boost::dynamic_pointer_cast<Send> (*r)) != 0) {
1123 if (r == _redirects.begin()) {
1124 s->expect_inputs (n_inputs());
1126 s->expect_inputs ((*prev)->output_streams());
1131 /* don't pay any attention to send output configuration, since it doesn't
1135 redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs);
1146 Route::apply_some_plugin_counts (list<InsertCount>& iclist)
1148 list<InsertCount>::iterator i;
1150 for (i = iclist.begin(); i != iclist.end(); ++i) {
1152 if ((*i).insert->configure_io ((*i).cnt, (*i).in, (*i).out)) {
1155 /* make sure that however many we have, they are all active */
1156 (*i).insert->activate ();
1163 Route::check_some_plugin_counts (list<InsertCount>& iclist, int32_t required_inputs, uint32_t* err_streams)
1165 list<InsertCount>::iterator i;
1167 for (i = iclist.begin(); i != iclist.end(); ++i) {
1169 if (((*i).cnt = (*i).insert->can_support_input_configuration (required_inputs)) < 0) {
1171 *err_streams = required_inputs;
1176 (*i).in = required_inputs;
1177 (*i).out = (*i).insert->compute_output_streams ((*i).cnt);
1179 required_inputs = (*i).out;
1186 Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_streams)
1188 ChanCount old_rmo = redirect_max_outs;
1194 RedirectList to_be_deleted;
1197 Glib::RWLock::WriterLock lm (redirect_lock);
1198 RedirectList::iterator tmp;
1199 RedirectList the_copy;
1201 the_copy = _redirects;
1203 /* remove all relevant redirects */
1205 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ) {
1209 if ((*i)->placement() == placement) {
1210 to_be_deleted.push_back (*i);
1211 _redirects.erase (i);
1217 /* now copy the relevant ones from "other" */
1219 for (RedirectList::const_iterator i = other._redirects.begin(); i != other._redirects.end(); ++i) {
1220 if ((*i)->placement() == placement) {
1221 _redirects.push_back (Redirect::clone (*i));
1225 /* reset plugin stream handling */
1227 if (_reset_plugin_counts (err_streams)) {
1229 /* FAILED COPY ATTEMPT: we have to restore order */
1231 /* delete all cloned redirects */
1233 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ) {
1238 if ((*i)->placement() == placement) {
1239 _redirects.erase (i);
1245 /* restore the natural order */
1247 _redirects = the_copy;
1248 redirect_max_outs = old_rmo;
1250 /* we failed, even though things are OK again */
1256 /* SUCCESSFUL COPY ATTEMPT: delete the redirects we removed pre-copy */
1257 to_be_deleted.clear ();
1261 if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
1265 redirects_changed (this); /* EMIT SIGNAL */
1270 Route::all_redirects_flip ()
1272 Glib::RWLock::ReaderLock lm (redirect_lock);
1274 if (_redirects.empty()) {
1278 bool first_is_on = _redirects.front()->active();
1280 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1281 (*i)->set_active (!first_is_on, this);
1285 /** Set all redirects with a given placement to a given active state.
1286 * @param p Placement of redirects to change.
1287 * @param state New active state for those redirects.
1290 Route::all_redirects_active (Placement p, bool state)
1292 Glib::RWLock::ReaderLock lm (redirect_lock);
1294 if (_redirects.empty()) {
1298 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1299 if ((*i)->placement() == p) {
1300 (*i)->set_active (state, this);
1305 struct RedirectSorter {
1306 bool operator() (boost::shared_ptr<const Redirect> a, boost::shared_ptr<const Redirect> b) {
1307 return a->sort_key() < b->sort_key();
1312 Route::sort_redirects (uint32_t* err_streams)
1315 RedirectSorter comparator;
1316 Glib::RWLock::WriterLock lm (redirect_lock);
1317 ChanCount old_rmo = redirect_max_outs;
1319 /* the sweet power of C++ ... */
1321 RedirectList as_it_was_before = _redirects;
1323 _redirects.sort (comparator);
1325 if (_reset_plugin_counts (err_streams)) {
1326 _redirects = as_it_was_before;
1327 redirect_max_outs = old_rmo;
1333 redirects_changed (this); /* EMIT SIGNAL */
1345 Route::get_template()
1347 return state(false);
1351 Route::state(bool full_state)
1353 XMLNode *node = new XMLNode("Route");
1354 RedirectList:: iterator i;
1358 node->add_property("flags", enum_2_string (_flags));
1361 node->add_property("default-type", _default_type.to_string());
1363 node->add_property("active", _active?"yes":"no");
1364 node->add_property("muted", _muted?"yes":"no");
1365 node->add_property("soloed", _soloed?"yes":"no");
1366 node->add_property("phase-invert", _phase_invert?"yes":"no");
1367 node->add_property("mute-affects-pre-fader", _mute_affects_pre_fader?"yes":"no");
1368 node->add_property("mute-affects-post-fader", _mute_affects_post_fader?"yes":"no");
1369 node->add_property("mute-affects-control-outs", _mute_affects_control_outs?"yes":"no");
1370 node->add_property("mute-affects-main-outs", _mute_affects_main_outs?"yes":"no");
1373 node->add_property("edit-group", _edit_group->name());
1376 node->add_property("mix-group", _mix_group->name());
1379 string order_string;
1380 OrderKeys::iterator x = order_keys.begin();
1382 while (x != order_keys.end()) {
1383 order_string += string ((*x).first);
1384 order_string += '=';
1385 snprintf (buf, sizeof(buf), "%ld", (*x).second);
1386 order_string += buf;
1390 if (x == order_keys.end()) {
1394 order_string += ':';
1396 node->add_property ("order-keys", order_string);
1398 node->add_child_nocopy (IO::state (full_state));
1399 node->add_child_nocopy (_solo_control.get_state ());
1400 node->add_child_nocopy (_mute_control.get_state ());
1402 XMLNode* remote_control_node = new XMLNode (X_("remote_control"));
1403 snprintf (buf, sizeof (buf), "%d", _remote_control_id);
1404 remote_control_node->add_property (X_("id"), buf);
1405 node->add_child_nocopy (*remote_control_node);
1407 if (_control_outs) {
1408 XMLNode* cnode = new XMLNode (X_("ControlOuts"));
1409 cnode->add_child_nocopy (_control_outs->state (full_state));
1410 node->add_child_nocopy (*cnode);
1413 if (_comment.length()) {
1414 XMLNode *cmt = node->add_child ("Comment");
1415 cmt->add_content (_comment);
1418 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
1419 node->add_child_nocopy((*i)->state (full_state));
1423 node->add_child_copy (*_extra_xml);
1430 Route::set_deferred_state ()
1433 XMLNodeConstIterator niter;
1435 if (!deferred_state) {
1439 nlist = deferred_state->children();
1441 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1442 add_redirect_from_xml (**niter);
1445 delete deferred_state;
1450 Route::add_redirect_from_xml (const XMLNode& node)
1452 const XMLProperty *prop;
1454 if (node.name() == "Send") {
1458 boost::shared_ptr<Send> send (new Send (_session, node));
1459 add_redirect (send, this);
1462 catch (failed_constructor &err) {
1463 error << _("Send construction failed") << endmsg;
1467 } else if (node.name() == "Insert") {
1470 if ((prop = node.property ("type")) != 0) {
1472 boost::shared_ptr<Insert> insert;
1474 if (prop->value() == "ladspa" || prop->value() == "Ladspa" || prop->value() == "vst") {
1476 insert.reset (new PluginInsert(_session, node));
1478 } else if (prop->value() == "port") {
1481 insert.reset (new PortInsert (_session, node));
1485 error << string_compose(_("unknown Insert type \"%1\"; ignored"), prop->value()) << endmsg;
1488 add_redirect (insert, this);
1491 error << _("Insert XML node has no type property") << endmsg;
1495 catch (failed_constructor &err) {
1496 warning << _("insert could not be created. Ignored.") << endmsg;
1503 Route::set_state (const XMLNode& node)
1505 return _set_state (node, true);
1509 Route::_set_state (const XMLNode& node, bool call_base)
1512 XMLNodeConstIterator niter;
1514 XMLPropertyList plist;
1515 const XMLProperty *prop;
1517 if (node.name() != "Route"){
1518 error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
1522 if ((prop = node.property (X_("flags"))) != 0) {
1523 _flags = Flag (string_2_enum (prop->value(), _flags));
1528 if ((prop = node.property (X_("default-type"))) != 0) {
1529 _default_type = DataType(prop->value());
1530 assert(_default_type != DataType::NIL);
1533 if ((prop = node.property (X_("phase-invert"))) != 0) {
1534 set_phase_invert(prop->value()=="yes"?true:false, this);
1537 if ((prop = node.property (X_("active"))) != 0) {
1538 set_active (prop->value() == "yes");
1541 if ((prop = node.property (X_("muted"))) != 0) {
1542 bool yn = prop->value()=="yes"?true:false;
1544 /* force reset of mute status */
1548 mute_gain = desired_mute_gain;
1551 if ((prop = node.property (X_("soloed"))) != 0) {
1552 bool yn = prop->value()=="yes"?true:false;
1554 /* force reset of solo status */
1557 set_solo (yn, this);
1558 solo_gain = desired_solo_gain;
1561 if ((prop = node.property (X_("mute-affects-pre-fader"))) != 0) {
1562 _mute_affects_pre_fader = (prop->value()=="yes")?true:false;
1565 if ((prop = node.property (X_("mute-affects-post-fader"))) != 0) {
1566 _mute_affects_post_fader = (prop->value()=="yes")?true:false;
1569 if ((prop = node.property (X_("mute-affects-control-outs"))) != 0) {
1570 _mute_affects_control_outs = (prop->value()=="yes")?true:false;
1573 if ((prop = node.property (X_("mute-affects-main-outs"))) != 0) {
1574 _mute_affects_main_outs = (prop->value()=="yes")?true:false;
1577 if ((prop = node.property (X_("edit-group"))) != 0) {
1578 RouteGroup* edit_group = _session.edit_group_by_name(prop->value());
1579 if(edit_group == 0) {
1580 error << string_compose(_("Route %1: unknown edit group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
1582 set_edit_group(edit_group, this);
1586 if ((prop = node.property (X_("order-keys"))) != 0) {
1590 string::size_type colon, equal;
1591 string remaining = prop->value();
1593 while (remaining.length()) {
1595 if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
1596 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1599 if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) {
1600 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1603 set_order_key (remaining.substr (0, equal).c_str(), n);
1607 colon = remaining.find_first_of (':');
1609 if (colon != string::npos) {
1610 remaining = remaining.substr (colon+1);
1617 nlist = node.children();
1619 if (deferred_state) {
1620 delete deferred_state;
1623 deferred_state = new XMLNode(X_("deferred state"));
1625 /* set parent class properties before anything else */
1627 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1631 if (child->name() == IO::state_node_name && call_base) {
1633 IO::set_state (*child);
1638 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1642 if (child->name() == X_("Send")) {
1645 if (!IO::ports_legal) {
1647 deferred_state->add_child_copy (*child);
1650 add_redirect_from_xml (*child);
1653 } else if (child->name() == X_("Insert")) {
1655 if (!IO::ports_legal) {
1657 deferred_state->add_child_copy (*child);
1661 add_redirect_from_xml (*child);
1664 } else if (child->name() == X_("Automation")) {
1666 if ((prop = child->property (X_("path"))) != 0) {
1667 load_automation (prop->value());
1670 } else if (child->name() == X_("ControlOuts")) {
1672 string coutname = _name;
1673 coutname += _("[control]");
1675 _control_outs = new IO (_session, coutname);
1676 _control_outs->set_state (**(child->children().begin()));
1678 } else if (child->name() == X_("Comment")) {
1680 /* XXX this is a terrible API design in libxml++ */
1682 XMLNode *cmt = *(child->children().begin());
1683 _comment = cmt->content();
1685 } else if (child->name() == X_("extra")) {
1687 _extra_xml = new XMLNode (*child);
1689 } else if (child->name() == X_("controllable") && (prop = child->property("name")) != 0) {
1691 if (prop->value() == "solo") {
1692 _solo_control.set_state (*child);
1693 _session.add_controllable (&_solo_control);
1695 else if (prop->value() == "mute") {
1696 _mute_control.set_state (*child);
1697 _session.add_controllable (&_mute_control);
1700 else if (child->name() == X_("remote_control")) {
1701 if ((prop = child->property (X_("id"))) != 0) {
1703 sscanf (prop->value().c_str(), "%d", &x);
1704 set_remote_control_id (x);
1709 if ((prop = node.property (X_("mix-group"))) != 0) {
1710 RouteGroup* mix_group = _session.mix_group_by_name(prop->value());
1711 if (mix_group == 0) {
1712 error << string_compose(_("Route %1: unknown mix group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
1714 set_mix_group(mix_group, this);
1722 Route::curve_reallocate ()
1724 // _gain_automation_curve.finish_resize ();
1725 // _pan_automation_curve.finish_resize ();
1729 Route::silence (nframes_t nframes, nframes_t offset)
1733 IO::silence (nframes, offset);
1735 if (_control_outs) {
1736 _control_outs->silence (nframes, offset);
1740 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
1743 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1744 boost::shared_ptr<PluginInsert> pi;
1745 if (!_active && (pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
1746 // skip plugins, they don't need anything when we're not active
1750 (*i)->silence (nframes, offset);
1753 if (nframes == _session.get_block_size() && offset == 0) {
1763 Route::set_control_outs (const vector<string>& ports)
1765 Glib::Mutex::Lock lm (control_outs_lock);
1766 vector<string>::const_iterator i;
1768 if (_control_outs) {
1769 delete _control_outs;
1773 if (ports.empty()) {
1777 string coutname = _name;
1778 coutname += _("[control]");
1780 _control_outs = new IO (_session, coutname);
1782 /* our control outs need as many outputs as we
1783 have audio outputs. we track the changes in ::output_change_handler().
1786 _control_outs->ensure_io (ChanCount::ZERO, ChanCount(DataType::AUDIO, n_outputs().get(DataType::AUDIO)), true, this);
1792 Route::set_edit_group (RouteGroup *eg, void *src)
1795 if (eg == _edit_group) {
1800 _edit_group->remove (this);
1803 if ((_edit_group = eg) != 0) {
1804 _edit_group->add (this);
1807 _session.set_dirty ();
1808 edit_group_changed (src); /* EMIT SIGNAL */
1812 Route::drop_edit_group (void *src)
1815 _session.set_dirty ();
1816 edit_group_changed (src); /* EMIT SIGNAL */
1820 Route::set_mix_group (RouteGroup *mg, void *src)
1823 if (mg == _mix_group) {
1828 _mix_group->remove (this);
1831 if ((_mix_group = mg) != 0) {
1832 _mix_group->add (this);
1835 _session.set_dirty ();
1836 mix_group_changed (src); /* EMIT SIGNAL */
1840 Route::drop_mix_group (void *src)
1843 _session.set_dirty ();
1844 mix_group_changed (src); /* EMIT SIGNAL */
1848 Route::set_comment (string cmt, void *src)
1851 comment_changed (src);
1852 _session.set_dirty ();
1856 Route::feeds (boost::shared_ptr<Route> other)
1861 uint32_t no = self.n_outputs().get_total();
1862 uint32_t ni = other->n_inputs ().get_total();
1864 for (i = 0; i < no; ++i) {
1865 for (j = 0; j < ni; ++j) {
1866 if (self.output(i)->connected_to (other->input(j)->name())) {
1872 /* check Redirects which may also interconnect Routes */
1874 for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); r++) {
1876 no = (*r)->n_outputs().get_total();
1878 for (i = 0; i < no; ++i) {
1879 for (j = 0; j < ni; ++j) {
1880 if ((*r)->output(i)->connected_to (other->input (j)->name())) {
1887 /* check for control room outputs which may also interconnect Routes */
1889 if (_control_outs) {
1891 no = _control_outs->n_outputs().get_total();
1893 for (i = 0; i < no; ++i) {
1894 for (j = 0; j < ni; ++j) {
1895 if (_control_outs->output(i)->connected_to (other->input (j)->name())) {
1906 Route::set_mute_config (mute_type t, bool onoff, void *src)
1910 _mute_affects_pre_fader = onoff;
1911 pre_fader_changed(src); /* EMIT SIGNAL */
1915 _mute_affects_post_fader = onoff;
1916 post_fader_changed(src); /* EMIT SIGNAL */
1920 _mute_affects_control_outs = onoff;
1921 control_outs_changed(src); /* EMIT SIGNAL */
1925 _mute_affects_main_outs = onoff;
1926 main_outs_changed(src); /* EMIT SIGNAL */
1932 Route::get_mute_config (mute_type t)
1938 onoff = _mute_affects_pre_fader;
1941 onoff = _mute_affects_post_fader;
1944 onoff = _mute_affects_control_outs;
1947 onoff = _mute_affects_main_outs;
1955 Route::set_active (bool yn)
1958 active_changed(); /* EMIT SIGNAL */
1962 Route::handle_transport_stopped (bool abort_ignored, bool did_locate, bool can_flush_redirects)
1964 nframes_t now = _session.transport_frame();
1967 Glib::RWLock::ReaderLock lm (redirect_lock);
1970 automation_snapshot (now);
1973 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1975 if (Config->get_plugins_stop_with_transport() && can_flush_redirects) {
1976 (*i)->deactivate ();
1980 (*i)->transport_stopped (now);
1984 IO::transport_stopped (now);
1986 _roll_delay = _initial_delay;
1990 Route::input_change_handler (IOChange change, void *ignored)
1992 if (change & ConfigurationChanged) {
1993 reset_plugin_counts (0);
1998 Route::output_change_handler (IOChange change, void *ignored)
2000 if (change & ConfigurationChanged) {
2001 if (_control_outs) {
2002 _control_outs->ensure_io (ChanCount::ZERO, ChanCount(DataType::AUDIO, n_outputs().get(DataType::AUDIO)), true, this);
2005 reset_plugin_counts (0);
2010 Route::pans_required () const
2012 if (n_outputs().get(DataType::AUDIO) < 2) {
2016 return max (n_inputs ().get(DataType::AUDIO), static_cast<size_t>(redirect_max_outs.get(DataType::AUDIO)));
2020 Route::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset,
2021 bool session_state_changing, bool can_record, bool rec_monitors_input)
2023 if (n_outputs().get_total() == 0) {
2027 if (session_state_changing || !_active) {
2028 silence (nframes, offset);
2032 apply_gain_automation = false;
2034 if (n_inputs().get_total()) {
2035 passthru (start_frame, end_frame, nframes, offset, 0, false);
2037 silence (nframes, offset);
2044 Route::check_initial_delay (nframes_t nframes, nframes_t& offset, nframes_t& transport_frame)
2046 if (_roll_delay > nframes) {
2048 _roll_delay -= nframes;
2049 silence (nframes, offset);
2050 /* transport frame is not legal for caller to use */
2053 } else if (_roll_delay > 0) {
2055 nframes -= _roll_delay;
2057 silence (_roll_delay, offset);
2059 offset += _roll_delay;
2060 transport_frame += _roll_delay;
2069 Route::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, int declick,
2070 bool can_record, bool rec_monitors_input)
2073 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
2075 // automation snapshot can also be called from the non-rt context
2076 // and it uses the redirect list, so we take the lock out here
2077 automation_snapshot (_session.transport_frame());
2081 if ((n_outputs().get_total() == 0 && _redirects.empty()) || n_inputs().get_total() == 0 || !_active) {
2082 silence (nframes, offset);
2086 nframes_t unused = 0;
2088 if ((nframes = check_initial_delay (nframes, offset, unused)) == 0) {
2094 apply_gain_automation = false;
2097 Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK);
2099 if (am.locked() && _session.transport_rolling()) {
2101 if (gain_automation_playback()) {
2102 apply_gain_automation = _gain_automation_curve.rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes);
2107 passthru (start_frame, end_frame, nframes, offset, declick, false);
2113 Route::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset,
2114 bool can_record, bool rec_monitors_input)
2116 silence (nframes, offset);
2121 Route::toggle_monitor_input ()
2123 for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
2124 i->ensure_monitor_input( ! i->monitoring_input());
2129 Route::has_external_redirects () const
2131 boost::shared_ptr<const PortInsert> pi;
2133 for (RedirectList::const_iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2134 if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*i)) != 0) {
2136 for (PortSet::const_iterator port = pi->outputs().begin();
2137 port != pi->outputs().end(); ++port) {
2139 string port_name = port->name();
2140 string client_name = port_name.substr (0, port_name.find(':'));
2142 /* only say "yes" if the redirect is actually in use */
2144 if (client_name != "ardour" && pi->active()) {
2155 Route::flush_redirects ()
2157 /* XXX shouldn't really try to take this lock, since
2158 this is called from the RT audio thread.
2161 Glib::RWLock::ReaderLock lm (redirect_lock);
2163 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2164 (*i)->deactivate ();
2170 Route::set_meter_point (MeterPoint p, void *src)
2172 if (_meter_point != p) {
2174 meter_change (src); /* EMIT SIGNAL */
2175 _session.set_dirty ();
2180 Route::update_total_latency ()
2184 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2185 if ((*i)->active ()) {
2186 _own_latency += (*i)->latency ();
2190 set_port_latency (_own_latency);
2192 /* this (virtual) function is used for pure Routes,
2193 not derived classes like AudioTrack. this means
2194 that the data processed here comes from an input
2195 port, not prerecorded material, and therefore we
2196 have to take into account any input latency.
2199 _own_latency += input_latency ();
2201 return _own_latency;
2205 Route::set_latency_delay (nframes_t longest_session_latency)
2207 _initial_delay = longest_session_latency - _own_latency;
2209 if (_session.transport_stopped()) {
2210 _roll_delay = _initial_delay;
2215 Route::automation_snapshot (nframes_t now)
2217 IO::automation_snapshot (now);
2219 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2220 (*i)->automation_snapshot (now);
2224 Route::ToggleControllable::ToggleControllable (std::string name, Route& s, ToggleType tp)
2225 : Controllable (name), route (s), type(tp)
2231 Route::ToggleControllable::set_value (float val)
2233 bool bval = ((val >= 0.5f) ? true: false);
2237 route.set_mute (bval, this);
2240 route.set_solo (bval, this);
2248 Route::ToggleControllable::get_value (void) const
2254 val = route.muted() ? 1.0f : 0.0f;
2257 val = route.soloed() ? 1.0f : 0.0f;
2267 Route::set_block_size (nframes_t nframes)
2269 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2270 (*i)->set_block_size (nframes);
2275 Route::redirect_active_proxy (Redirect* ignored, void* ignored_src)
2277 _session.update_latency_compensation (false, false);
2281 Route::protect_automation ()
2283 switch (gain_automation_state()) {
2285 set_gain_automation_state (Off);
2287 set_gain_automation_state (Play);
2293 switch (panner().automation_state ()) {
2295 panner().set_automation_state (Off);
2298 panner().set_automation_state (Play);
2304 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2305 boost::shared_ptr<PluginInsert> pi;
2306 if ((pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
2307 pi->protect_automation ();
2313 Route::set_pending_declick (int declick)
2316 /* this call is not allowed to turn off a pending declick unless "force" is true */
2318 _pending_declick = declick;
2320 // cerr << _name << ": after setting to " << declick << " pending declick = " << _pending_declick << endl;
2322 _pending_declick = 0;