Make the set_state() function respect redirects already present on the route. Still...
[ardour.git] / libs / ardour / route.cc
1 /*
2     Copyright (C) 2000 Paul Davis 
3
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.
8
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.
13
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.
17
18 */
19
20 #include <cmath>
21 #include <fstream>
22 #include <cassert>
23
24 #include <sigc++/bind.h>
25 #include <pbd/xml++.h>
26 #include <pbd/enumwriter.h>
27
28 #include <ardour/timestamps.h>
29 #include <ardour/buffer.h>
30 #include <ardour/audioengine.h>
31 #include <ardour/route.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/ladspa_plugin.h>
41 #include <ardour/panner.h>
42 #include <ardour/dB.h>
43 #include <ardour/mix.h>
44
45 #include "i18n.h"
46
47 using namespace std;
48 using namespace ARDOUR;
49 using namespace PBD;
50
51
52 uint32_t Route::order_key_cnt = 0;
53
54
55 Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg, DataType default_type)
56         : IO (sess, name, input_min, input_max, output_min, output_max, default_type),
57           _flags (flg),
58           _solo_control (X_("solo"), *this, ToggleControllable::SoloControl),
59           _mute_control (X_("mute"), *this, ToggleControllable::MuteControl)
60 {
61         init ();
62 }
63
64 Route::Route (Session& sess, const XMLNode& node, DataType default_type)
65         : IO (sess, *node.child ("IO"), default_type),
66           _solo_control (X_("solo"), *this, ToggleControllable::SoloControl),
67           _mute_control (X_("mute"), *this, ToggleControllable::MuteControl)
68 {
69         init ();
70         _set_state (node, false);
71 }
72
73 void
74 Route::init ()
75 {
76         redirect_max_outs = 0;
77         _muted = false;
78         _soloed = false;
79         _solo_safe = false;
80         _phase_invert = false;
81         order_keys[strdup (N_("signal"))] = order_key_cnt++;
82         _active = true;
83         _silent = false;
84         _meter_point = MeterPostFader;
85         _initial_delay = 0;
86         _roll_delay = 0;
87         _own_latency = 0;
88         _have_internal_generator = false;
89         _declickable = false;
90         _pending_declick = true;
91         _remote_control_id = 0;
92         _ignore_gain_on_deliver = true;
93         
94         _edit_group = 0;
95         _mix_group = 0;
96
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();
101         
102         solo_gain = 1.0;
103         desired_solo_gain = 1.0;
104         mute_gain = 1.0;
105         desired_mute_gain = 1.0;
106
107         _control_outs = 0;
108
109         input_changed.connect (mem_fun (this, &Route::input_change_handler));
110         output_changed.connect (mem_fun (this, &Route::output_change_handler));
111 }
112
113 Route::~Route ()
114 {
115         clear_redirects (PreFader, this);
116         clear_redirects (PostFader, this);
117
118         for (OrderKeys::iterator i = order_keys.begin(); i != order_keys.end(); ++i) {
119                 free ((void*)(i->first));
120         }
121
122         if (_control_outs) {
123                 delete _control_outs;
124         }
125 }
126
127 void
128 Route::set_remote_control_id (uint32_t id)
129 {
130         if (id != _remote_control_id) {
131                 _remote_control_id = id;
132                 RemoteControlIDChanged ();
133         }
134 }
135
136 uint32_t
137 Route::remote_control_id() const
138 {
139         return _remote_control_id;
140 }
141
142 long
143 Route::order_key (const char* name) const
144 {
145         OrderKeys::const_iterator i;
146         
147         for (i = order_keys.begin(); i != order_keys.end(); ++i) {
148                 if (!strcmp (name, i->first)) {
149                         return i->second;
150                 }
151         }
152
153         return -1;
154 }
155
156 void
157 Route::set_order_key (const char* name, long n)
158 {
159         order_keys[strdup(name)] = n;
160         _session.set_dirty ();
161 }
162
163 void
164 Route::inc_gain (gain_t fraction, void *src)
165 {
166         IO::inc_gain (fraction, src);
167 }
168
169 void
170 Route::set_gain (gain_t val, void *src)
171 {
172         if (src != 0 && _mix_group && src != _mix_group && _mix_group->is_active()) {
173                 
174                 if (_mix_group->is_relative()) {
175                         
176                         
177                         gain_t usable_gain  = gain();
178                         if (usable_gain < 0.000001f) {
179                                 usable_gain=0.000001f;
180                         }
181                                                 
182                         gain_t delta = val;
183                         if (delta < 0.000001f) {
184                                 delta=0.000001f;
185                         }
186
187                         delta -= usable_gain;
188
189                         if (delta == 0.0f) return;
190
191                         gain_t factor = delta / usable_gain;
192
193                         if (factor > 0.0f) {
194                                 factor = _mix_group->get_max_factor(factor);
195                                 if (factor == 0.0f) {
196                                         gain_changed (src);
197                                         return;
198                                 }
199                         } else {
200                                 factor = _mix_group->get_min_factor(factor);
201                                 if (factor == 0.0f) {
202                                         gain_changed (src);
203                                         return;
204                                 }
205                         }
206                                         
207                         _mix_group->apply (&Route::inc_gain, factor, _mix_group);
208
209                 } else {
210                         
211                         _mix_group->apply (&Route::set_gain, val, _mix_group);
212                 }
213
214                 return;
215         } 
216
217         if (val == gain()) {
218                 return;
219         }
220
221         IO::set_gain (val, src);
222 }
223
224 void
225 Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
226                                nframes_t start_frame, nframes_t end_frame, 
227                                nframes_t nframes, nframes_t offset, bool with_redirects, int declick,
228                                bool meter)
229 {
230         uint32_t n;
231         RedirectList::iterator i;
232         bool post_fader_work = false;
233         bool mute_declick_applied = false;
234         gain_t dmg, dsg, dg;
235         vector<Sample*>::iterator bufiter;
236         IO *co;
237         bool mute_audible;
238         bool solo_audible;
239         bool no_monitor;
240         gain_t* gab = _session.gain_automation_buffer();
241
242         switch (Config->get_monitoring_model()) {
243         case HardwareMonitoring:
244         case ExternalMonitoring:
245                 no_monitor = true;
246                 break;
247         default:
248                 no_monitor = false;
249         }
250
251         declick = _pending_declick;
252
253         {
254                 Glib::Mutex::Lock cm (control_outs_lock, Glib::TRY_LOCK);
255                 
256                 if (cm.locked()) {
257                         co = _control_outs;
258                 } else {
259                         co = 0;
260                 }
261         }
262         
263         { 
264                 Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK);
265                 
266                 if (dm.locked()) {
267                         dmg = desired_mute_gain;
268                         dsg = desired_solo_gain;
269                         dg = _desired_gain;
270                 } else {
271                         dmg = mute_gain;
272                         dsg = solo_gain;
273                         dg = _gain;
274                 }
275         }
276
277         /* ----------------------------------------------------------------------------------------------------
278            GLOBAL DECLICK (for transport changes etc.)
279            -------------------------------------------------------------------------------------------------- */
280
281         if (declick > 0) {
282                 apply_declick (bufs, nbufs, nframes, 0.0, 1.0, false);
283                 _pending_declick = 0;
284         } else if (declick < 0) {
285                 apply_declick (bufs, nbufs, nframes, 1.0, 0.0, false);
286                 _pending_declick = 0;
287         } else {
288
289                 /* no global declick */
290
291                 if (solo_gain != dsg) {
292                         apply_declick (bufs, nbufs, nframes, solo_gain, dsg, false);
293                         solo_gain = dsg;
294                 }
295         }
296
297
298         /* ----------------------------------------------------------------------------------------------------
299            INPUT METERING & MONITORING
300            -------------------------------------------------------------------------------------------------- */
301
302         if (meter && (_meter_point == MeterInput)) {
303                 for (n = 0; n < nbufs; ++n) {
304                         _peak_power[n] = Session::compute_peak (bufs[n], nframes, _peak_power[n]); 
305                 }
306         }
307
308         if (!_soloed && _mute_affects_pre_fader && (mute_gain != dmg)) {
309                 apply_declick (bufs, nbufs, nframes, mute_gain, dmg, false);
310                 mute_gain = dmg;
311                 mute_declick_applied = true;
312         }
313
314         if ((_meter_point == MeterInput) && co) {
315                 
316                 solo_audible = dsg > 0;
317                 mute_audible = dmg > 0;// || !_mute_affects_pre_fader;
318                 
319                 if (    // muted by solo of another track
320                         
321                         !solo_audible || 
322                         
323                         // muted by mute of this track 
324                         
325                         !mute_audible ||
326                         
327                         // rec-enabled but not s/w monitoring 
328                         
329                         // TODO: this is probably wrong
330
331                         (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording()))
332
333                         ) {
334                         
335                         co->silence (nframes, offset);
336                         
337                 } else {
338
339                         co->deliver_output (bufs, nbufs, nframes, offset);
340                         
341                 } 
342         } 
343
344         /* ----------------------------------------------------------------------------------------------------
345            PRE-FADER REDIRECTS
346            -------------------------------------------------------------------------------------------------- */
347
348         if (with_redirects) {
349                 Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK);
350                 if (rm.locked()) {
351                         if (mute_gain > 0 || !_mute_affects_pre_fader) {
352                                 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
353                                         switch ((*i)->placement()) {
354                                         case PreFader:
355                                                 if (dsg == 0) {
356                                                         if (boost::dynamic_pointer_cast<Send>(*i) || boost::dynamic_pointer_cast<PortInsert>(*i)) {
357                                                                 (*i)->silence (nframes, offset);
358                                                         }
359                                                 } else {
360                                                         (*i)->run (bufs, nbufs, nframes, offset);
361                                                 }
362                                                 break;
363                                         case PostFader:
364                                                 post_fader_work = true;
365                                                 break;
366                                         }
367                                 }
368                         } else {
369                                 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
370                                         switch ((*i)->placement()) {
371                                         case PreFader:
372                                                 (*i)->silence (nframes, offset);
373                                                 break;
374                                         case PostFader:
375                                                 post_fader_work = true;
376                                                 break;
377                                         }
378                                 }
379                         }
380                 } 
381         }
382
383
384         if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_post_fader) {
385                 apply_declick (bufs, nbufs, nframes, mute_gain, dmg, false);
386                 mute_gain = dmg;
387                 mute_declick_applied = true;
388         }
389
390         /* ----------------------------------------------------------------------------------------------------
391            PRE-FADER METERING & MONITORING
392            -------------------------------------------------------------------------------------------------- */
393
394         if (meter && (_meter_point == MeterPreFader)) {
395                 for (n = 0; n < nbufs; ++n) {
396                         _peak_power[n] = Session::compute_peak (bufs[n], nframes, _peak_power[n]);
397                 }
398         }
399
400         
401         if ((_meter_point == MeterPreFader) && co) {
402                 
403                 solo_audible = dsg > 0;
404                 mute_audible = dmg > 0 || !_mute_affects_pre_fader;
405                 
406                 if ( // muted by solo of another track
407                         
408                         !solo_audible || 
409                         
410                         // muted by mute of this track 
411                         
412                         !mute_audible ||
413                         
414                         // rec-enabled but not s/w monitoring 
415                         
416                         (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording()))
417
418                         ) {
419                         
420                         co->silence (nframes, offset);
421                         
422                 } else {
423
424                         co->deliver_output_no_pan (bufs, nbufs, nframes, offset);
425                         
426                 } 
427         } 
428         
429         /* ----------------------------------------------------------------------------------------------------
430            GAIN STAGE
431            -------------------------------------------------------------------------------------------------- */
432
433         /* if not recording or recording and requiring any monitor signal, then apply gain */
434
435         if ( // not recording 
436
437                 !(record_enabled() && _session.actively_recording()) || 
438                 
439             // OR recording 
440                 
441                 // h/w monitoring not in use 
442                 
443                 (!Config->get_monitoring_model() == HardwareMonitoring && 
444
445                  // AND software monitoring required
446
447                  Config->get_monitoring_model() == SoftwareMonitoring)) { 
448                 
449                 if (apply_gain_automation) {
450                         
451                         if (_phase_invert) {
452                                 for (n = 0; n < nbufs; ++n)  {
453                                         Sample *sp = bufs[n];
454                                         
455                                         for (nframes_t nx = 0; nx < nframes; ++nx) {
456                                                 sp[nx] *= -gab[nx];
457                                         }
458                                 }
459                         } else {
460                                 for (n = 0; n < nbufs; ++n) {
461                                         Sample *sp = bufs[n];
462                                         
463                                         for (nframes_t nx = 0; nx < nframes; ++nx) {
464                                                 sp[nx] *= gab[nx];
465                                         }
466                                 }
467                         }
468                         
469                         if (apply_gain_automation && _session.transport_rolling() && nframes > 0) {
470                                 _effective_gain = gab[nframes-1];
471                         }
472                         
473                 } else {
474                         
475                         /* manual (scalar) gain */
476                         
477                         if (_gain != dg) {
478                                 
479                                 apply_declick (bufs, nbufs, nframes, _gain, dg, _phase_invert);
480                                 _gain = dg;
481                                 
482                         } else if (_gain != 0 && (_phase_invert || _gain != 1.0)) {
483                                 
484                                 /* no need to interpolate current gain value,
485                                    but its non-unity, so apply it. if the gain
486                                    is zero, do nothing because we'll ship silence
487                                    below.
488                                 */
489
490                                 gain_t this_gain;
491                                 
492                                 if (_phase_invert) {
493                                         this_gain = -_gain;
494                                 } else {
495                                         this_gain = _gain;
496                                 }
497                                 
498                                 for (n = 0; n < nbufs; ++n) {
499                                         Sample *sp = bufs[n];
500                                         Session::apply_gain_to_buffer(sp,nframes,this_gain);
501                                 }
502
503                         } else if (_gain == 0) {
504                                 for (n = 0; n < nbufs; ++n) {
505                                         memset (bufs[n], 0, sizeof (Sample) * nframes);
506                                 }
507                         }
508                 }
509
510         } else {
511
512                 /* actively recording, no monitoring required; leave buffers as-is to save CPU cycles */
513
514         }
515
516         /* ----------------------------------------------------------------------------------------------------
517            POST-FADER REDIRECTS
518            -------------------------------------------------------------------------------------------------- */
519
520         /* note that post_fader_work cannot be true unless with_redirects was also true, so don't test both */
521
522         if (post_fader_work) {
523
524                 Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK);
525                 if (rm.locked()) {
526                         if (mute_gain > 0 || !_mute_affects_post_fader) {
527                                 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
528                                         switch ((*i)->placement()) {
529                                         case PreFader:
530                                                 break;
531                                         case PostFader:
532                                                 if (dsg == 0) {
533                                                         if (boost::dynamic_pointer_cast<Send>(*i) || boost::dynamic_pointer_cast<PortInsert>(*i)) {
534                                                                 (*i)->silence (nframes, offset);
535                                                         }
536                                                 } else {
537                                                         (*i)->run (bufs, nbufs, nframes, offset);
538                                                 }
539                                                 break;
540                                         }
541                                 }
542                         } else {
543                                 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
544                                         switch ((*i)->placement()) {
545                                         case PreFader:
546                                                 break;
547                                         case PostFader:
548                                                 (*i)->silence (nframes, offset);
549                                                 break;
550                                         }
551                                 }
552                         }
553                 } 
554         }
555
556         if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_control_outs) {
557                 apply_declick (bufs, nbufs, nframes, mute_gain, dmg, false);
558                 mute_gain = dmg;
559                 mute_declick_applied = true;
560         }
561
562         /* ----------------------------------------------------------------------------------------------------
563            CONTROL OUTPUT STAGE
564            -------------------------------------------------------------------------------------------------- */
565
566         if ((_meter_point == MeterPostFader) && co) {
567                 
568                 solo_audible = solo_gain > 0;
569                 mute_audible = dmg > 0 || !_mute_affects_control_outs;
570
571                 if ( // silent anyway
572
573                         (_gain == 0 && !apply_gain_automation) || 
574                     
575                      // muted by solo of another track
576
577                         !solo_audible || 
578                     
579                      // muted by mute of this track 
580
581                         !mute_audible ||
582
583                     // recording but not s/w monitoring 
584                         
585                         (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording()))
586
587                         ) {
588                         
589                         co->silence (nframes, offset);
590                         
591                 } else {
592
593                         co->deliver_output_no_pan (bufs, nbufs, nframes, offset);
594                 } 
595         } 
596
597         /* ----------------------------------------------------------------------
598            GLOBAL MUTE 
599            ----------------------------------------------------------------------*/
600
601         if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_main_outs) {
602                 apply_declick (bufs, nbufs, nframes, mute_gain, dmg, false);
603                 mute_gain = dmg;
604                 mute_declick_applied = true;
605         }
606         
607         /* ----------------------------------------------------------------------------------------------------
608            MAIN OUTPUT STAGE
609            -------------------------------------------------------------------------------------------------- */
610
611         solo_audible = dsg > 0;
612         mute_audible = dmg > 0 || !_mute_affects_main_outs;
613         
614         if (n_outputs() == 0) {
615             
616             /* relax */
617
618         } else if (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording())) {
619                 
620                 IO::silence (nframes, offset);
621                 
622         } else {
623
624                 if ( // silent anyway
625
626                     (_gain == 0 && !apply_gain_automation) ||
627                     
628                     // muted by solo of another track, but not using control outs for solo
629
630                     (!solo_audible && (Config->get_solo_model() != SoloBus)) ||
631                     
632                     // muted by mute of this track
633
634                     !mute_audible
635
636                         ) {
637
638                         /* don't use Route::silence() here, because that causes
639                            all outputs (sends, port inserts, etc. to be silent).
640                         */
641                         
642                         if (_meter_point == MeterPostFader) {
643                                 reset_peak_meters ();
644                         }
645
646                         IO::silence (nframes, offset);
647                         
648                 } else {
649                         
650                         if ((_session.transport_speed() > 1.5f || 
651                              _session.transport_speed() < -1.5f) &&
652                             Config->get_quieten_at_speed()) {
653                                 pan (bufs, nbufs, nframes, offset, speed_quietning); 
654                         } else {
655                                 // cerr << _name << " panner state = " << _panner->automation_state() << endl;
656                                 if (!_panner->empty() &&
657                                     (_panner->automation_state() & Play ||
658                                      ((_panner->automation_state() & Touch) && !_panner->touching()))) {
659                                         pan_automated (bufs, nbufs, start_frame, end_frame, nframes, offset);
660                                 } else {
661                                         pan (bufs, nbufs, nframes, offset, 1.0); 
662                                 }
663                         }
664                 }
665
666         }
667
668         /* ----------------------------------------------------------------------------------------------------
669            POST-FADER METERING
670            -------------------------------------------------------------------------------------------------- */
671
672         if (meter && (_meter_point == MeterPostFader)) {
673 //              cerr << "meter post" << endl;
674
675                 if ((_gain == 0 && !apply_gain_automation) || dmg == 0) {
676                         uint32_t no = n_outputs();
677                         for (n = 0; n < no; ++n) {
678                                 _peak_power[n] = 0;
679                         } 
680                 } else {
681                         uint32_t no = n_outputs();
682                         for (n = 0; n < no; ++n) {
683                                 _peak_power[n] = Session::compute_peak (output(n)->get_buffer (nframes) + offset, nframes, _peak_power[n]);
684                         }
685                 }
686         }
687 }
688
689 uint32_t
690 Route::n_process_buffers ()
691 {
692         return max (n_inputs(), redirect_max_outs);
693 }
694
695 void
696
697 Route::passthru (nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset, int declick, bool meter_first)
698 {
699         vector<Sample*>& bufs = _session.get_passthru_buffers();
700         uint32_t limit = n_process_buffers ();
701
702         _silent = false;
703
704         collect_input (bufs, limit, nframes, offset);
705
706 #define meter_stream meter_first
707
708         if (meter_first) {
709                 for (uint32_t n = 0; n < limit; ++n) {
710                         _peak_power[n] = Session::compute_peak (bufs[n], nframes, _peak_power[n]);
711                 }
712                 meter_stream = false;
713         } else {
714                 meter_stream = true;
715         }
716                 
717         process_output_buffers (bufs, limit, start_frame, end_frame, nframes, offset, true, declick, meter_stream);
718
719 #undef meter_stream
720 }
721
722 void
723 Route::set_phase_invert (bool yn, void *src)
724 {
725         if (_phase_invert != yn) {
726                 _phase_invert = yn;
727         }
728         //  phase_invert_changed (src); /* EMIT SIGNAL */
729 }
730
731 void
732 Route::set_solo (bool yn, void *src)
733 {
734         if (_solo_safe) {
735                 return;
736         }
737
738         if (_mix_group && src != _mix_group && _mix_group->is_active()) {
739                 _mix_group->apply (&Route::set_solo, yn, _mix_group);
740                 return;
741         }
742
743         if (_soloed != yn) {
744                 _soloed = yn;
745                 solo_changed (src); /* EMIT SIGNAL */
746                 _solo_control.Changed (); /* EMIT SIGNAL */
747         }
748 }
749
750 void
751 Route::set_solo_mute (bool yn)
752 {
753         Glib::Mutex::Lock lm (declick_lock);
754
755         /* Called by Session in response to another Route being soloed.
756          */
757            
758         desired_solo_gain = (yn?0.0:1.0);
759 }
760
761 void
762 Route::set_solo_safe (bool yn, void *src)
763 {
764         if (_solo_safe != yn) {
765                 _solo_safe = yn;
766                  solo_safe_changed (src); /* EMIT SIGNAL */
767         }
768 }
769
770 void
771 Route::set_mute (bool yn, void *src)
772
773 {
774         if (_mix_group && src != _mix_group && _mix_group->is_active()) {
775                 _mix_group->apply (&Route::set_mute, yn, _mix_group);
776                 return;
777         }
778
779         if (_muted != yn) {
780                 _muted = yn;
781                 mute_changed (src); /* EMIT SIGNAL */
782                 
783                 _mute_control.Changed (); /* EMIT SIGNAL */
784                 
785                 Glib::Mutex::Lock lm (declick_lock);
786                 desired_mute_gain = (yn?0.0f:1.0f);
787         }
788 }
789
790 int
791 Route::add_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
792 {
793         uint32_t old_rmo = redirect_max_outs;
794
795         if (!_session.engine().connected()) {
796                 return 1;
797         }
798
799         {
800                 Glib::RWLock::WriterLock lm (redirect_lock);
801
802                 boost::shared_ptr<PluginInsert> pi;
803                 boost::shared_ptr<PortInsert> porti;
804
805                 uint32_t potential_max_streams = 0;
806
807                 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(redirect)) != 0) {
808                         pi->set_count (1);
809
810                         if (pi->input_streams() == 0) {
811                                 /* instrument plugin */
812                                 _have_internal_generator = true;
813                         }
814
815                         potential_max_streams = max(pi->input_streams(), pi->output_streams());
816                         
817                 } else if ((porti = boost::dynamic_pointer_cast<PortInsert>(redirect)) != 0) {
818
819                         /* force new port inserts to start out with an i/o configuration
820                            that matches this route's i/o configuration.
821
822                            the "inputs" for the port are supposed to match the output
823                            of this route.
824
825                            the "outputs" of the route should match the inputs of this
826                            route. XXX shouldn't they match the number of active signal
827                            streams at the point of insertion?
828                            
829                         */
830
831                         porti->ensure_io (n_outputs (), n_inputs(), false, this);
832                 }
833
834                 // Ensure peak vector sizes before the plugin is activated
835                 while (_peak_power.size() < potential_max_streams) {
836                         _peak_power.push_back(0);
837                 }
838                 while (_visible_peak_power.size() < potential_max_streams) {
839                         _visible_peak_power.push_back(-INFINITY);
840                 }
841                 while (_max_peak_power.size() < potential_max_streams) {
842                         _max_peak_power.push_back(-INFINITY);
843                 }
844
845                 _redirects.push_back (redirect);
846
847                 if (_reset_plugin_counts (err_streams)) {
848                         _redirects.pop_back ();
849                         _reset_plugin_counts (0); // it worked before we tried to add it ...
850                         return -1;
851                 }
852
853                 redirect->activate ();
854                 redirect->active_changed.connect (mem_fun (*this, &Route::redirect_active_proxy));
855         }
856         
857         if (redirect_max_outs != old_rmo || old_rmo == 0) {
858                 reset_panner ();
859         }
860
861
862         redirects_changed (src); /* EMIT SIGNAL */
863         return 0;
864 }
865
866 int
867 Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_streams)
868 {
869         uint32_t old_rmo = redirect_max_outs;
870
871         if (!_session.engine().connected()) {
872                 return 1;
873         }
874
875         {
876                 Glib::RWLock::WriterLock lm (redirect_lock);
877
878                 RedirectList::iterator existing_end = _redirects.end();
879                 --existing_end;
880
881                 uint32_t potential_max_streams = 0;
882
883                 for (RedirectList::const_iterator i = others.begin(); i != others.end(); ++i) {
884                         
885                         boost::shared_ptr<PluginInsert> pi;
886                         
887                         if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
888                                 pi->set_count (1);
889                                 
890                                 uint32_t m = max(pi->input_streams(), pi->output_streams());
891                                 if (m > potential_max_streams)
892                                         potential_max_streams = m;
893                         }
894
895                         // Ensure peak vector sizes before the plugin is activated
896                         while (_peak_power.size() < potential_max_streams) {
897                                 _peak_power.push_back(0);
898                         }
899                         while (_visible_peak_power.size() < potential_max_streams) {
900                                 _visible_peak_power.push_back(-INFINITY);
901                         }
902                         while (_max_peak_power.size() < potential_max_streams) {
903                                 _max_peak_power.push_back(-INFINITY);
904                         }
905
906                         _redirects.push_back (*i);
907                         
908                         if (_reset_plugin_counts (err_streams)) {
909                                 ++existing_end;
910                                 _redirects.erase (existing_end, _redirects.end());
911                                 _reset_plugin_counts (0); // it worked before we tried to add it ...
912                                 return -1;
913                         }
914                         
915                         (*i)->activate ();
916                         (*i)->active_changed.connect (mem_fun (*this, &Route::redirect_active_proxy));
917                 }
918         }
919         
920         if (redirect_max_outs != old_rmo || old_rmo == 0) {
921                 reset_panner ();
922         }
923
924         redirects_changed (src); /* EMIT SIGNAL */
925         return 0;
926 }
927
928 /** Remove redirects with a given placement.
929  * @param p Placement of redirects to remove.
930  */
931 void
932 Route::clear_redirects (Placement p, void *src)
933 {
934         const uint32_t old_rmo = redirect_max_outs;
935
936         if (!_session.engine().connected()) {
937                 return;
938         }
939
940         {
941                 Glib::RWLock::WriterLock lm (redirect_lock);
942                 RedirectList new_list;
943                 
944                 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
945                         if ((*i)->placement() == p) {
946                                 /* it's the placement we want to get rid of */
947                                 (*i)->drop_references ();
948                         } else {
949                                 /* it's a different placement, so keep it */
950                                 new_list.push_back (*i);
951                         }
952                 }
953                 
954                 _redirects = new_list;
955         }
956
957         /* FIXME: can't see how this test can ever fire */
958         if (redirect_max_outs != old_rmo) {
959                 reset_panner ();
960         }
961         
962         redirect_max_outs = 0;
963         _have_internal_generator = false;
964         redirects_changed (src); /* EMIT SIGNAL */
965 }
966
967 int
968 Route::remove_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
969 {
970         uint32_t old_rmo = redirect_max_outs;
971
972         if (!_session.engine().connected()) {
973                 return 1;
974         }
975
976         redirect_max_outs = 0;
977
978         {
979                 Glib::RWLock::WriterLock lm (redirect_lock);
980                 RedirectList::iterator i;
981                 bool removed = false;
982
983                 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
984                         if (*i == redirect) {
985
986                                 RedirectList::iterator tmp;
987
988                                 /* move along, see failure case for reset_plugin_counts()
989                                    where we may need to reinsert the redirect.
990                                 */
991
992                                 tmp = i;
993                                 ++tmp;
994
995                                 /* stop redirects that send signals to JACK ports
996                                    from causing noise as a result of no longer being
997                                    run.
998                                 */
999
1000                                 boost::shared_ptr<Send> send;
1001                                 boost::shared_ptr<PortInsert> port_insert;
1002                                 
1003                                 if ((send = boost::dynamic_pointer_cast<Send> (*i)) != 0) {
1004                                         send->disconnect_inputs (this);
1005                                         send->disconnect_outputs (this);
1006                                 } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (*i)) != 0) {
1007                                         port_insert->disconnect_inputs (this);
1008                                         port_insert->disconnect_outputs (this);
1009                                 }
1010
1011                                 _redirects.erase (i);
1012
1013                                 i = tmp;
1014                                 removed = true;
1015                                 break;
1016                         }
1017                 }
1018
1019                 if (!removed) {
1020                         /* what? */
1021                         return 1;
1022                 }
1023
1024                 if (_reset_plugin_counts (err_streams)) {
1025                         /* get back to where we where */
1026                         _redirects.insert (i, redirect);
1027                         /* we know this will work, because it worked before :) */
1028                         _reset_plugin_counts (0);
1029                         return -1;
1030                 }
1031
1032                 bool foo = false;
1033
1034                 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
1035                         boost::shared_ptr<PluginInsert> pi;
1036                         
1037                         if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
1038                                 if (pi->is_generator()) {
1039                                         foo = true;
1040                                 }
1041                         }
1042                 }
1043
1044                 _have_internal_generator = foo;
1045         }
1046
1047         if (old_rmo != redirect_max_outs) {
1048                 reset_panner ();
1049         }
1050
1051         redirect->drop_references ();
1052
1053         redirects_changed (src); /* EMIT SIGNAL */
1054         return 0;
1055 }
1056
1057 int
1058 Route::reset_plugin_counts (uint32_t* lpc)
1059 {
1060         Glib::RWLock::WriterLock lm (redirect_lock);
1061         return _reset_plugin_counts (lpc);
1062 }
1063
1064
1065 int
1066 Route::_reset_plugin_counts (uint32_t* err_streams)
1067 {
1068         RedirectList::iterator r;
1069         uint32_t i_cnt;
1070         uint32_t s_cnt;
1071         map<Placement,list<InsertCount> > insert_map;
1072         nframes_t initial_streams;
1073
1074         redirect_max_outs = 0;
1075         i_cnt = 0;
1076         s_cnt = 0;
1077
1078         /* divide inserts up by placement so we get the signal flow
1079            properly modelled. we need to do this because the _redirects
1080            list is not sorted by placement, and because other reasons may 
1081            exist now or in the future for this separate treatment.
1082         */
1083         
1084         for (r = _redirects.begin(); r != _redirects.end(); ++r) {
1085
1086                 boost::shared_ptr<Insert> insert;
1087
1088                 /* do this here in case we bomb out before we get to the end of
1089                    this function.
1090                 */
1091
1092                 redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs);
1093
1094                 if ((insert = boost::dynamic_pointer_cast<Insert>(*r)) != 0) {
1095                         ++i_cnt;
1096                         insert_map[insert->placement()].push_back (InsertCount (insert));
1097
1098                         /* reset plugin counts back to one for now so
1099                            that we have a predictable, controlled
1100                            state to try to configure.
1101                         */
1102
1103                         boost::shared_ptr<PluginInsert> pi;
1104                 
1105                         if ((pi = boost::dynamic_pointer_cast<PluginInsert>(insert)) != 0) {
1106                                 pi->set_count (1);
1107                         }
1108
1109                 } else if (boost::dynamic_pointer_cast<Send> (*r) != 0) {
1110                         ++s_cnt;
1111                 }
1112         }
1113         
1114         if (i_cnt == 0) {
1115                 if (s_cnt) {
1116                         goto recompute;
1117                 } else {
1118                         return 0;
1119                 }
1120         }
1121
1122         /* Now process each placement in order, checking to see if we 
1123            can really do what has been requested.
1124         */
1125
1126         /* A: PreFader */
1127         
1128         if (check_some_plugin_counts (insert_map[PreFader], n_inputs (), err_streams)) {
1129                 return -1;
1130         }
1131
1132         /* figure out the streams that will feed into PreFader */
1133
1134         if (!insert_map[PreFader].empty()) {
1135                 InsertCount& ic (insert_map[PreFader].back());
1136                 initial_streams = ic.insert->compute_output_streams (ic.cnt);
1137         } else {
1138                 initial_streams = n_inputs ();
1139         }
1140
1141         /* B: PostFader */
1142
1143         if (check_some_plugin_counts (insert_map[PostFader], initial_streams, err_streams)) {
1144                 return -1;
1145         }
1146
1147         /* OK, everything can be set up correctly, so lets do it */
1148
1149         apply_some_plugin_counts (insert_map[PreFader]);
1150         apply_some_plugin_counts (insert_map[PostFader]);
1151
1152         /* recompute max outs of any redirect */
1153
1154   recompute:
1155
1156         redirect_max_outs = 0;
1157         RedirectList::iterator prev = _redirects.end();
1158
1159         for (r = _redirects.begin(); r != _redirects.end(); prev = r, ++r) {
1160                 boost::shared_ptr<Send> s;
1161
1162                 if ((s = boost::dynamic_pointer_cast<Send> (*r)) != 0) {
1163                         if (r == _redirects.begin()) {
1164                                 s->expect_inputs (n_inputs());
1165                         } else {
1166                                 s->expect_inputs ((*prev)->output_streams());
1167                         }
1168
1169                 } else {
1170                         
1171                         /* don't pay any attention to send output configuration, since it doesn't
1172                            affect the route.
1173                          */
1174
1175                         redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs);
1176                         
1177                 }
1178         }
1179
1180         /* we're done */
1181
1182         return 0;
1183 }                                  
1184
1185 int32_t
1186 Route::apply_some_plugin_counts (list<InsertCount>& iclist)
1187 {
1188         list<InsertCount>::iterator i;
1189
1190         for (i = iclist.begin(); i != iclist.end(); ++i) {
1191                 
1192                 if ((*i).insert->configure_io ((*i).cnt, (*i).in, (*i).out)) {
1193                         return -1;
1194                 }
1195                 /* make sure that however many we have, they are all active */
1196                 (*i).insert->activate ();
1197         }
1198
1199         return 0;
1200 }
1201
1202 int32_t
1203 Route::check_some_plugin_counts (list<InsertCount>& iclist, int32_t required_inputs, uint32_t* err_streams)
1204 {
1205         list<InsertCount>::iterator i;
1206         
1207         for (i = iclist.begin(); i != iclist.end(); ++i) {
1208
1209                 if (((*i).cnt = (*i).insert->can_support_input_configuration (required_inputs)) < 0) {
1210                         if (err_streams) {
1211                                 *err_streams = required_inputs;
1212                         }
1213                         return -1;
1214                 }
1215                 
1216                 (*i).in = required_inputs;
1217                 (*i).out = (*i).insert->compute_output_streams ((*i).cnt);
1218
1219                 required_inputs = (*i).out;
1220         }
1221
1222         return 0;
1223 }
1224
1225 int
1226 Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_streams)
1227 {
1228         uint32_t old_rmo = redirect_max_outs;
1229
1230         if (err_streams) {
1231                 *err_streams = 0;
1232         }
1233
1234         RedirectList to_be_deleted;
1235
1236         {
1237                 Glib::RWLock::WriterLock lm (redirect_lock);
1238                 RedirectList::iterator tmp;
1239                 RedirectList the_copy;
1240
1241                 the_copy = _redirects;
1242                 
1243                 /* remove all relevant redirects */
1244
1245                 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ) {
1246                         tmp = i;
1247                         ++tmp;
1248
1249                         if ((*i)->placement() == placement) {
1250                                 to_be_deleted.push_back (*i);
1251                                 _redirects.erase (i);
1252                         }
1253
1254                         i = tmp;
1255                 }
1256
1257                 /* now copy the relevant ones from "other" */
1258                 
1259                 for (RedirectList::const_iterator i = other._redirects.begin(); i != other._redirects.end(); ++i) {
1260                         if ((*i)->placement() == placement) {
1261                                 _redirects.push_back (Redirect::clone (*i));
1262                         }
1263                 }
1264
1265                 /* reset plugin stream handling */
1266
1267                 if (_reset_plugin_counts (err_streams)) {
1268
1269                         /* FAILED COPY ATTEMPT: we have to restore order */
1270
1271                         /* delete all cloned redirects */
1272
1273                         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ) {
1274
1275                                 tmp = i;
1276                                 ++tmp;
1277
1278                                 if ((*i)->placement() == placement) {
1279                                         _redirects.erase (i);
1280                                 }
1281                                 
1282                                 i = tmp;
1283                         }
1284
1285                         /* restore the natural order */
1286
1287                         _redirects = the_copy;
1288                         redirect_max_outs = old_rmo;
1289
1290                         /* we failed, even though things are OK again */
1291
1292                         return -1;
1293
1294                 } else {
1295                         
1296                         /* SUCCESSFUL COPY ATTEMPT: delete the redirects we removed pre-copy */
1297                         to_be_deleted.clear ();
1298                 }
1299         }
1300
1301         if (redirect_max_outs != old_rmo || old_rmo == 0) {
1302                 reset_panner ();
1303         }
1304
1305         redirects_changed (this); /* EMIT SIGNAL */
1306         return 0;
1307 }
1308
1309 void
1310 Route::all_redirects_flip ()
1311 {
1312         Glib::RWLock::ReaderLock lm (redirect_lock);
1313
1314         if (_redirects.empty()) {
1315                 return;
1316         }
1317
1318         bool first_is_on = _redirects.front()->active();
1319         
1320         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1321                 (*i)->set_active (!first_is_on, this);
1322         }
1323 }
1324
1325 /** Set all redirects with a given placement to a given active state.
1326  * @param p Placement of redirects to change.
1327  * @param state New active state for those redirects.
1328  */
1329 void
1330 Route::all_redirects_active (Placement p, bool state)
1331 {
1332         Glib::RWLock::ReaderLock lm (redirect_lock);
1333
1334         if (_redirects.empty()) {
1335                 return;
1336         }
1337
1338         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1339                 if ((*i)->placement() == p) {
1340                         (*i)->set_active (state, this);
1341                 }
1342         }
1343 }
1344
1345 struct RedirectSorter {
1346     bool operator() (boost::shared_ptr<const Redirect> a, boost::shared_ptr<const Redirect> b) {
1347             return a->sort_key() < b->sort_key();
1348     }
1349 };
1350
1351 int
1352 Route::sort_redirects (uint32_t* err_streams)
1353 {
1354         {
1355                 RedirectSorter comparator;
1356                 Glib::RWLock::WriterLock lm (redirect_lock);
1357                 uint32_t old_rmo = redirect_max_outs;
1358
1359                 /* the sweet power of C++ ... */
1360
1361                 RedirectList as_it_was_before = _redirects;
1362
1363                 _redirects.sort (comparator);
1364         
1365                 if (_reset_plugin_counts (err_streams)) {
1366                         _redirects = as_it_was_before;
1367                         redirect_max_outs = old_rmo;
1368                         return -1;
1369                 } 
1370         } 
1371
1372         reset_panner ();
1373         redirects_changed (this); /* EMIT SIGNAL */
1374
1375         return 0;
1376 }
1377
1378 XMLNode&
1379 Route::get_state()
1380 {
1381         return state(true);
1382 }
1383
1384 XMLNode&
1385 Route::get_template()
1386 {
1387         return state(false);
1388 }
1389
1390 XMLNode&
1391 Route::state(bool full_state)
1392 {
1393         XMLNode *node = new XMLNode("Route");
1394         RedirectList:: iterator i;
1395         char buf[32];
1396
1397         if (_flags) {
1398                 node->add_property("flags", enum_2_string (_flags));
1399         }
1400         
1401         node->add_property("default-type", _default_type.to_string());
1402
1403         node->add_property("active", _active?"yes":"no");
1404         node->add_property("muted", _muted?"yes":"no");
1405         node->add_property("soloed", _soloed?"yes":"no");
1406         node->add_property("phase-invert", _phase_invert?"yes":"no");
1407         node->add_property("mute-affects-pre-fader", _mute_affects_pre_fader?"yes":"no"); 
1408         node->add_property("mute-affects-post-fader", _mute_affects_post_fader?"yes":"no"); 
1409         node->add_property("mute-affects-control-outs", _mute_affects_control_outs?"yes":"no"); 
1410         node->add_property("mute-affects-main-outs", _mute_affects_main_outs?"yes":"no"); 
1411
1412         if (_edit_group) {
1413                 node->add_property("edit-group", _edit_group->name());
1414         }
1415         if (_mix_group) {
1416                 node->add_property("mix-group", _mix_group->name());
1417         }
1418
1419         string order_string;
1420         OrderKeys::iterator x = order_keys.begin(); 
1421
1422         while (x != order_keys.end()) {
1423                 order_string += string ((*x).first);
1424                 order_string += '=';
1425                 snprintf (buf, sizeof(buf), "%ld", (*x).second);
1426                 order_string += buf;
1427                 
1428                 ++x;
1429
1430                 if (x == order_keys.end()) {
1431                         break;
1432                 }
1433
1434                 order_string += ':';
1435         }
1436         node->add_property ("order-keys", order_string);
1437
1438         node->add_child_nocopy (IO::state (full_state));
1439         node->add_child_nocopy (_solo_control.get_state ());
1440         node->add_child_nocopy (_mute_control.get_state ());
1441
1442         XMLNode* remote_control_node = new XMLNode (X_("remote_control"));
1443         snprintf (buf, sizeof (buf), "%d", _remote_control_id);
1444         remote_control_node->add_property (X_("id"), buf);
1445         node->add_child_nocopy (*remote_control_node);
1446
1447         if (_control_outs) {
1448                 XMLNode* cnode = new XMLNode (X_("ControlOuts"));
1449                 cnode->add_child_nocopy (_control_outs->state (full_state));
1450                 node->add_child_nocopy (*cnode);
1451         }
1452
1453         if (_comment.length()) {
1454                 XMLNode *cmt = node->add_child ("Comment");
1455                 cmt->add_content (_comment);
1456         }
1457
1458         for (i = _redirects.begin(); i != _redirects.end(); ++i) {
1459                 node->add_child_nocopy((*i)->state (full_state));
1460         }
1461
1462         if (_extra_xml){
1463                 node->add_child_copy (*_extra_xml);
1464         }
1465         
1466         return *node;
1467 }
1468
1469 void
1470 Route::set_deferred_state ()
1471 {
1472         XMLNodeList nlist;
1473         XMLNodeConstIterator niter;
1474
1475         if (!deferred_state) {
1476                 return;
1477         }
1478
1479         nlist = deferred_state->children();
1480
1481         for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1482                 add_redirect_from_xml (**niter);
1483         }
1484
1485         delete deferred_state;
1486         deferred_state = 0;
1487 }
1488
1489 void
1490 Route::add_redirect_from_xml (const XMLNode& node)
1491 {
1492         const XMLProperty *prop;
1493
1494         if (node.name() == "Send") {
1495                 
1496
1497                 try {
1498                         boost::shared_ptr<Send> send (new Send (_session, node));
1499                         add_redirect (send, this);
1500                 } 
1501                 
1502                 catch (failed_constructor &err) {
1503                         error << _("Send construction failed") << endmsg;
1504                         return;
1505                 }
1506                 
1507         } else if (node.name() == "Insert") {
1508                 
1509                 try {
1510                         if ((prop = node.property ("type")) != 0) {
1511
1512                                 boost::shared_ptr<Insert> insert;
1513
1514                                 if (prop->value() == "ladspa" || prop->value() == "Ladspa" || prop->value() == "vst") {
1515
1516                                         insert.reset (new PluginInsert(_session, node));
1517                                         
1518                                 } else if (prop->value() == "port") {
1519
1520
1521                                         insert.reset (new PortInsert (_session, node));
1522
1523                                 } else {
1524
1525                                         error << string_compose(_("unknown Insert type \"%1\"; ignored"), prop->value()) << endmsg;
1526                                 }
1527
1528                                 add_redirect (insert, this);
1529                                 
1530                         } else {
1531                                 error << _("Insert XML node has no type property") << endmsg;
1532                         }
1533                 }
1534                 
1535                 catch (failed_constructor &err) {
1536                         warning << _("insert could not be created. Ignored.") << endmsg;
1537                         return;
1538                 }
1539         }
1540 }
1541
1542 int
1543 Route::set_state (const XMLNode& node)
1544 {
1545         return _set_state (node, true);
1546 }
1547
1548 int
1549 Route::_set_state (const XMLNode& node, bool call_base)
1550 {
1551         XMLNodeList nlist;
1552         XMLNodeConstIterator niter;
1553         XMLNode *child;
1554         XMLPropertyList plist;
1555         const XMLProperty *prop;
1556
1557         if (node.name() != "Route"){
1558                 error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
1559                 return -1;
1560         }
1561
1562         if ((prop = node.property (X_("flags"))) != 0) {
1563                 _flags = Flag (string_2_enum (prop->value(), _flags));
1564         } else {
1565                 _flags = Flag (0);
1566         }
1567         
1568         if ((prop = node.property (X_("default-type"))) != 0) {
1569                 _default_type = DataType(prop->value());
1570                 assert(_default_type != DataType::NIL);
1571         }
1572
1573         if ((prop = node.property (X_("phase-invert"))) != 0) {
1574                 set_phase_invert(prop->value()=="yes"?true:false, this);
1575         }
1576
1577         if ((prop = node.property (X_("active"))) != 0) {
1578                 set_active (prop->value() == "yes");
1579         }
1580
1581         if ((prop = node.property (X_("muted"))) != 0) {
1582                 bool yn = prop->value()=="yes"?true:false; 
1583
1584                 /* force reset of mute status */
1585
1586                 _muted = !yn;
1587                 set_mute(yn, this);
1588                 mute_gain = desired_mute_gain;
1589         }
1590
1591         if ((prop = node.property (X_("soloed"))) != 0) {
1592                 bool yn = prop->value()=="yes"?true:false; 
1593
1594                 /* force reset of solo status */
1595
1596                 _soloed = !yn;
1597                 set_solo (yn, this);
1598                 solo_gain = desired_solo_gain;
1599         }
1600
1601         if ((prop = node.property (X_("mute-affects-pre-fader"))) != 0) {
1602                 _mute_affects_pre_fader = (prop->value()=="yes")?true:false;
1603         }
1604
1605         if ((prop = node.property (X_("mute-affects-post-fader"))) != 0) {
1606                 _mute_affects_post_fader = (prop->value()=="yes")?true:false;
1607         }
1608
1609         if ((prop = node.property (X_("mute-affects-control-outs"))) != 0) {
1610                 _mute_affects_control_outs = (prop->value()=="yes")?true:false;
1611         }
1612
1613         if ((prop = node.property (X_("mute-affects-main-outs"))) != 0) {
1614                 _mute_affects_main_outs = (prop->value()=="yes")?true:false;
1615         }
1616
1617         if ((prop = node.property (X_("edit-group"))) != 0) {
1618                 RouteGroup* edit_group = _session.edit_group_by_name(prop->value());
1619                 if(edit_group == 0) {
1620                         error << string_compose(_("Route %1: unknown edit group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
1621                 } else {
1622                         set_edit_group(edit_group, this);
1623                 }
1624         }
1625
1626         if ((prop = node.property (X_("order-keys"))) != 0) {
1627
1628                 long n;
1629
1630                 string::size_type colon, equal;
1631                 string remaining = prop->value();
1632
1633                 while (remaining.length()) {
1634
1635                         if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
1636                                 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1637                                       << endmsg;
1638                         } else {
1639                                 if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) {
1640                                         error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1641                                               << endmsg;
1642                                 } else {
1643                                         set_order_key (remaining.substr (0, equal).c_str(), n);
1644                                 }
1645                         }
1646
1647                         colon = remaining.find_first_of (':');
1648
1649                         if (colon != string::npos) {
1650                                 remaining = remaining.substr (colon+1);
1651                         } else {
1652                                 break;
1653                         }
1654                 }
1655         }
1656
1657         nlist = node.children();
1658
1659         if (deferred_state) {
1660                 delete deferred_state;
1661         }
1662
1663         deferred_state = new XMLNode(X_("deferred state"));
1664
1665         /* set parent class properties before anything else */
1666
1667         for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1668
1669                 child = *niter;
1670
1671                 if (child->name() == IO::state_node_name && call_base) {
1672
1673                         IO::set_state (*child);
1674                         break;
1675                 }
1676         }
1677
1678         XMLNodeList redirect_nodes;
1679                         
1680         for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1681
1682                 child = *niter;
1683                         
1684                 if (child->name() == X_("Send") || child->name() == X_("Insert")) {
1685                         redirect_nodes.push_back(child);
1686                 }
1687
1688         }
1689
1690         _set_redirect_states(redirect_nodes);
1691
1692
1693         for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1694                 child = *niter;
1695                 // All redirects (sends and inserts) have been applied already
1696
1697                 if (child->name() == X_("Automation")) {
1698                         
1699                         if ((prop = child->property (X_("path"))) != 0)  {
1700                                 load_automation (prop->value());
1701                         }
1702
1703                 } else if (child->name() == X_("ControlOuts")) {
1704                         
1705                         string coutname = _name;
1706                         coutname += _("[control]");
1707
1708                         _control_outs = new IO (_session, coutname);
1709                         _control_outs->set_state (**(child->children().begin()));
1710
1711                 } else if (child->name() == X_("Comment")) {
1712
1713                         /* XXX this is a terrible API design in libxml++ */
1714
1715                         XMLNode *cmt = *(child->children().begin());
1716                         _comment = cmt->content();
1717
1718                 } else if (child->name() == X_("extra")) {
1719
1720                         _extra_xml = new XMLNode (*child);
1721
1722                 } else if (child->name() == X_("controllable") && (prop = child->property("name")) != 0) {
1723                         
1724                         if (prop->value() == "solo") {
1725                                 _solo_control.set_state (*child);
1726                                 _session.add_controllable (&_solo_control);
1727                         }
1728                         else if (prop->value() == "mute") {
1729                                 _mute_control.set_state (*child);
1730                                 _session.add_controllable (&_mute_control);
1731                         }
1732                 }
1733                 else if (child->name() == X_("remote_control")) {
1734                         if ((prop = child->property (X_("id"))) != 0) {
1735                                 int32_t x;
1736                                 sscanf (prop->value().c_str(), "%d", &x);
1737                                 set_remote_control_id (x);
1738                         }
1739                 }
1740         }
1741
1742         if ((prop = node.property (X_("mix-group"))) != 0) {
1743                 RouteGroup* mix_group = _session.mix_group_by_name(prop->value());
1744                 if (mix_group == 0) {
1745                         error << string_compose(_("Route %1: unknown mix group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
1746                 }  else {
1747                         set_mix_group(mix_group, this);
1748                 }
1749         }
1750
1751         return 0;
1752 }
1753
1754 void
1755 Route::_set_redirect_states(const XMLNodeList &nlist)
1756 {
1757         XMLNodeConstIterator niter;
1758         char buf[64];
1759
1760         RedirectList::iterator i, o;
1761
1762         // Iterate through existing redirects, remove those which are not in the state list
1763         for (i = _redirects.begin(); i != _redirects.end(); ) {
1764                 RedirectList::iterator tmp = i;
1765                 ++tmp;
1766
1767                 bool redirectInStateList = false;
1768         
1769                 (*i)->id().print (buf, sizeof (buf));
1770
1771
1772                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1773
1774                         if (strncmp(buf,(*niter)->child(X_("Redirect"))->child(X_("IO"))->property(X_("id"))->value().c_str(), sizeof(buf)) == 0) {
1775                                 redirectInStateList = true;
1776                                 break;
1777                         }
1778                 }
1779                 
1780                 if (!redirectInStateList) {
1781                         remove_redirect ( *i, this);
1782                 }
1783
1784
1785                 i = tmp;
1786         }
1787
1788
1789         // Iterate through state list and make sure all redirects are on the track and in the correct order,
1790         // set the state of existing redirects according to the new state on the same go
1791         i = _redirects.begin();
1792         for (niter = nlist.begin(); niter != nlist.end(); ++niter, ++i) {
1793
1794                 // Check whether the next redirect in the list 
1795                 o = i;
1796
1797                 while (o != _redirects.end()) {
1798                         (*o)->id().print (buf, sizeof (buf));
1799                         if ( strncmp(buf, (*niter)->child(X_("Redirect"))->child(X_("IO"))->property(X_("id"))->value().c_str(), sizeof(buf)) == 0)
1800                                 break;
1801                         ++o;
1802                 }
1803
1804                 if (o == _redirects.end()) {
1805                         // If the redirect (*niter) is not on the route, we need to create it
1806                         // and move it to the correct location
1807
1808                         RedirectList::iterator prev_last = _redirects.end();
1809                         --prev_last; // We need this to check whether adding succeeded
1810                         
1811                         add_redirect_from_xml (**niter);
1812
1813                         RedirectList::iterator last = _redirects.end();
1814                         --last;
1815
1816                         if (prev_last == last) {
1817                                 cerr << "Could not fully restore state as some redirects were not possible to create" << endl;
1818                                 continue;
1819
1820                         }
1821
1822                         boost::shared_ptr<Redirect> tmp = (*last);
1823                         // remove the redirect from the wrong location
1824                         _redirects.erase(last);
1825                         // insert the new redirect at the current location
1826                         _redirects.insert(i, tmp);
1827
1828                         --i; // move pointer to the newly inserted redirect
1829                         continue;
1830                 }
1831
1832                 // We found the redirect (*niter) on the route, first we must make sure the redirect
1833                 // is at the location provided in the XML state
1834                 if (i != o) {
1835                         boost::shared_ptr<Redirect> tmp = (*o);
1836                         // remove the old copy
1837                         _redirects.erase(o);
1838                         // insert the redirect at the correct location
1839                         _redirects.insert(i, tmp);
1840
1841                         --i; // move pointer so it points to the right redirect
1842                 }
1843
1844                 (*i)->set_state( (**niter) );
1845         }
1846         
1847         redirects_changed(this);
1848 }
1849
1850 void
1851 Route::curve_reallocate ()
1852 {
1853 //      _gain_automation_curve.finish_resize ();
1854 //      _pan_automation_curve.finish_resize ();
1855 }
1856
1857 void
1858 Route::silence (nframes_t nframes, nframes_t offset)
1859 {
1860         if (!_silent) {
1861
1862                 // reset_peak_meters ();
1863                 
1864                 IO::silence (nframes, offset);
1865
1866                 if (_control_outs) {
1867                         _control_outs->silence (nframes, offset);
1868                 }
1869
1870                 { 
1871                         Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
1872                         
1873                         if (lm.locked()) {
1874                                 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1875                                         boost::shared_ptr<PluginInsert> pi;
1876                                         if (!_active && (pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
1877                                                 // skip plugins, they don't need anything when we're not active
1878                                                 continue;
1879                                         }
1880
1881                                         (*i)->silence (nframes, offset);
1882                                 }
1883
1884                                 if (nframes == _session.get_block_size() && offset == 0) {
1885                                         // _silent = true;
1886                                 }
1887                         }
1888                 }
1889                 
1890         }
1891 }       
1892
1893 int
1894 Route::set_control_outs (const vector<string>& ports)
1895 {
1896         Glib::Mutex::Lock lm (control_outs_lock);
1897         vector<string>::const_iterator i;
1898         uint32_t limit;
1899
1900         if (_control_outs) {
1901                 delete _control_outs;
1902                 _control_outs = 0;
1903         }
1904
1905         if (control() || master()) {
1906                 /* no control outs for these two special busses */
1907                 return 0;
1908         }
1909         
1910         if (ports.empty()) {
1911                 return 0;
1912         }
1913  
1914         string coutname = _name;
1915         coutname += _("[control]");
1916         
1917         _control_outs = new IO (_session, coutname);
1918
1919         /* our control outs need as many outputs as we
1920            have outputs. we track the changes in ::output_change_handler().
1921         */
1922
1923         limit = n_outputs ();
1924
1925         if (_control_outs->ensure_io (0, limit, true, this)) {
1926                 return -1;
1927         }
1928
1929         /* now connect to the named ports */
1930
1931         for (uint32_t n = 0; n < limit; ++n) {
1932                 if (_control_outs->connect_output (_control_outs->output (n), ports[n], this)) {
1933                         error << string_compose (_("could not connect %1 to %2"), _control_outs->output(n)->name(), ports[n]) << endmsg;
1934                         return -1;
1935                 }
1936         }
1937  
1938         return 0;
1939 }       
1940
1941 void
1942 Route::set_edit_group (RouteGroup *eg, void *src)
1943
1944 {
1945         if (eg == _edit_group) {
1946                 return;
1947         }
1948
1949         if (_edit_group) {
1950                 _edit_group->remove (this);
1951         }
1952
1953         if ((_edit_group = eg) != 0) {
1954                 _edit_group->add (this);
1955         }
1956
1957         _session.set_dirty ();
1958         edit_group_changed (src); /* EMIT SIGNAL */
1959 }
1960
1961 void
1962 Route::drop_edit_group (void *src)
1963 {
1964         _edit_group = 0;
1965         _session.set_dirty ();
1966         edit_group_changed (src); /* EMIT SIGNAL */
1967 }
1968
1969 void
1970 Route::set_mix_group (RouteGroup *mg, void *src)
1971
1972 {
1973         if (mg == _mix_group) {
1974                 return;
1975         }
1976
1977         if (_mix_group) {
1978                 _mix_group->remove (this);
1979         }
1980
1981         if ((_mix_group = mg) != 0) {
1982                 _mix_group->add (this);
1983         }
1984
1985         _session.set_dirty ();
1986         mix_group_changed (src); /* EMIT SIGNAL */
1987 }
1988
1989 void
1990 Route::drop_mix_group (void *src)
1991 {
1992         _mix_group = 0;
1993         _session.set_dirty ();
1994         mix_group_changed (src); /* EMIT SIGNAL */
1995 }
1996
1997 void
1998 Route::set_comment (string cmt, void *src)
1999 {
2000         _comment = cmt;
2001         comment_changed (src);
2002         _session.set_dirty ();
2003 }
2004
2005 bool
2006 Route::feeds (boost::shared_ptr<Route> other)
2007 {
2008         uint32_t i, j;
2009
2010         IO& self = *this;
2011         uint32_t no = self.n_outputs();
2012         uint32_t ni = other->n_inputs ();
2013
2014         for (i = 0; i < no; ++i) {
2015                 for (j = 0; j < ni; ++j) {
2016                         if (self.output(i)->connected_to (other->input(j)->name())) {
2017                                 return true;
2018                         }
2019                 }
2020         }
2021
2022         /* check Redirects which may also interconnect Routes */
2023
2024         for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); r++) {
2025
2026                 no = (*r)->n_outputs();
2027
2028                 for (i = 0; i < no; ++i) {
2029                         for (j = 0; j < ni; ++j) {
2030                                 if ((*r)->output(i)->connected_to (other->input (j)->name())) {
2031                                         return true;
2032                                 }
2033                         }
2034                 }
2035         }
2036
2037         /* check for control room outputs which may also interconnect Routes */
2038
2039         if (_control_outs) {
2040
2041                 no = _control_outs->n_outputs();
2042                 
2043                 for (i = 0; i < no; ++i) {
2044                         for (j = 0; j < ni; ++j) {
2045                                 if (_control_outs->output(i)->connected_to (other->input (j)->name())) {
2046                                         return true;
2047                                 }
2048                         }
2049                 }
2050         }
2051
2052         return false;
2053 }
2054
2055 void
2056 Route::set_mute_config (mute_type t, bool onoff, void *src)
2057 {
2058         switch (t) {
2059         case PRE_FADER:
2060                 _mute_affects_pre_fader = onoff;
2061                  pre_fader_changed(src); /* EMIT SIGNAL */
2062                 break;
2063
2064         case POST_FADER:
2065                 _mute_affects_post_fader = onoff;
2066                  post_fader_changed(src); /* EMIT SIGNAL */
2067                 break;
2068
2069         case CONTROL_OUTS:
2070                 _mute_affects_control_outs = onoff;
2071                  control_outs_changed(src); /* EMIT SIGNAL */
2072                 break;
2073
2074         case MAIN_OUTS:
2075                 _mute_affects_main_outs = onoff;
2076                  main_outs_changed(src); /* EMIT SIGNAL */
2077                 break;
2078         }
2079 }
2080
2081 bool
2082 Route::get_mute_config (mute_type t)
2083 {
2084         bool onoff = false;
2085         
2086         switch (t){
2087         case PRE_FADER:
2088                 onoff = _mute_affects_pre_fader; 
2089                 break;
2090         case POST_FADER:
2091                 onoff = _mute_affects_post_fader;
2092                 break;
2093         case CONTROL_OUTS:
2094                 onoff = _mute_affects_control_outs;
2095                 break;
2096         case MAIN_OUTS:
2097                 onoff = _mute_affects_main_outs;
2098                 break;
2099         }
2100         
2101         return onoff;
2102 }
2103
2104 void
2105 Route::set_active (bool yn)
2106 {
2107         _active = yn; 
2108          active_changed(); /* EMIT SIGNAL */
2109 }
2110
2111 void
2112 Route::handle_transport_stopped (bool abort_ignored, bool did_locate, bool can_flush_redirects)
2113 {
2114         nframes_t now = _session.transport_frame();
2115
2116         {
2117                 Glib::RWLock::ReaderLock lm (redirect_lock);
2118
2119                 if (!did_locate) {
2120                         automation_snapshot (now);
2121                 }
2122
2123                 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2124                         
2125                         if (Config->get_plugins_stop_with_transport() && can_flush_redirects) {
2126                                 (*i)->deactivate ();
2127                                 (*i)->activate ();
2128                         }
2129                         
2130                         (*i)->transport_stopped (now);
2131                 }
2132         }
2133
2134         IO::transport_stopped (now);
2135  
2136         _roll_delay = _initial_delay;
2137 }
2138
2139 void
2140 Route::input_change_handler (IOChange change, void *ignored)
2141 {
2142         if (change & ConfigurationChanged) {
2143                 reset_plugin_counts (0);
2144         }
2145 }
2146
2147 void
2148 Route::output_change_handler (IOChange change, void *ignored)
2149 {
2150         if (change & ConfigurationChanged) {
2151                 if (_control_outs) {
2152                         _control_outs->ensure_io (0, n_outputs(), true, this);
2153                 }
2154                 
2155                 reset_plugin_counts (0);
2156         }
2157 }
2158
2159 uint32_t
2160 Route::pans_required () const
2161 {
2162         if (n_outputs() < 2) {
2163                 return 0;
2164         }
2165         
2166         return max (n_inputs (), redirect_max_outs);
2167 }
2168
2169 int 
2170 Route::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, 
2171                    bool session_state_changing, bool can_record, bool rec_monitors_input)
2172 {
2173         if (n_outputs() == 0) {
2174                 return 0;
2175         }
2176
2177         if (session_state_changing || !_active)  {
2178                 silence (nframes, offset);
2179                 return 0;
2180         }
2181
2182         apply_gain_automation = false;
2183         
2184         if (n_inputs()) {
2185                 passthru (start_frame, end_frame, nframes, offset, 0, false);
2186         } else {
2187                 silence (nframes, offset);
2188         }
2189
2190         return 0;
2191 }
2192
2193 nframes_t
2194 Route::check_initial_delay (nframes_t nframes, nframes_t& offset, nframes_t& transport_frame)
2195 {
2196         if (_roll_delay > nframes) {
2197
2198                 _roll_delay -= nframes;
2199                 silence (nframes, offset);
2200                 /* transport frame is not legal for caller to use */
2201                 return 0;
2202
2203         } else if (_roll_delay > 0) {
2204
2205                 nframes -= _roll_delay;
2206
2207                 silence (_roll_delay, offset);
2208
2209                 offset += _roll_delay;
2210                 transport_frame += _roll_delay;
2211
2212                 _roll_delay = 0;
2213         }
2214
2215         return nframes;
2216 }
2217
2218 int
2219 Route::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, int declick,
2220              bool can_record, bool rec_monitors_input)
2221 {
2222         {
2223                 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
2224                 if (lm.locked()) {
2225                         // automation snapshot can also be called from the non-rt context
2226                         // and it uses the redirect list, so we take the lock out here
2227                         automation_snapshot (_session.transport_frame());
2228                 }
2229         }
2230
2231         if ((n_outputs() == 0 && _redirects.empty()) || n_inputs() == 0 || !_active) {
2232                 silence (nframes, offset);
2233                 return 0;
2234         }
2235         
2236         nframes_t unused = 0;
2237
2238         if ((nframes = check_initial_delay (nframes, offset, unused)) == 0) {
2239                 return 0;
2240         }
2241
2242         _silent = false;
2243
2244         apply_gain_automation = false;
2245
2246         { 
2247                 Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK);
2248                 
2249                 if (am.locked() && _session.transport_rolling()) {
2250                         
2251                         nframes_t start_frame = end_frame - nframes;
2252                         
2253                         if (gain_automation_playback()) {
2254                                 apply_gain_automation = _gain_automation_curve.rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes);
2255                         }
2256                 }
2257         }
2258
2259         passthru (start_frame, end_frame, nframes, offset, declick, false);
2260
2261         return 0;
2262 }
2263
2264 int
2265 Route::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, 
2266                     bool can_record, bool rec_monitors_input)
2267 {
2268         silence (nframes, offset);
2269         return 0;
2270 }
2271
2272 void
2273 Route::toggle_monitor_input ()
2274 {
2275         for (vector<Port*>::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
2276                 (*i)->ensure_monitor_input(!(*i)->monitoring_input());
2277         }
2278 }
2279
2280 bool
2281 Route::has_external_redirects () const
2282 {
2283         boost::shared_ptr<const PortInsert> pi;
2284         
2285         for (RedirectList::const_iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2286                 if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*i)) != 0) {
2287
2288                         uint32_t no = pi->n_outputs();
2289
2290                         for (uint32_t n = 0; n < no; ++n) {
2291                                 
2292                                 string port_name = pi->output(n)->name();
2293                                 string client_name = port_name.substr (0, port_name.find(':'));
2294
2295                                 /* only say "yes" if the redirect is actually in use */
2296                                 
2297                                 if (client_name != "ardour" && pi->active()) {
2298                                         return true;
2299                                 }
2300                         }
2301                 }
2302         }
2303
2304         return false;
2305 }
2306
2307 void
2308 Route::flush_redirects ()
2309 {
2310         /* XXX shouldn't really try to take this lock, since
2311            this is called from the RT audio thread.
2312         */
2313
2314         Glib::RWLock::ReaderLock lm (redirect_lock);
2315
2316         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2317                 (*i)->deactivate ();
2318                 (*i)->activate ();
2319         }
2320 }
2321
2322 void
2323 Route::set_meter_point (MeterPoint p, void *src)
2324 {
2325         if (_meter_point != p) {
2326                 _meter_point = p;
2327                  meter_change (src); /* EMIT SIGNAL */
2328                 _session.set_dirty ();
2329         }
2330 }
2331
2332 nframes_t
2333 Route::update_total_latency ()
2334 {
2335         _own_latency = 0;
2336
2337         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2338                 if ((*i)->active ()) {
2339                         _own_latency += (*i)->latency ();
2340                 }
2341         }
2342
2343         set_port_latency (_own_latency);
2344
2345         /* this (virtual) function is used for pure Routes,
2346            not derived classes like AudioTrack.  this means
2347            that the data processed here comes from an input
2348            port, not prerecorded material, and therefore we
2349            have to take into account any input latency.
2350         */
2351
2352         _own_latency += input_latency ();
2353
2354         return _own_latency;
2355 }
2356
2357 void
2358 Route::set_latency_delay (nframes_t longest_session_latency)
2359 {
2360         _initial_delay = longest_session_latency - _own_latency;
2361
2362         if (_session.transport_stopped()) {
2363                 _roll_delay = _initial_delay;
2364         }
2365 }
2366
2367 void
2368 Route::automation_snapshot (nframes_t now)
2369 {
2370         IO::automation_snapshot (now);
2371
2372         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2373                 (*i)->automation_snapshot (now);
2374         }
2375 }
2376
2377 Route::ToggleControllable::ToggleControllable (std::string name, Route& s, ToggleType tp)
2378         : Controllable (name), route (s), type(tp)
2379 {
2380         
2381 }
2382
2383 void
2384 Route::ToggleControllable::set_value (float val)
2385 {
2386         bool bval = ((val >= 0.5f) ? true: false);
2387         
2388         switch (type) {
2389         case MuteControl:
2390                 route.set_mute (bval, this);
2391                 break;
2392         case SoloControl:
2393                 route.set_solo (bval, this);
2394                 break;
2395         default:
2396                 break;
2397         }
2398 }
2399
2400 float
2401 Route::ToggleControllable::get_value (void) const
2402 {
2403         float val = 0.0f;
2404         
2405         switch (type) {
2406         case MuteControl:
2407                 val = route.muted() ? 1.0f : 0.0f;
2408                 break;
2409         case SoloControl:
2410                 val = route.soloed() ? 1.0f : 0.0f;
2411                 break;
2412         default:
2413                 break;
2414         }
2415
2416         return val;
2417 }
2418
2419 void 
2420 Route::set_block_size (nframes_t nframes)
2421 {
2422         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2423                 (*i)->set_block_size (nframes);
2424         }
2425 }
2426
2427 void
2428 Route::redirect_active_proxy (Redirect* ignored, void* ignored_src)
2429 {
2430         _session.update_latency_compensation (false, false);
2431 }
2432
2433 void
2434 Route::protect_automation ()
2435 {
2436         switch (gain_automation_state()) {
2437         case Write:
2438                 set_gain_automation_state (Off);
2439         case Touch:
2440                 set_gain_automation_state (Play);
2441                 break;
2442         default:
2443                 break;
2444         }
2445
2446         switch (panner().automation_state ()) {
2447         case Write:
2448                 panner().set_automation_state (Off);
2449                 break;
2450         case Touch:
2451                 panner().set_automation_state (Play);
2452                 break;
2453         default:
2454                 break;
2455         }
2456         
2457         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2458                 boost::shared_ptr<PluginInsert> pi;
2459                 if ((pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
2460                         pi->protect_automation ();
2461                 }
2462         }
2463 }
2464
2465 void
2466 Route::set_pending_declick (int declick)
2467 {
2468         if (_declickable) {
2469                 /* this call is not allowed to turn off a pending declick unless "force" is true */
2470                 if (declick) {
2471                         _pending_declick = declick;
2472                 }
2473                 // cerr << _name << ": after setting to " << declick << " pending declick = " << _pending_declick << endl;
2474         } else {
2475                 _pending_declick = 0;
2476         }
2477
2478 }