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