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/amp.h>
45 #include <ardour/meter.h>
46 #include <ardour/buffer_set.h>
50 using namespace ARDOUR;
53 uint32_t Route::order_key_cnt = 0;
56 Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg, DataType default_type)
57 : IO (sess, name, input_min, input_max, output_min, output_max, default_type),
59 _solo_control (X_("solo"), *this, ToggleControllable::SoloControl),
60 _mute_control (X_("mute"), *this, ToggleControllable::MuteControl)
65 Route::Route (Session& sess, const XMLNode& node, DataType default_type)
66 : IO (sess, *node.child ("IO"), default_type),
67 _solo_control (X_("solo"), *this, ToggleControllable::SoloControl),
68 _mute_control (X_("mute"), *this, ToggleControllable::MuteControl)
71 _set_state (node, false);
77 redirect_max_outs.reset();
81 _phase_invert = false;
82 order_keys[strdup (N_("signal"))] = order_key_cnt++;
85 _meter_point = MeterPostFader;
89 _have_internal_generator = false;
91 _pending_declick = true;
92 _remote_control_id = 0;
97 _mute_affects_pre_fader = Config->get_mute_affects_pre_fader();
98 _mute_affects_post_fader = Config->get_mute_affects_post_fader();
99 _mute_affects_control_outs = Config->get_mute_affects_control_outs();
100 _mute_affects_main_outs = Config->get_mute_affects_main_outs();
103 desired_solo_gain = 1.0;
105 desired_mute_gain = 1.0;
109 input_changed.connect (mem_fun (this, &Route::input_change_handler));
110 output_changed.connect (mem_fun (this, &Route::output_change_handler));
115 clear_redirects (PreFader, this);
116 clear_redirects (PostFader, this);
118 for (OrderKeys::iterator i = order_keys.begin(); i != order_keys.end(); ++i) {
119 free ((void*)(i->first));
123 delete _control_outs;
128 Route::set_remote_control_id (uint32_t id)
130 if (id != _remote_control_id) {
131 _remote_control_id = id;
132 RemoteControlIDChanged ();
137 Route::remote_control_id() const
139 return _remote_control_id;
143 Route::order_key (const char* name) const
145 OrderKeys::const_iterator i;
147 for (i = order_keys.begin(); i != order_keys.end(); ++i) {
148 if (!strcmp (name, i->first)) {
157 Route::set_order_key (const char* name, long n)
159 order_keys[strdup(name)] = n;
160 _session.set_dirty ();
164 Route::inc_gain (gain_t fraction, void *src)
166 IO::inc_gain (fraction, src);
170 Route::set_gain (gain_t val, void *src)
172 if (src != 0 && _mix_group && src != _mix_group && _mix_group->is_active()) {
174 if (_mix_group->is_relative()) {
177 gain_t usable_gain = gain();
178 if (usable_gain < 0.000001f) {
179 usable_gain=0.000001f;
183 if (delta < 0.000001f) {
187 delta -= usable_gain;
189 if (delta == 0.0f) return;
191 gain_t factor = delta / usable_gain;
194 factor = _mix_group->get_max_factor(factor);
195 if (factor == 0.0f) {
200 factor = _mix_group->get_min_factor(factor);
201 if (factor == 0.0f) {
207 _mix_group->apply (&Route::inc_gain, factor, _mix_group);
211 _mix_group->apply (&Route::set_gain, val, _mix_group);
221 IO::set_gain (val, src);
224 /** Process this route for one (sub) cycle (process thread)
226 * @param bufs Scratch buffers to use for the signal path
227 * @param start_frame Initial transport frame
228 * @param end_frame Final transport frame
229 * @param nframes Number of frames to output (to ports)
230 * @param offset Output offset (of port buffers, for split cycles)
232 * Note that (end_frame - start_frame) may not be equal to nframes when the
233 * transport speed isn't 1.0 (eg varispeed).
236 Route::process_output_buffers (BufferSet& bufs,
237 nframes_t start_frame, nframes_t end_frame,
238 nframes_t nframes, nframes_t offset, bool with_redirects, int declick,
241 // This is definitely very audio-only for now
242 assert(_default_type == DataType::AUDIO);
244 RedirectList::iterator i;
245 bool post_fader_work = false;
246 bool mute_declick_applied = false;
252 gain_t* gab = _session.gain_automation_buffer();
254 switch (Config->get_monitoring_model()) {
255 case HardwareMonitoring:
256 case ExternalMonitoring:
263 declick = _pending_declick;
266 Glib::Mutex::Lock cm (control_outs_lock, Glib::TRY_LOCK);
276 Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK);
279 dmg = desired_mute_gain;
280 dsg = desired_solo_gain;
289 /* ----------------------------------------------------------------------------------------------------
290 GLOBAL DECLICK (for transport changes etc.)
291 -------------------------------------------------------------------------------------------------- */
294 Amp::run (bufs, nframes, 0.0, 1.0, false);
295 _pending_declick = 0;
296 } else if (declick < 0) {
297 Amp::run (bufs, nframes, 1.0, 0.0, false);
298 _pending_declick = 0;
301 /* no global declick */
303 if (solo_gain != dsg) {
304 Amp::run (bufs, nframes, solo_gain, dsg, false);
310 /* ----------------------------------------------------------------------------------------------------
311 INPUT METERING & MONITORING
312 -------------------------------------------------------------------------------------------------- */
314 if (meter && (_meter_point == MeterInput)) {
315 _meter->run(bufs, nframes);
318 if (!_soloed && _mute_affects_pre_fader && (mute_gain != dmg)) {
319 Amp::run (bufs, nframes, mute_gain, dmg, false);
321 mute_declick_applied = true;
324 if ((_meter_point == MeterInput) && co) {
326 solo_audible = dsg > 0;
327 mute_audible = dmg > 0;// || !_mute_affects_pre_fader;
329 if ( // muted by solo of another track
333 // muted by mute of this track
337 // rec-enabled but not s/w monitoring
339 // TODO: this is probably wrong
341 (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording()))
345 co->silence (nframes, offset);
349 co->deliver_output (bufs, start_frame, end_frame, nframes, offset);
354 /* ---------------------------------------------------------------------------------------------------
356 -------------------------------------------------------------------------------------------------- */
358 /* FIXME: Somewhere in these loops is where bufs.count() should go from n_inputs() to redirect_max_outs()
359 * (if they differ). Something explicit needs to be done here to make sure the list of redirects will
360 * give us what we need (possibly by inserting transparent 'translators' into the list to make it work) */
362 if (with_redirects) {
363 Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK);
365 if (mute_gain > 0 || !_mute_affects_pre_fader) {
366 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
367 switch ((*i)->placement()) {
369 (*i)->run (bufs, start_frame, end_frame, nframes, offset);
372 post_fader_work = true;
377 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
378 switch ((*i)->placement()) {
380 (*i)->silence (nframes, offset);
383 post_fader_work = true;
391 // FIXME: for now, just hope the redirects list did what it was supposed to
392 bufs.set_count(n_process_buffers());
395 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_post_fader) {
396 Amp::run (bufs, nframes, mute_gain, dmg, false);
398 mute_declick_applied = true;
401 /* ----------------------------------------------------------------------------------------------------
402 PRE-FADER METERING & MONITORING
403 -------------------------------------------------------------------------------------------------- */
405 if (meter && (_meter_point == MeterPreFader)) {
406 _meter->run(bufs, nframes);
410 if ((_meter_point == MeterPreFader) && co) {
412 solo_audible = dsg > 0;
413 mute_audible = dmg > 0 || !_mute_affects_pre_fader;
415 if ( // muted by solo of another track
419 // muted by mute of this track
423 // rec-enabled but not s/w monitoring
425 (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording()))
429 co->silence (nframes, offset);
433 co->deliver_output (bufs, start_frame, end_frame, nframes, offset);
438 /* ----------------------------------------------------------------------------------------------------
440 -------------------------------------------------------------------------------------------------- */
442 /* if not recording or recording and requiring any monitor signal, then apply gain */
444 if ( // not recording
446 !(record_enabled() && _session.actively_recording()) ||
450 // h/w monitoring not in use
452 (!Config->get_monitoring_model() == HardwareMonitoring &&
454 // AND software monitoring required
456 Config->get_monitoring_model() == SoftwareMonitoring)) {
458 if (apply_gain_automation) {
461 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
462 Sample* const sp = i->data(nframes);
464 for (nframes_t nx = 0; nx < nframes; ++nx) {
469 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
470 Sample* const sp = i->data(nframes);
472 for (nframes_t nx = 0; nx < nframes; ++nx) {
478 if (apply_gain_automation && _session.transport_rolling() && nframes > 0) {
479 _effective_gain = gab[nframes-1];
484 /* manual (scalar) gain */
488 Amp::run (bufs, nframes, _gain, dg, _phase_invert);
491 } else if (_gain != 0 && (_phase_invert || _gain != 1.0)) {
493 /* no need to interpolate current gain value,
494 but its non-unity, so apply it. if the gain
495 is zero, do nothing because we'll ship silence
507 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
508 Sample* const sp = i->data(nframes);
509 apply_gain_to_buffer(sp,nframes,this_gain);
512 } else if (_gain == 0) {
513 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
521 /* actively recording, no monitoring required; leave buffers as-is to save CPU cycles */
525 /* ----------------------------------------------------------------------------------------------------
527 -------------------------------------------------------------------------------------------------- */
529 /* note that post_fader_work cannot be true unless with_redirects was also true, so don't test both */
531 if (post_fader_work) {
533 Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK);
535 if (mute_gain > 0 || !_mute_affects_post_fader) {
536 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
537 switch ((*i)->placement()) {
541 (*i)->run (bufs, start_frame, end_frame, nframes, offset);
546 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
547 switch ((*i)->placement()) {
551 (*i)->silence (nframes, offset);
559 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_control_outs) {
560 Amp::run (bufs, nframes, mute_gain, dmg, false);
562 mute_declick_applied = true;
565 /* ----------------------------------------------------------------------------------------------------
567 -------------------------------------------------------------------------------------------------- */
569 if ((_meter_point == MeterPostFader) && co) {
571 solo_audible = solo_gain > 0;
572 mute_audible = dmg > 0 || !_mute_affects_control_outs;
574 if ( // silent anyway
576 (_gain == 0 && !apply_gain_automation) ||
578 // muted by solo of another track
582 // muted by mute of this track
586 // recording but not s/w monitoring
588 (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording()))
592 co->silence (nframes, offset);
596 co->deliver_output (bufs, start_frame, end_frame, nframes, offset);
600 /* ----------------------------------------------------------------------
602 ----------------------------------------------------------------------*/
604 if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_main_outs) {
605 Amp::run (bufs, nframes, mute_gain, dmg, false);
607 mute_declick_applied = true;
610 /* ----------------------------------------------------------------------------------------------------
612 -------------------------------------------------------------------------------------------------- */
614 solo_audible = dsg > 0;
615 mute_audible = dmg > 0 || !_mute_affects_main_outs;
617 if (n_outputs().get(_default_type) == 0) {
621 } else if (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording())) {
623 IO::silence (nframes, offset);
627 if ( // silent anyway
629 (_gain == 0 && !apply_gain_automation) ||
631 // muted by solo of another track, but not using control outs for solo
633 (!solo_audible && (Config->get_solo_model() != SoloBus)) ||
635 // muted by mute of this track
641 /* don't use Route::silence() here, because that causes
642 all outputs (sends, port inserts, etc. to be silent).
645 if (_meter_point == MeterPostFader) {
646 peak_meter().reset();
649 IO::silence (nframes, offset);
653 deliver_output(bufs, start_frame, end_frame, nframes, offset);
659 /* ----------------------------------------------------------------------------------------------------
661 -------------------------------------------------------------------------------------------------- */
663 if (meter && (_meter_point == MeterPostFader)) {
664 if ((_gain == 0 && !apply_gain_automation) || dmg == 0) {
667 _meter->run(output_buffers(), nframes, offset);
673 Route::n_process_buffers ()
675 return max (n_inputs(), redirect_max_outs);
679 Route::passthru (nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset, int declick, bool meter_first)
681 BufferSet& bufs = _session.get_scratch_buffers(n_process_buffers());
685 collect_input (bufs, nframes, offset);
687 #define meter_stream meter_first
690 _meter->run(bufs, nframes);
691 meter_stream = false;
696 process_output_buffers (bufs, start_frame, end_frame, nframes, offset, true, declick, meter_stream);
702 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)
704 process_output_buffers (_session.get_silent_buffers (n_process_buffers()), start_frame, end_frame, nframes, offset, true, declick, meter);
708 Route::set_solo (bool yn, void *src)
714 if (_mix_group && src != _mix_group && _mix_group->is_active()) {
715 _mix_group->apply (&Route::set_solo, yn, _mix_group);
721 solo_changed (src); /* EMIT SIGNAL */
722 _solo_control.Changed (); /* EMIT SIGNAL */
727 Route::set_solo_mute (bool yn)
729 Glib::Mutex::Lock lm (declick_lock);
731 /* Called by Session in response to another Route being soloed.
734 desired_solo_gain = (yn?0.0:1.0);
738 Route::set_solo_safe (bool yn, void *src)
740 if (_solo_safe != yn) {
742 solo_safe_changed (src); /* EMIT SIGNAL */
747 Route::set_mute (bool yn, void *src)
750 if (_mix_group && src != _mix_group && _mix_group->is_active()) {
751 _mix_group->apply (&Route::set_mute, yn, _mix_group);
757 mute_changed (src); /* EMIT SIGNAL */
759 _mute_control.Changed (); /* EMIT SIGNAL */
761 Glib::Mutex::Lock lm (declick_lock);
762 desired_mute_gain = (yn?0.0f:1.0f);
767 Route::add_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
769 ChanCount old_rmo = redirect_max_outs;
771 if (!_session.engine().connected()) {
776 Glib::RWLock::WriterLock lm (redirect_lock);
778 boost::shared_ptr<PluginInsert> pi;
779 boost::shared_ptr<PortInsert> porti;
781 redirect->set_default_type(_default_type);
783 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(redirect)) != 0) {
786 if (pi->input_streams() == ChanCount::ZERO) {
787 /* generator plugin */
788 _have_internal_generator = true;
791 } else if ((porti = boost::dynamic_pointer_cast<PortInsert>(redirect)) != 0) {
793 /* force new port inserts to start out with an i/o configuration
794 that matches this route's i/o configuration.
796 the "inputs" for the port are supposed to match the output
799 the "outputs" of the route should match the inputs of this
800 route. XXX shouldn't they match the number of active signal
801 streams at the point of insertion?
803 // FIXME: (yes, they should)
805 porti->ensure_io (n_outputs (), n_inputs(), false, this);
808 // Ensure peak vector sizes before the plugin is activated
809 ChanCount potential_max_streams = max(redirect->input_streams(), redirect->output_streams());
810 _meter->setup(potential_max_streams);
812 _redirects.push_back (redirect);
814 if (_reset_plugin_counts (err_streams)) {
815 _redirects.pop_back ();
816 _reset_plugin_counts (0); // it worked before we tried to add it ...
820 redirect->activate ();
821 redirect->active_changed.connect (mem_fun (*this, &Route::redirect_active_proxy));
824 if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
829 redirects_changed (src); /* EMIT SIGNAL */
834 Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_streams)
836 ChanCount old_rmo = redirect_max_outs;
838 if (!_session.engine().connected()) {
843 Glib::RWLock::WriterLock lm (redirect_lock);
845 RedirectList::iterator existing_end = _redirects.end();
848 ChanCount potential_max_streams;
850 for (RedirectList::const_iterator i = others.begin(); i != others.end(); ++i) {
852 boost::shared_ptr<PluginInsert> pi;
854 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
857 ChanCount m = max(pi->input_streams(), pi->output_streams());
858 if (m > potential_max_streams)
859 potential_max_streams = m;
862 // Ensure peak vector sizes before the plugin is activated
863 _meter->setup(potential_max_streams);
865 _redirects.push_back (*i);
867 if (_reset_plugin_counts (err_streams)) {
869 _redirects.erase (existing_end, _redirects.end());
870 _reset_plugin_counts (0); // it worked before we tried to add it ...
875 (*i)->active_changed.connect (mem_fun (*this, &Route::redirect_active_proxy));
879 if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
883 redirects_changed (src); /* EMIT SIGNAL */
887 /** Remove redirects with a given placement.
888 * @param p Placement of redirects to remove.
891 Route::clear_redirects (Placement p, void *src)
893 const ChanCount old_rmo = redirect_max_outs;
895 if (!_session.engine().connected()) {
900 Glib::RWLock::WriterLock lm (redirect_lock);
901 RedirectList new_list;
903 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
904 if ((*i)->placement() == p) {
905 /* it's the placement we want to get rid of */
906 (*i)->drop_references ();
908 /* it's a different placement, so keep it */
909 new_list.push_back (*i);
913 _redirects = new_list;
916 /* FIXME: can't see how this test can ever fire */
917 if (redirect_max_outs != old_rmo) {
921 redirect_max_outs.reset();
922 _have_internal_generator = false;
923 redirects_changed (src); /* EMIT SIGNAL */
927 Route::remove_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
929 ChanCount old_rmo = redirect_max_outs;
931 if (!_session.engine().connected()) {
935 redirect_max_outs.reset();
938 Glib::RWLock::WriterLock lm (redirect_lock);
939 RedirectList::iterator i;
940 bool removed = false;
942 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
943 if (*i == redirect) {
945 RedirectList::iterator tmp;
947 /* move along, see failure case for reset_plugin_counts()
948 where we may need to reinsert the redirect.
954 /* stop redirects that send signals to JACK ports
955 from causing noise as a result of no longer being
959 boost::shared_ptr<Send> send;
960 boost::shared_ptr<PortInsert> port_insert;
962 if ((send = boost::dynamic_pointer_cast<Send> (*i)) != 0) {
963 send->disconnect_inputs (this);
964 send->disconnect_outputs (this);
965 } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (*i)) != 0) {
966 port_insert->disconnect_inputs (this);
967 port_insert->disconnect_outputs (this);
970 _redirects.erase (i);
983 if (_reset_plugin_counts (err_streams)) {
984 /* get back to where we where */
985 _redirects.insert (i, redirect);
986 /* we know this will work, because it worked before :) */
987 _reset_plugin_counts (0);
993 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
994 boost::shared_ptr<PluginInsert> pi;
996 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
997 if (pi->is_generator()) {
1003 _have_internal_generator = foo;
1006 if (old_rmo != redirect_max_outs) {
1010 redirect->drop_references ();
1012 redirects_changed (src); /* EMIT SIGNAL */
1017 Route::reset_plugin_counts (uint32_t* lpc)
1019 Glib::RWLock::WriterLock lm (redirect_lock);
1020 return _reset_plugin_counts (lpc);
1025 Route::_reset_plugin_counts (uint32_t* err_streams)
1027 RedirectList::iterator r;
1030 map<Placement,list<InsertCount> > insert_map;
1031 nframes_t initial_streams;
1033 redirect_max_outs.reset();
1037 /* divide inserts up by placement so we get the signal flow
1038 properly modelled. we need to do this because the _redirects
1039 list is not sorted by placement, and because other reasons may
1040 exist now or in the future for this separate treatment.
1043 for (r = _redirects.begin(); r != _redirects.end(); ++r) {
1045 boost::shared_ptr<Insert> insert;
1047 /* do this here in case we bomb out before we get to the end of
1051 redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs);
1053 if ((insert = boost::dynamic_pointer_cast<Insert>(*r)) != 0) {
1055 insert_map[insert->placement()].push_back (InsertCount (insert));
1057 /* reset plugin counts back to one for now so
1058 that we have a predictable, controlled
1059 state to try to configure.
1062 boost::shared_ptr<PluginInsert> pi;
1064 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(insert)) != 0) {
1068 } else if (boost::dynamic_pointer_cast<Send> (*r) != 0) {
1081 /* Now process each placement in order, checking to see if we
1082 can really do what has been requested.
1087 if (check_some_plugin_counts (insert_map[PreFader], n_inputs ().get(_default_type), err_streams)) {
1091 /* figure out the streams that will feed into PreFader */
1093 if (!insert_map[PreFader].empty()) {
1094 InsertCount& ic (insert_map[PreFader].back());
1095 initial_streams = ic.insert->compute_output_streams (ic.cnt);
1097 initial_streams = n_inputs ().get(_default_type);
1102 if (check_some_plugin_counts (insert_map[PostFader], initial_streams, err_streams)) {
1106 /* OK, everything can be set up correctly, so lets do it */
1108 apply_some_plugin_counts (insert_map[PreFader]);
1109 apply_some_plugin_counts (insert_map[PostFader]);
1111 /* recompute max outs of any redirect */
1115 redirect_max_outs.reset();
1116 RedirectList::iterator prev = _redirects.end();
1118 for (r = _redirects.begin(); r != _redirects.end(); prev = r, ++r) {
1119 boost::shared_ptr<Send> s;
1121 if ((s = boost::dynamic_pointer_cast<Send> (*r)) != 0) {
1122 if (r == _redirects.begin()) {
1123 s->expect_inputs (n_inputs());
1125 s->expect_inputs ((*prev)->output_streams());
1130 /* don't pay any attention to send output configuration, since it doesn't
1134 redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs);
1145 Route::apply_some_plugin_counts (list<InsertCount>& iclist)
1147 list<InsertCount>::iterator i;
1149 for (i = iclist.begin(); i != iclist.end(); ++i) {
1151 if ((*i).insert->configure_io ((*i).cnt, (*i).in, (*i).out)) {
1154 /* make sure that however many we have, they are all active */
1155 (*i).insert->activate ();
1162 Route::check_some_plugin_counts (list<InsertCount>& iclist, int32_t required_inputs, uint32_t* err_streams)
1164 list<InsertCount>::iterator i;
1166 for (i = iclist.begin(); i != iclist.end(); ++i) {
1168 if (((*i).cnt = (*i).insert->can_support_input_configuration (required_inputs)) < 0) {
1170 *err_streams = required_inputs;
1175 (*i).in = required_inputs;
1176 (*i).out = (*i).insert->compute_output_streams ((*i).cnt);
1178 required_inputs = (*i).out;
1185 Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_streams)
1187 ChanCount old_rmo = redirect_max_outs;
1193 RedirectList to_be_deleted;
1196 Glib::RWLock::WriterLock lm (redirect_lock);
1197 RedirectList::iterator tmp;
1198 RedirectList the_copy;
1200 the_copy = _redirects;
1202 /* remove all relevant redirects */
1204 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ) {
1208 if ((*i)->placement() == placement) {
1209 to_be_deleted.push_back (*i);
1210 _redirects.erase (i);
1216 /* now copy the relevant ones from "other" */
1218 for (RedirectList::const_iterator i = other._redirects.begin(); i != other._redirects.end(); ++i) {
1219 if ((*i)->placement() == placement) {
1220 _redirects.push_back (Redirect::clone (*i));
1224 /* reset plugin stream handling */
1226 if (_reset_plugin_counts (err_streams)) {
1228 /* FAILED COPY ATTEMPT: we have to restore order */
1230 /* delete all cloned redirects */
1232 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ) {
1237 if ((*i)->placement() == placement) {
1238 _redirects.erase (i);
1244 /* restore the natural order */
1246 _redirects = the_copy;
1247 redirect_max_outs = old_rmo;
1249 /* we failed, even though things are OK again */
1255 /* SUCCESSFUL COPY ATTEMPT: delete the redirects we removed pre-copy */
1256 to_be_deleted.clear ();
1260 if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
1264 redirects_changed (this); /* EMIT SIGNAL */
1269 Route::all_redirects_flip ()
1271 Glib::RWLock::ReaderLock lm (redirect_lock);
1273 if (_redirects.empty()) {
1277 bool first_is_on = _redirects.front()->active();
1279 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1280 (*i)->set_active (!first_is_on, this);
1284 /** Set all redirects with a given placement to a given active state.
1285 * @param p Placement of redirects to change.
1286 * @param state New active state for those redirects.
1289 Route::all_redirects_active (Placement p, bool state)
1291 Glib::RWLock::ReaderLock lm (redirect_lock);
1293 if (_redirects.empty()) {
1297 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1298 if ((*i)->placement() == p) {
1299 (*i)->set_active (state, this);
1304 struct RedirectSorter {
1305 bool operator() (boost::shared_ptr<const Redirect> a, boost::shared_ptr<const Redirect> b) {
1306 return a->sort_key() < b->sort_key();
1311 Route::sort_redirects (uint32_t* err_streams)
1314 RedirectSorter comparator;
1315 Glib::RWLock::WriterLock lm (redirect_lock);
1316 ChanCount old_rmo = redirect_max_outs;
1318 /* the sweet power of C++ ... */
1320 RedirectList as_it_was_before = _redirects;
1322 _redirects.sort (comparator);
1324 if (_reset_plugin_counts (err_streams)) {
1325 _redirects = as_it_was_before;
1326 redirect_max_outs = old_rmo;
1332 redirects_changed (this); /* EMIT SIGNAL */
1344 Route::get_template()
1346 return state(false);
1350 Route::state(bool full_state)
1352 XMLNode *node = new XMLNode("Route");
1353 RedirectList:: iterator i;
1357 node->add_property("flags", enum_2_string (_flags));
1360 node->add_property("default-type", _default_type.to_string());
1362 node->add_property("active", _active?"yes":"no");
1363 node->add_property("muted", _muted?"yes":"no");
1364 node->add_property("soloed", _soloed?"yes":"no");
1365 node->add_property("phase-invert", _phase_invert?"yes":"no");
1366 node->add_property("mute-affects-pre-fader", _mute_affects_pre_fader?"yes":"no");
1367 node->add_property("mute-affects-post-fader", _mute_affects_post_fader?"yes":"no");
1368 node->add_property("mute-affects-control-outs", _mute_affects_control_outs?"yes":"no");
1369 node->add_property("mute-affects-main-outs", _mute_affects_main_outs?"yes":"no");
1372 node->add_property("edit-group", _edit_group->name());
1375 node->add_property("mix-group", _mix_group->name());
1378 string order_string;
1379 OrderKeys::iterator x = order_keys.begin();
1381 while (x != order_keys.end()) {
1382 order_string += string ((*x).first);
1383 order_string += '=';
1384 snprintf (buf, sizeof(buf), "%ld", (*x).second);
1385 order_string += buf;
1389 if (x == order_keys.end()) {
1393 order_string += ':';
1395 node->add_property ("order-keys", order_string);
1397 node->add_child_nocopy (IO::state (full_state));
1398 node->add_child_nocopy (_solo_control.get_state ());
1399 node->add_child_nocopy (_mute_control.get_state ());
1401 XMLNode* remote_control_node = new XMLNode (X_("remote_control"));
1402 snprintf (buf, sizeof (buf), "%d", _remote_control_id);
1403 remote_control_node->add_property (X_("id"), buf);
1404 node->add_child_nocopy (*remote_control_node);
1406 if (_control_outs) {
1407 XMLNode* cnode = new XMLNode (X_("ControlOuts"));
1408 cnode->add_child_nocopy (_control_outs->state (full_state));
1409 node->add_child_nocopy (*cnode);
1412 if (_comment.length()) {
1413 XMLNode *cmt = node->add_child ("Comment");
1414 cmt->add_content (_comment);
1417 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
1418 node->add_child_nocopy((*i)->state (full_state));
1422 node->add_child_copy (*_extra_xml);
1429 Route::set_deferred_state ()
1432 XMLNodeConstIterator niter;
1434 if (!deferred_state) {
1438 nlist = deferred_state->children();
1440 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1441 add_redirect_from_xml (**niter);
1444 delete deferred_state;
1449 Route::add_redirect_from_xml (const XMLNode& node)
1451 const XMLProperty *prop;
1453 if (node.name() == "Send") {
1457 boost::shared_ptr<Send> send (new Send (_session, node));
1458 add_redirect (send, this);
1461 catch (failed_constructor &err) {
1462 error << _("Send construction failed") << endmsg;
1466 } else if (node.name() == "Insert") {
1469 if ((prop = node.property ("type")) != 0) {
1471 boost::shared_ptr<Insert> insert;
1473 if (prop->value() == "ladspa" || prop->value() == "Ladspa" || prop->value() == "vst") {
1475 insert.reset (new PluginInsert(_session, node));
1477 } else if (prop->value() == "port") {
1480 insert.reset (new PortInsert (_session, node));
1484 error << string_compose(_("unknown Insert type \"%1\"; ignored"), prop->value()) << endmsg;
1487 add_redirect (insert, this);
1490 error << _("Insert XML node has no type property") << endmsg;
1494 catch (failed_constructor &err) {
1495 warning << _("insert could not be created. Ignored.") << endmsg;
1502 Route::set_state (const XMLNode& node)
1504 return _set_state (node, true);
1508 Route::_set_state (const XMLNode& node, bool call_base)
1511 XMLNodeConstIterator niter;
1513 XMLPropertyList plist;
1514 const XMLProperty *prop;
1516 if (node.name() != "Route"){
1517 error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
1521 if ((prop = node.property (X_("flags"))) != 0) {
1522 _flags = Flag (string_2_enum (prop->value(), _flags));
1527 if ((prop = node.property (X_("default-type"))) != 0) {
1528 _default_type = DataType(prop->value());
1529 assert(_default_type != DataType::NIL);
1532 if ((prop = node.property (X_("phase-invert"))) != 0) {
1533 set_phase_invert(prop->value()=="yes"?true:false, this);
1536 if ((prop = node.property (X_("active"))) != 0) {
1537 set_active (prop->value() == "yes");
1540 if ((prop = node.property (X_("muted"))) != 0) {
1541 bool yn = prop->value()=="yes"?true:false;
1543 /* force reset of mute status */
1547 mute_gain = desired_mute_gain;
1550 if ((prop = node.property (X_("soloed"))) != 0) {
1551 bool yn = prop->value()=="yes"?true:false;
1553 /* force reset of solo status */
1556 set_solo (yn, this);
1557 solo_gain = desired_solo_gain;
1560 if ((prop = node.property (X_("mute-affects-pre-fader"))) != 0) {
1561 _mute_affects_pre_fader = (prop->value()=="yes")?true:false;
1564 if ((prop = node.property (X_("mute-affects-post-fader"))) != 0) {
1565 _mute_affects_post_fader = (prop->value()=="yes")?true:false;
1568 if ((prop = node.property (X_("mute-affects-control-outs"))) != 0) {
1569 _mute_affects_control_outs = (prop->value()=="yes")?true:false;
1572 if ((prop = node.property (X_("mute-affects-main-outs"))) != 0) {
1573 _mute_affects_main_outs = (prop->value()=="yes")?true:false;
1576 if ((prop = node.property (X_("edit-group"))) != 0) {
1577 RouteGroup* edit_group = _session.edit_group_by_name(prop->value());
1578 if(edit_group == 0) {
1579 error << string_compose(_("Route %1: unknown edit group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
1581 set_edit_group(edit_group, this);
1585 if ((prop = node.property (X_("order-keys"))) != 0) {
1589 string::size_type colon, equal;
1590 string remaining = prop->value();
1592 while (remaining.length()) {
1594 if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
1595 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1598 if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) {
1599 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1602 set_order_key (remaining.substr (0, equal).c_str(), n);
1606 colon = remaining.find_first_of (':');
1608 if (colon != string::npos) {
1609 remaining = remaining.substr (colon+1);
1616 nlist = node.children();
1618 if (deferred_state) {
1619 delete deferred_state;
1622 deferred_state = new XMLNode(X_("deferred state"));
1624 /* set parent class properties before anything else */
1626 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1630 if (child->name() == IO::state_node_name && call_base) {
1632 IO::set_state (*child);
1637 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1641 if (child->name() == X_("Send")) {
1644 if (!IO::ports_legal) {
1646 deferred_state->add_child_copy (*child);
1649 add_redirect_from_xml (*child);
1652 } else if (child->name() == X_("Insert")) {
1654 if (!IO::ports_legal) {
1656 deferred_state->add_child_copy (*child);
1660 add_redirect_from_xml (*child);
1663 } else if (child->name() == X_("Automation")) {
1665 if ((prop = child->property (X_("path"))) != 0) {
1666 load_automation (prop->value());
1669 } else if (child->name() == X_("ControlOuts")) {
1671 string coutname = _name;
1672 coutname += _("[control]");
1674 _control_outs = new IO (_session, coutname);
1675 _control_outs->set_state (**(child->children().begin()));
1677 } else if (child->name() == X_("Comment")) {
1679 /* XXX this is a terrible API design in libxml++ */
1681 XMLNode *cmt = *(child->children().begin());
1682 _comment = cmt->content();
1684 } else if (child->name() == X_("extra")) {
1686 _extra_xml = new XMLNode (*child);
1688 } else if (child->name() == X_("controllable") && (prop = child->property("name")) != 0) {
1690 if (prop->value() == "solo") {
1691 _solo_control.set_state (*child);
1692 _session.add_controllable (&_solo_control);
1694 else if (prop->value() == "mute") {
1695 _mute_control.set_state (*child);
1696 _session.add_controllable (&_mute_control);
1699 else if (child->name() == X_("remote_control")) {
1700 if ((prop = child->property (X_("id"))) != 0) {
1702 sscanf (prop->value().c_str(), "%d", &x);
1703 set_remote_control_id (x);
1708 if ((prop = node.property (X_("mix-group"))) != 0) {
1709 RouteGroup* mix_group = _session.mix_group_by_name(prop->value());
1710 if (mix_group == 0) {
1711 error << string_compose(_("Route %1: unknown mix group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
1713 set_mix_group(mix_group, this);
1721 Route::curve_reallocate ()
1723 // _gain_automation_curve.finish_resize ();
1724 // _pan_automation_curve.finish_resize ();
1728 Route::silence (nframes_t nframes, nframes_t offset)
1732 IO::silence (nframes, offset);
1734 if (_control_outs) {
1735 _control_outs->silence (nframes, offset);
1739 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
1742 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1743 boost::shared_ptr<PluginInsert> pi;
1744 if (!_active && (pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
1745 // skip plugins, they don't need anything when we're not active
1749 (*i)->silence (nframes, offset);
1752 if (nframes == _session.get_block_size() && offset == 0) {
1762 Route::set_control_outs (const vector<string>& ports)
1764 Glib::Mutex::Lock lm (control_outs_lock);
1765 vector<string>::const_iterator i;
1767 if (_control_outs) {
1768 delete _control_outs;
1772 if (ports.empty()) {
1776 string coutname = _name;
1777 coutname += _("[control]");
1779 _control_outs = new IO (_session, coutname);
1781 /* our control outs need as many outputs as we
1782 have audio outputs. we track the changes in ::output_change_handler().
1785 _control_outs->ensure_io (ChanCount::ZERO, ChanCount(DataType::AUDIO, n_outputs().get(DataType::AUDIO)), true, this);
1791 Route::set_edit_group (RouteGroup *eg, void *src)
1794 if (eg == _edit_group) {
1799 _edit_group->remove (this);
1802 if ((_edit_group = eg) != 0) {
1803 _edit_group->add (this);
1806 _session.set_dirty ();
1807 edit_group_changed (src); /* EMIT SIGNAL */
1811 Route::drop_edit_group (void *src)
1814 _session.set_dirty ();
1815 edit_group_changed (src); /* EMIT SIGNAL */
1819 Route::set_mix_group (RouteGroup *mg, void *src)
1822 if (mg == _mix_group) {
1827 _mix_group->remove (this);
1830 if ((_mix_group = mg) != 0) {
1831 _mix_group->add (this);
1834 _session.set_dirty ();
1835 mix_group_changed (src); /* EMIT SIGNAL */
1839 Route::drop_mix_group (void *src)
1842 _session.set_dirty ();
1843 mix_group_changed (src); /* EMIT SIGNAL */
1847 Route::set_comment (string cmt, void *src)
1850 comment_changed (src);
1851 _session.set_dirty ();
1855 Route::feeds (boost::shared_ptr<Route> other)
1860 uint32_t no = self.n_outputs().get_total();
1861 uint32_t ni = other->n_inputs ().get_total();
1863 for (i = 0; i < no; ++i) {
1864 for (j = 0; j < ni; ++j) {
1865 if (self.output(i)->connected_to (other->input(j)->name())) {
1871 /* check Redirects which may also interconnect Routes */
1873 for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); r++) {
1875 no = (*r)->n_outputs().get_total();
1877 for (i = 0; i < no; ++i) {
1878 for (j = 0; j < ni; ++j) {
1879 if ((*r)->output(i)->connected_to (other->input (j)->name())) {
1886 /* check for control room outputs which may also interconnect Routes */
1888 if (_control_outs) {
1890 no = _control_outs->n_outputs().get_total();
1892 for (i = 0; i < no; ++i) {
1893 for (j = 0; j < ni; ++j) {
1894 if (_control_outs->output(i)->connected_to (other->input (j)->name())) {
1905 Route::set_mute_config (mute_type t, bool onoff, void *src)
1909 _mute_affects_pre_fader = onoff;
1910 pre_fader_changed(src); /* EMIT SIGNAL */
1914 _mute_affects_post_fader = onoff;
1915 post_fader_changed(src); /* EMIT SIGNAL */
1919 _mute_affects_control_outs = onoff;
1920 control_outs_changed(src); /* EMIT SIGNAL */
1924 _mute_affects_main_outs = onoff;
1925 main_outs_changed(src); /* EMIT SIGNAL */
1931 Route::get_mute_config (mute_type t)
1937 onoff = _mute_affects_pre_fader;
1940 onoff = _mute_affects_post_fader;
1943 onoff = _mute_affects_control_outs;
1946 onoff = _mute_affects_main_outs;
1954 Route::set_active (bool yn)
1957 active_changed(); /* EMIT SIGNAL */
1961 Route::handle_transport_stopped (bool abort_ignored, bool did_locate, bool can_flush_redirects)
1963 nframes_t now = _session.transport_frame();
1966 Glib::RWLock::ReaderLock lm (redirect_lock);
1969 automation_snapshot (now);
1972 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1974 if (Config->get_plugins_stop_with_transport() && can_flush_redirects) {
1975 (*i)->deactivate ();
1979 (*i)->transport_stopped (now);
1983 IO::transport_stopped (now);
1985 _roll_delay = _initial_delay;
1989 Route::input_change_handler (IOChange change, void *ignored)
1991 if (change & ConfigurationChanged) {
1992 reset_plugin_counts (0);
1997 Route::output_change_handler (IOChange change, void *ignored)
1999 if (change & ConfigurationChanged) {
2000 if (_control_outs) {
2001 _control_outs->ensure_io (ChanCount::ZERO, ChanCount(DataType::AUDIO, n_outputs().get(DataType::AUDIO)), true, this);
2004 reset_plugin_counts (0);
2009 Route::pans_required () const
2011 if (n_outputs().get(DataType::AUDIO) < 2) {
2015 return max (n_inputs ().get(DataType::AUDIO), static_cast<size_t>(redirect_max_outs.get(DataType::AUDIO)));
2019 Route::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset,
2020 bool session_state_changing, bool can_record, bool rec_monitors_input)
2022 if (n_outputs().get_total() == 0) {
2026 if (session_state_changing || !_active) {
2027 silence (nframes, offset);
2031 apply_gain_automation = false;
2033 if (n_inputs().get_total()) {
2034 passthru (start_frame, end_frame, nframes, offset, 0, false);
2036 silence (nframes, offset);
2043 Route::check_initial_delay (nframes_t nframes, nframes_t& offset, nframes_t& transport_frame)
2045 if (_roll_delay > nframes) {
2047 _roll_delay -= nframes;
2048 silence (nframes, offset);
2049 /* transport frame is not legal for caller to use */
2052 } else if (_roll_delay > 0) {
2054 nframes -= _roll_delay;
2056 silence (_roll_delay, offset);
2058 offset += _roll_delay;
2059 transport_frame += _roll_delay;
2068 Route::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, int declick,
2069 bool can_record, bool rec_monitors_input)
2072 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
2074 // automation snapshot can also be called from the non-rt context
2075 // and it uses the redirect list, so we take the lock out here
2076 automation_snapshot (_session.transport_frame());
2080 if ((n_outputs().get_total() == 0 && _redirects.empty()) || n_inputs().get_total() == 0 || !_active) {
2081 silence (nframes, offset);
2085 nframes_t unused = 0;
2087 if ((nframes = check_initial_delay (nframes, offset, unused)) == 0) {
2093 apply_gain_automation = false;
2096 Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK);
2098 if (am.locked() && _session.transport_rolling()) {
2100 if (gain_automation_playback()) {
2101 apply_gain_automation = _gain_automation_curve.rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes);
2106 passthru (start_frame, end_frame, nframes, offset, declick, false);
2112 Route::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset,
2113 bool can_record, bool rec_monitors_input)
2115 silence (nframes, offset);
2120 Route::toggle_monitor_input ()
2122 for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
2123 i->ensure_monitor_input( ! i->monitoring_input());
2128 Route::has_external_redirects () const
2130 boost::shared_ptr<const PortInsert> pi;
2132 for (RedirectList::const_iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2133 if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*i)) != 0) {
2135 for (PortSet::const_iterator port = pi->outputs().begin();
2136 port != pi->outputs().end(); ++port) {
2138 string port_name = port->name();
2139 string client_name = port_name.substr (0, port_name.find(':'));
2141 /* only say "yes" if the redirect is actually in use */
2143 if (client_name != "ardour" && pi->active()) {
2154 Route::flush_redirects ()
2156 /* XXX shouldn't really try to take this lock, since
2157 this is called from the RT audio thread.
2160 Glib::RWLock::ReaderLock lm (redirect_lock);
2162 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2163 (*i)->deactivate ();
2169 Route::set_meter_point (MeterPoint p, void *src)
2171 if (_meter_point != p) {
2173 meter_change (src); /* EMIT SIGNAL */
2174 _session.set_dirty ();
2179 Route::update_total_latency ()
2183 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2184 if ((*i)->active ()) {
2185 _own_latency += (*i)->latency ();
2189 set_port_latency (_own_latency);
2191 /* this (virtual) function is used for pure Routes,
2192 not derived classes like AudioTrack. this means
2193 that the data processed here comes from an input
2194 port, not prerecorded material, and therefore we
2195 have to take into account any input latency.
2198 _own_latency += input_latency ();
2200 return _own_latency;
2204 Route::set_latency_delay (nframes_t longest_session_latency)
2206 _initial_delay = longest_session_latency - _own_latency;
2208 if (_session.transport_stopped()) {
2209 _roll_delay = _initial_delay;
2214 Route::automation_snapshot (nframes_t now)
2216 IO::automation_snapshot (now);
2218 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2219 (*i)->automation_snapshot (now);
2223 Route::ToggleControllable::ToggleControllable (std::string name, Route& s, ToggleType tp)
2224 : Controllable (name), route (s), type(tp)
2230 Route::ToggleControllable::set_value (float val)
2232 bool bval = ((val >= 0.5f) ? true: false);
2236 route.set_mute (bval, this);
2239 route.set_solo (bval, this);
2247 Route::ToggleControllable::get_value (void) const
2253 val = route.muted() ? 1.0f : 0.0f;
2256 val = route.soloed() ? 1.0f : 0.0f;
2266 Route::set_block_size (nframes_t nframes)
2268 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2269 (*i)->set_block_size (nframes);
2274 Route::redirect_active_proxy (Redirect* ignored, void* ignored_src)
2276 _session.update_latency_compensation (false, false);
2280 Route::protect_automation ()
2282 switch (gain_automation_state()) {
2284 set_gain_automation_state (Off);
2286 set_gain_automation_state (Play);
2292 switch (panner().automation_state ()) {
2294 panner().set_automation_state (Off);
2297 panner().set_automation_state (Play);
2303 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2304 boost::shared_ptr<PluginInsert> pi;
2305 if ((pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
2306 pi->protect_automation ();
2312 Route::set_pending_declick (int declick)
2315 /* this call is not allowed to turn off a pending declick unless "force" is true */
2317 _pending_declick = declick;
2319 // cerr << _name << ": after setting to " << declick << " pending declick = " << _pending_declick << endl;
2321 _pending_declick = 0;