MIDI metering.
[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         if (meter_first) {
703                 _meter->run(bufs, nframes);
704                 meter_first = false;
705         }
706                 
707         process_output_buffers (bufs, start_frame, end_frame, nframes, offset, true, declick, meter_first);
708 }
709
710 void
711 Route::passthru_silence (nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset, int declick, bool meter)
712 {
713         process_output_buffers (_session.get_silent_buffers (n_process_buffers()), start_frame, end_frame, nframes, offset, true, declick, meter);
714 }
715
716 void
717 Route::set_solo (bool yn, void *src)
718 {
719         if (_solo_safe) {
720                 return;
721         }
722
723         if (_mix_group && src != _mix_group && _mix_group->is_active()) {
724                 _mix_group->apply (&Route::set_solo, yn, _mix_group);
725                 return;
726         }
727
728         if (_soloed != yn) {
729                 _soloed = yn;
730                 solo_changed (src); /* EMIT SIGNAL */
731                 _solo_control.Changed (); /* EMIT SIGNAL */
732         }
733 }
734
735 void
736 Route::set_solo_mute (bool yn)
737 {
738         Glib::Mutex::Lock lm (declick_lock);
739
740         /* Called by Session in response to another Route being soloed.
741          */
742            
743         desired_solo_gain = (yn?0.0:1.0);
744 }
745
746 void
747 Route::set_solo_safe (bool yn, void *src)
748 {
749         if (_solo_safe != yn) {
750                 _solo_safe = yn;
751                  solo_safe_changed (src); /* EMIT SIGNAL */
752         }
753 }
754
755 void
756 Route::set_mute (bool yn, void *src)
757
758 {
759         if (_mix_group && src != _mix_group && _mix_group->is_active()) {
760                 _mix_group->apply (&Route::set_mute, yn, _mix_group);
761                 return;
762         }
763
764         if (_muted != yn) {
765                 _muted = yn;
766                 mute_changed (src); /* EMIT SIGNAL */
767                 
768                 _mute_control.Changed (); /* EMIT SIGNAL */
769                 
770                 Glib::Mutex::Lock lm (declick_lock);
771                 desired_mute_gain = (yn?0.0f:1.0f);
772         }
773 }
774
775 int
776 Route::add_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
777 {
778         ChanCount old_rmo = redirect_max_outs;
779
780         if (!_session.engine().connected()) {
781                 return 1;
782         }
783
784         {
785                 Glib::RWLock::WriterLock lm (redirect_lock);
786
787                 boost::shared_ptr<PluginInsert> pi;
788                 boost::shared_ptr<PortInsert> porti;
789
790                 redirect->set_default_type(_default_type);
791
792                 if ((pi = boost::dynamic_pointer_cast<PluginInsert>(redirect)) != 0) {
793                         pi->set_count (1);
794
795                         if (pi->input_streams() == ChanCount::ZERO) {
796                                 /* generator plugin */
797                                 _have_internal_generator = true;
798                         }
799                         
800                 } else if ((porti = boost::dynamic_pointer_cast<PortInsert>(redirect)) != 0) {
801
802                         /* force new port inserts to start out with an i/o configuration
803                            that matches this route's i/o configuration.
804
805                            the "inputs" for the port are supposed to match the output
806                            of this route.
807
808                            the "outputs" of the route should match the inputs of this
809                            route. XXX shouldn't they match the number of active signal
810                            streams at the point of insertion?
811                         */
812                         // FIXME: (yes, they should)
813
814                         porti->ensure_io (n_outputs (), n_inputs(), false, this);
815                 }
816                 
817                 // Ensure peak vector sizes before the plugin is activated
818                 ChanCount potential_max_streams = max(redirect->input_streams(), redirect->output_streams());
819                 _meter->setup(potential_max_streams);
820
821                 _redirects.push_back (redirect);
822
823                 if (_reset_plugin_counts (err_streams)) {
824                         _redirects.pop_back ();
825                         _reset_plugin_counts (0); // it worked before we tried to add it ...
826                         return -1;
827                 }
828
829                 redirect->activate ();
830                 redirect->active_changed.connect (mem_fun (*this, &Route::redirect_active_proxy));
831         }
832         
833         if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
834                 reset_panner ();
835         }
836
837
838         redirects_changed (src); /* EMIT SIGNAL */
839         return 0;
840 }
841
842 int
843 Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_streams)
844 {
845         ChanCount old_rmo = redirect_max_outs;
846
847         if (!_session.engine().connected()) {
848                 return 1;
849         }
850
851         {
852                 Glib::RWLock::WriterLock lm (redirect_lock);
853
854                 RedirectList::iterator existing_end = _redirects.end();
855                 --existing_end;
856
857                 ChanCount potential_max_streams;
858
859                 for (RedirectList::const_iterator i = others.begin(); i != others.end(); ++i) {
860                         
861                         boost::shared_ptr<PluginInsert> pi;
862                         
863                         if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
864                                 pi->set_count (1);
865                                 
866                                 ChanCount m = max(pi->input_streams(), pi->output_streams());
867                                 if (m > potential_max_streams)
868                                         potential_max_streams = m;
869                         }
870
871                         // Ensure peak vector sizes before the plugin is activated
872                         _meter->setup(potential_max_streams);
873
874                         _redirects.push_back (*i);
875                         
876                         if (_reset_plugin_counts (err_streams)) {
877                                 ++existing_end;
878                                 _redirects.erase (existing_end, _redirects.end());
879                                 _reset_plugin_counts (0); // it worked before we tried to add it ...
880                                 return -1;
881                         }
882                         
883                         (*i)->activate ();
884                         (*i)->active_changed.connect (mem_fun (*this, &Route::redirect_active_proxy));
885                 }
886         }
887         
888         if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
889                 reset_panner ();
890         }
891
892         redirects_changed (src); /* EMIT SIGNAL */
893         return 0;
894 }
895
896 /** Turn off all redirects with a given placement
897  * @param p Placement of redirects to disable
898  */
899
900 void
901 Route::disable_redirects (Placement p)
902 {
903         Glib::RWLock::ReaderLock lm (redirect_lock);
904         
905         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
906                 if ((*i)->placement() == p) {
907                         (*i)->set_active (false, this);
908                 }
909         }
910 }
911
912 /** Turn off all redirects 
913  */
914
915 void
916 Route::disable_redirects ()
917 {
918         Glib::RWLock::ReaderLock lm (redirect_lock);
919         
920         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
921                 (*i)->set_active (false, this);
922         }
923 }
924
925 /** Turn off all redirects with a given placement
926  * @param p Placement of redirects to disable
927  */
928
929 void
930 Route::disable_plugins (Placement p)
931 {
932         Glib::RWLock::ReaderLock lm (redirect_lock);
933         
934         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
935                 if (boost::dynamic_pointer_cast<PluginInsert> (*i) && (*i)->placement() == p) {
936                         (*i)->set_active (false, this);
937                 }
938         }
939 }
940
941 /** Turn off all plugins
942  */
943
944 void
945 Route::disable_plugins ()
946 {
947         Glib::RWLock::ReaderLock lm (redirect_lock);
948         
949         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
950                 if (boost::dynamic_pointer_cast<PluginInsert> (*i)) {
951                         (*i)->set_active (false, this);
952                 }
953         }
954 }
955
956
957 void
958 Route::ab_plugins (bool forward)
959 {
960         Glib::RWLock::ReaderLock lm (redirect_lock);
961                         
962         if (forward) {
963
964                 /* forward = turn off all active redirects, and mark them so that the next time
965                    we go the other way, we will revert them
966                 */
967
968                 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
969                         if (!boost::dynamic_pointer_cast<PluginInsert> (*i)) {
970                                 continue;
971                         }
972
973                         if ((*i)->active()) {
974                                 (*i)->set_active (false, this);
975                                 (*i)->set_next_ab_is_active (true);
976                         } else {
977                                 (*i)->set_next_ab_is_active (false);
978                         }
979                 }
980
981         } else {
982
983                 /* backward = if the redirect was marked to go active on the next ab, do so */
984
985                 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
986
987                         if (!boost::dynamic_pointer_cast<PluginInsert> (*i)) {
988                                 continue;
989                         }
990
991                         if ((*i)->get_next_ab_is_active()) {
992                                 (*i)->set_active (true, this);
993                         } else {
994                                 (*i)->set_active (false, this);
995                         }
996                 }
997         }
998 }
999
1000 /** Remove redirects with a given placement.
1001  * @param p Placement of redirects to remove.
1002  */
1003 void
1004 Route::clear_redirects (Placement p, void *src)
1005 {
1006         const ChanCount old_rmo = redirect_max_outs;
1007
1008         if (!_session.engine().connected()) {
1009                 return;
1010         }
1011
1012         {
1013                 Glib::RWLock::WriterLock lm (redirect_lock);
1014                 RedirectList new_list;
1015                 
1016                 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1017                         if ((*i)->placement() == p) {
1018                                 /* it's the placement we want to get rid of */
1019                                 (*i)->drop_references ();
1020                         } else {
1021                                 /* it's a different placement, so keep it */
1022                                 new_list.push_back (*i);
1023                         }
1024                 }
1025                 
1026                 _redirects = new_list;
1027         }
1028
1029         /* FIXME: can't see how this test can ever fire */
1030         if (redirect_max_outs != old_rmo) {
1031                 reset_panner ();
1032         }
1033         
1034         redirect_max_outs.reset();
1035         _have_internal_generator = false;
1036         redirects_changed (src); /* EMIT SIGNAL */
1037 }
1038
1039 int
1040 Route::remove_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
1041 {
1042         ChanCount old_rmo = redirect_max_outs;
1043
1044         if (!_session.engine().connected()) {
1045                 return 1;
1046         }
1047
1048         redirect_max_outs.reset();
1049
1050         {
1051                 Glib::RWLock::WriterLock lm (redirect_lock);
1052                 RedirectList::iterator i;
1053                 bool removed = false;
1054
1055                 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
1056                         if (*i == redirect) {
1057
1058                                 RedirectList::iterator tmp;
1059
1060                                 /* move along, see failure case for reset_plugin_counts()
1061                                    where we may need to reinsert the redirect.
1062                                 */
1063
1064                                 tmp = i;
1065                                 ++tmp;
1066
1067                                 /* stop redirects that send signals to JACK ports
1068                                    from causing noise as a result of no longer being
1069                                    run.
1070                                 */
1071
1072                                 boost::shared_ptr<Send> send;
1073                                 boost::shared_ptr<PortInsert> port_insert;
1074                                 
1075                                 if ((send = boost::dynamic_pointer_cast<Send> (*i)) != 0) {
1076                                         send->disconnect_inputs (this);
1077                                         send->disconnect_outputs (this);
1078                                 } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (*i)) != 0) {
1079                                         port_insert->disconnect_inputs (this);
1080                                         port_insert->disconnect_outputs (this);
1081                                 }
1082
1083                                 _redirects.erase (i);
1084
1085                                 i = tmp;
1086                                 removed = true;
1087                                 break;
1088                         }
1089                 }
1090
1091                 if (!removed) {
1092                         /* what? */
1093                         return 1;
1094                 }
1095
1096                 if (_reset_plugin_counts (err_streams)) {
1097                         /* get back to where we where */
1098                         _redirects.insert (i, redirect);
1099                         /* we know this will work, because it worked before :) */
1100                         _reset_plugin_counts (0);
1101                         return -1;
1102                 }
1103
1104                 bool foo = false;
1105
1106                 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
1107                         boost::shared_ptr<PluginInsert> pi;
1108                         
1109                         if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
1110                                 if (pi->is_generator()) {
1111                                         foo = true;
1112                                 }
1113                         }
1114                 }
1115
1116                 _have_internal_generator = foo;
1117         }
1118
1119         if (old_rmo != redirect_max_outs) {
1120                 reset_panner ();
1121         }
1122
1123         redirect->drop_references ();
1124
1125         redirects_changed (src); /* EMIT SIGNAL */
1126         return 0;
1127 }
1128
1129 int
1130 Route::reset_plugin_counts (uint32_t* lpc)
1131 {
1132         Glib::RWLock::WriterLock lm (redirect_lock);
1133         return _reset_plugin_counts (lpc);
1134 }
1135
1136
1137 int
1138 Route::_reset_plugin_counts (uint32_t* err_streams)
1139 {
1140         RedirectList::iterator r;
1141         uint32_t i_cnt;
1142         uint32_t s_cnt;
1143         map<Placement,list<InsertCount> > insert_map;
1144         nframes_t initial_streams;
1145
1146         redirect_max_outs.reset();
1147         i_cnt = 0;
1148         s_cnt = 0;
1149
1150         /* divide inserts up by placement so we get the signal flow
1151            properly modelled. we need to do this because the _redirects
1152            list is not sorted by placement, and because other reasons may 
1153            exist now or in the future for this separate treatment.
1154         */
1155         
1156         for (r = _redirects.begin(); r != _redirects.end(); ++r) {
1157
1158                 boost::shared_ptr<Insert> insert;
1159
1160                 /* do this here in case we bomb out before we get to the end of
1161                    this function.
1162                 */
1163
1164                 redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs);
1165
1166                 if ((insert = boost::dynamic_pointer_cast<Insert>(*r)) != 0) {
1167                         ++i_cnt;
1168                         insert_map[insert->placement()].push_back (InsertCount (insert));
1169
1170                         /* reset plugin counts back to one for now so
1171                            that we have a predictable, controlled
1172                            state to try to configure.
1173                         */
1174
1175                         boost::shared_ptr<PluginInsert> pi;
1176                 
1177                         if ((pi = boost::dynamic_pointer_cast<PluginInsert>(insert)) != 0) {
1178                                 pi->set_count (1);
1179                         }
1180
1181                 } else if (boost::dynamic_pointer_cast<Send> (*r) != 0) {
1182                         ++s_cnt;
1183                 }
1184         }
1185         
1186         if (i_cnt == 0) {
1187                 if (s_cnt) {
1188                         goto recompute;
1189                 } else {
1190                         return 0;
1191                 }
1192         }
1193
1194         /* Now process each placement in order, checking to see if we 
1195            can really do what has been requested.
1196         */
1197
1198         /* A: PreFader */
1199         
1200         if (check_some_plugin_counts (insert_map[PreFader], n_inputs ().get(_default_type), err_streams)) {
1201                 return -1;
1202         }
1203
1204         /* figure out the streams that will feed into PreFader */
1205
1206         if (!insert_map[PreFader].empty()) {
1207                 InsertCount& ic (insert_map[PreFader].back());
1208                 initial_streams = ic.insert->compute_output_streams (ic.cnt);
1209         } else {
1210                 initial_streams = n_inputs ().get(_default_type);
1211         }
1212
1213         /* B: PostFader */
1214
1215         if (check_some_plugin_counts (insert_map[PostFader], initial_streams, err_streams)) {
1216                 return -1;
1217         }
1218
1219         /* OK, everything can be set up correctly, so lets do it */
1220
1221         apply_some_plugin_counts (insert_map[PreFader]);
1222         apply_some_plugin_counts (insert_map[PostFader]);
1223
1224         /* recompute max outs of any redirect */
1225
1226   recompute:
1227
1228         redirect_max_outs.reset();
1229         RedirectList::iterator prev = _redirects.end();
1230
1231         for (r = _redirects.begin(); r != _redirects.end(); prev = r, ++r) {
1232                 boost::shared_ptr<Send> s;
1233
1234                 if ((s = boost::dynamic_pointer_cast<Send> (*r)) != 0) {
1235                         if (r == _redirects.begin()) {
1236                                 s->expect_inputs (n_inputs());
1237                         } else {
1238                                 s->expect_inputs ((*prev)->output_streams());
1239                         }
1240
1241                 } else {
1242                         
1243                         /* don't pay any attention to send output configuration, since it doesn't
1244                            affect the route.
1245                          */
1246
1247                         redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs);
1248                         
1249                 }
1250         }
1251
1252         /* we're done */
1253
1254         return 0;
1255 }                                  
1256
1257 int32_t
1258 Route::apply_some_plugin_counts (list<InsertCount>& iclist)
1259 {
1260         list<InsertCount>::iterator i;
1261
1262         for (i = iclist.begin(); i != iclist.end(); ++i) {
1263                 
1264                 if ((*i).insert->configure_io ((*i).cnt, (*i).in, (*i).out)) {
1265                         return -1;
1266                 }
1267                 /* make sure that however many we have, they are all active */
1268                 (*i).insert->activate ();
1269         }
1270
1271         return 0;
1272 }
1273
1274 int32_t
1275 Route::check_some_plugin_counts (list<InsertCount>& iclist, int32_t required_inputs, uint32_t* err_streams)
1276 {
1277         list<InsertCount>::iterator i;
1278         
1279         for (i = iclist.begin(); i != iclist.end(); ++i) {
1280
1281                 if (((*i).cnt = (*i).insert->can_support_input_configuration (required_inputs)) < 0) {
1282                         if (err_streams) {
1283                                 *err_streams = required_inputs;
1284                         }
1285                         return -1;
1286                 }
1287                 
1288                 (*i).in = required_inputs;
1289                 (*i).out = (*i).insert->compute_output_streams ((*i).cnt);
1290
1291                 required_inputs = (*i).out;
1292         }
1293
1294         return 0;
1295 }
1296
1297 int
1298 Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_streams)
1299 {
1300         ChanCount old_rmo = redirect_max_outs;
1301
1302         if (err_streams) {
1303                 *err_streams = 0;
1304         }
1305
1306         RedirectList to_be_deleted;
1307
1308         {
1309                 Glib::RWLock::WriterLock lm (redirect_lock);
1310                 RedirectList::iterator tmp;
1311                 RedirectList the_copy;
1312
1313                 the_copy = _redirects;
1314                 
1315                 /* remove all relevant redirects */
1316
1317                 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ) {
1318                         tmp = i;
1319                         ++tmp;
1320
1321                         if ((*i)->placement() == placement) {
1322                                 to_be_deleted.push_back (*i);
1323                                 _redirects.erase (i);
1324                         }
1325
1326                         i = tmp;
1327                 }
1328
1329                 /* now copy the relevant ones from "other" */
1330                 
1331                 for (RedirectList::const_iterator i = other._redirects.begin(); i != other._redirects.end(); ++i) {
1332                         if ((*i)->placement() == placement) {
1333                                 _redirects.push_back (Redirect::clone (*i));
1334                         }
1335                 }
1336
1337                 /* reset plugin stream handling */
1338
1339                 if (_reset_plugin_counts (err_streams)) {
1340
1341                         /* FAILED COPY ATTEMPT: we have to restore order */
1342
1343                         /* delete all cloned redirects */
1344
1345                         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ) {
1346
1347                                 tmp = i;
1348                                 ++tmp;
1349
1350                                 if ((*i)->placement() == placement) {
1351                                         _redirects.erase (i);
1352                                 }
1353                                 
1354                                 i = tmp;
1355                         }
1356
1357                         /* restore the natural order */
1358
1359                         _redirects = the_copy;
1360                         redirect_max_outs = old_rmo;
1361
1362                         /* we failed, even though things are OK again */
1363
1364                         return -1;
1365
1366                 } else {
1367                         
1368                         /* SUCCESSFUL COPY ATTEMPT: delete the redirects we removed pre-copy */
1369                         to_be_deleted.clear ();
1370                 }
1371         }
1372
1373         if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
1374                 reset_panner ();
1375         }
1376
1377         redirects_changed (this); /* EMIT SIGNAL */
1378         return 0;
1379 }
1380
1381 void
1382 Route::all_redirects_flip ()
1383 {
1384         Glib::RWLock::ReaderLock lm (redirect_lock);
1385
1386         if (_redirects.empty()) {
1387                 return;
1388         }
1389
1390         bool first_is_on = _redirects.front()->active();
1391         
1392         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1393                 (*i)->set_active (!first_is_on, this);
1394         }
1395 }
1396
1397 /** Set all redirects with a given placement to a given active state.
1398  * @param p Placement of redirects to change.
1399  * @param state New active state for those redirects.
1400  */
1401 void
1402 Route::all_redirects_active (Placement p, bool state)
1403 {
1404         Glib::RWLock::ReaderLock lm (redirect_lock);
1405
1406         if (_redirects.empty()) {
1407                 return;
1408         }
1409
1410         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1411                 if ((*i)->placement() == p) {
1412                         (*i)->set_active (state, this);
1413                 }
1414         }
1415 }
1416
1417 struct RedirectSorter {
1418     bool operator() (boost::shared_ptr<const Redirect> a, boost::shared_ptr<const Redirect> b) {
1419             return a->sort_key() < b->sort_key();
1420     }
1421 };
1422
1423 int
1424 Route::sort_redirects (uint32_t* err_streams)
1425 {
1426         {
1427                 RedirectSorter comparator;
1428                 Glib::RWLock::WriterLock lm (redirect_lock);
1429                 ChanCount old_rmo = redirect_max_outs;
1430
1431                 /* the sweet power of C++ ... */
1432
1433                 RedirectList as_it_was_before = _redirects;
1434
1435                 _redirects.sort (comparator);
1436         
1437                 if (_reset_plugin_counts (err_streams)) {
1438                         _redirects = as_it_was_before;
1439                         redirect_max_outs = old_rmo;
1440                         return -1;
1441                 } 
1442         } 
1443
1444         reset_panner ();
1445         redirects_changed (this); /* EMIT SIGNAL */
1446
1447         return 0;
1448 }
1449
1450 XMLNode&
1451 Route::get_state()
1452 {
1453         return state(true);
1454 }
1455
1456 XMLNode&
1457 Route::get_template()
1458 {
1459         return state(false);
1460 }
1461
1462 XMLNode&
1463 Route::state(bool full_state)
1464 {
1465         XMLNode *node = new XMLNode("Route");
1466         RedirectList:: iterator i;
1467         char buf[32];
1468
1469         if (_flags) {
1470                 node->add_property("flags", enum_2_string (_flags));
1471         }
1472         
1473         node->add_property("default-type", _default_type.to_string());
1474
1475         node->add_property("active", _active?"yes":"no");
1476         node->add_property("muted", _muted?"yes":"no");
1477         node->add_property("soloed", _soloed?"yes":"no");
1478         node->add_property("phase-invert", _phase_invert?"yes":"no");
1479         node->add_property("denormal-protection", _denormal_protection?"yes":"no");
1480         node->add_property("mute-affects-pre-fader", _mute_affects_pre_fader?"yes":"no"); 
1481         node->add_property("mute-affects-post-fader", _mute_affects_post_fader?"yes":"no"); 
1482         node->add_property("mute-affects-control-outs", _mute_affects_control_outs?"yes":"no"); 
1483         node->add_property("mute-affects-main-outs", _mute_affects_main_outs?"yes":"no"); 
1484
1485         if (_edit_group) {
1486                 node->add_property("edit-group", _edit_group->name());
1487         }
1488         if (_mix_group) {
1489                 node->add_property("mix-group", _mix_group->name());
1490         }
1491
1492         string order_string;
1493         OrderKeys::iterator x = order_keys.begin(); 
1494
1495         while (x != order_keys.end()) {
1496                 order_string += string ((*x).first);
1497                 order_string += '=';
1498                 snprintf (buf, sizeof(buf), "%ld", (*x).second);
1499                 order_string += buf;
1500                 
1501                 ++x;
1502
1503                 if (x == order_keys.end()) {
1504                         break;
1505                 }
1506
1507                 order_string += ':';
1508         }
1509         node->add_property ("order-keys", order_string);
1510
1511         node->add_child_nocopy (IO::state (full_state));
1512         node->add_child_nocopy (_solo_control.get_state ());
1513         node->add_child_nocopy (_mute_control.get_state ());
1514
1515         XMLNode* remote_control_node = new XMLNode (X_("remote_control"));
1516         snprintf (buf, sizeof (buf), "%d", _remote_control_id);
1517         remote_control_node->add_property (X_("id"), buf);
1518         node->add_child_nocopy (*remote_control_node);
1519
1520         if (_control_outs) {
1521                 XMLNode* cnode = new XMLNode (X_("ControlOuts"));
1522                 cnode->add_child_nocopy (_control_outs->state (full_state));
1523                 node->add_child_nocopy (*cnode);
1524         }
1525
1526         if (_comment.length()) {
1527                 XMLNode *cmt = node->add_child ("Comment");
1528                 cmt->add_content (_comment);
1529         }
1530
1531         for (i = _redirects.begin(); i != _redirects.end(); ++i) {
1532                 node->add_child_nocopy((*i)->state (full_state));
1533         }
1534
1535         if (_extra_xml){
1536                 node->add_child_copy (*_extra_xml);
1537         }
1538         
1539         return *node;
1540 }
1541
1542 XMLNode&
1543 Route::get_redirect_state ()
1544 {
1545         XMLNode* root = new XMLNode (X_("redirects"));
1546         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1547                 root->add_child_nocopy ((*i)->state (true));
1548         }
1549
1550         return *root;
1551 }
1552
1553 int
1554 Route::set_redirect_state (const XMLNode& root)
1555 {
1556         if (root.name() != X_("redirects")) {
1557                 return -1;
1558         }
1559
1560         XMLNodeList nlist;
1561         XMLNodeList nnlist;
1562         XMLNodeConstIterator iter;
1563         XMLNodeConstIterator niter;
1564         Glib::RWLock::ReaderLock lm (redirect_lock);
1565
1566         nlist = root.children();
1567         
1568         for (iter = nlist.begin(); iter != nlist.end(); ++iter){
1569
1570                 /* iter now points to a Redirect state node */
1571                 
1572                 nnlist = (*iter)->children ();
1573
1574                 for (niter = nnlist.begin(); niter != nnlist.end(); ++niter) {
1575
1576                         /* find the IO child node, since it contains the ID we need */
1577
1578                         /* XXX OOP encapsulation violation, ugh */
1579
1580                         if ((*niter)->name() == IO::state_node_name) {
1581
1582                                 XMLProperty* prop = (*niter)->property (X_("id"));
1583                                 
1584                                 if (!prop) {
1585                                         warning << _("Redirect node has no ID, ignored") << endmsg;
1586                                         break;
1587                                 }
1588
1589                                 ID id = prop->value ();
1590
1591                                 /* now look for a redirect with that ID */
1592         
1593                                 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1594                                         if ((*i)->id() == id) {
1595                                                 (*i)->set_state (**iter);
1596                                                 break;
1597                                         }
1598                                 }
1599                                 
1600                                 break;
1601                                 
1602                         }
1603                 }
1604
1605         }
1606
1607         return 0;
1608 }
1609
1610 void
1611 Route::set_deferred_state ()
1612 {
1613         XMLNodeList nlist;
1614         XMLNodeConstIterator niter;
1615
1616         if (!deferred_state) {
1617                 return;
1618         }
1619
1620         nlist = deferred_state->children();
1621
1622         for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1623                 add_redirect_from_xml (**niter);
1624         }
1625
1626         delete deferred_state;
1627         deferred_state = 0;
1628 }
1629
1630 void
1631 Route::add_redirect_from_xml (const XMLNode& node)
1632 {
1633         const XMLProperty *prop;
1634
1635         if (node.name() == "Send") {
1636                 
1637
1638                 try {
1639                         boost::shared_ptr<Send> send (new Send (_session, node));
1640                         add_redirect (send, this);
1641                 } 
1642                 
1643                 catch (failed_constructor &err) {
1644                         error << _("Send construction failed") << endmsg;
1645                         return;
1646                 }
1647                 
1648         } else if (node.name() == "Insert") {
1649                 
1650                 try {
1651                         if ((prop = node.property ("type")) != 0) {
1652
1653                                 boost::shared_ptr<Insert> insert;
1654
1655                                 if (prop->value() == "ladspa" || prop->value() == "Ladspa" || prop->value() == "vst") {
1656
1657                                         insert.reset (new PluginInsert(_session, node));
1658                                         
1659                                 } else if (prop->value() == "port") {
1660
1661
1662                                         insert.reset (new PortInsert (_session, node));
1663
1664                                 } else {
1665
1666                                         error << string_compose(_("unknown Insert type \"%1\"; ignored"), prop->value()) << endmsg;
1667                                 }
1668
1669                                 add_redirect (insert, this);
1670                                 
1671                         } else {
1672                                 error << _("Insert XML node has no type property") << endmsg;
1673                         }
1674                 }
1675                 
1676                 catch (failed_constructor &err) {
1677                         warning << _("insert could not be created. Ignored.") << endmsg;
1678                         return;
1679                 }
1680         }
1681 }
1682
1683 int
1684 Route::set_state (const XMLNode& node)
1685 {
1686         return _set_state (node, true);
1687 }
1688
1689 int
1690 Route::_set_state (const XMLNode& node, bool call_base)
1691 {
1692         XMLNodeList nlist;
1693         XMLNodeConstIterator niter;
1694         XMLNode *child;
1695         XMLPropertyList plist;
1696         const XMLProperty *prop;
1697
1698         if (node.name() != "Route"){
1699                 error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
1700                 return -1;
1701         }
1702
1703         if ((prop = node.property (X_("flags"))) != 0) {
1704                 _flags = Flag (string_2_enum (prop->value(), _flags));
1705         } else {
1706                 _flags = Flag (0);
1707         }
1708         
1709         if ((prop = node.property (X_("default-type"))) != 0) {
1710                 _default_type = DataType(prop->value());
1711                 assert(_default_type != DataType::NIL);
1712         }
1713
1714         if ((prop = node.property (X_("phase-invert"))) != 0) {
1715                 set_phase_invert (prop->value()=="yes"?true:false, this);
1716         }
1717
1718         if ((prop = node.property (X_("denormal-protection"))) != 0) {
1719                 set_denormal_protection (prop->value()=="yes"?true:false, this);
1720         }
1721
1722         if ((prop = node.property (X_("active"))) != 0) {
1723                 set_active (prop->value() == "yes");
1724         }
1725
1726         if ((prop = node.property (X_("muted"))) != 0) {
1727                 bool yn = prop->value()=="yes"?true:false; 
1728
1729                 /* force reset of mute status */
1730
1731                 _muted = !yn;
1732                 set_mute(yn, this);
1733                 mute_gain = desired_mute_gain;
1734         }
1735
1736         if ((prop = node.property (X_("soloed"))) != 0) {
1737                 bool yn = prop->value()=="yes"?true:false; 
1738
1739                 /* force reset of solo status */
1740
1741                 _soloed = !yn;
1742                 set_solo (yn, this);
1743                 solo_gain = desired_solo_gain;
1744         }
1745
1746         if ((prop = node.property (X_("mute-affects-pre-fader"))) != 0) {
1747                 _mute_affects_pre_fader = (prop->value()=="yes")?true:false;
1748         }
1749
1750         if ((prop = node.property (X_("mute-affects-post-fader"))) != 0) {
1751                 _mute_affects_post_fader = (prop->value()=="yes")?true:false;
1752         }
1753
1754         if ((prop = node.property (X_("mute-affects-control-outs"))) != 0) {
1755                 _mute_affects_control_outs = (prop->value()=="yes")?true:false;
1756         }
1757
1758         if ((prop = node.property (X_("mute-affects-main-outs"))) != 0) {
1759                 _mute_affects_main_outs = (prop->value()=="yes")?true:false;
1760         }
1761
1762         if ((prop = node.property (X_("edit-group"))) != 0) {
1763                 RouteGroup* edit_group = _session.edit_group_by_name(prop->value());
1764                 if(edit_group == 0) {
1765                         error << string_compose(_("Route %1: unknown edit group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
1766                 } else {
1767                         set_edit_group(edit_group, this);
1768                 }
1769         }
1770
1771         if ((prop = node.property (X_("order-keys"))) != 0) {
1772
1773                 long n;
1774
1775                 string::size_type colon, equal;
1776                 string remaining = prop->value();
1777
1778                 while (remaining.length()) {
1779
1780                         if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
1781                                 error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1782                                       << endmsg;
1783                         } else {
1784                                 if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) {
1785                                         error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
1786                                               << endmsg;
1787                                 } else {
1788                                         set_order_key (remaining.substr (0, equal).c_str(), n);
1789                                 }
1790                         }
1791
1792                         colon = remaining.find_first_of (':');
1793
1794                         if (colon != string::npos) {
1795                                 remaining = remaining.substr (colon+1);
1796                         } else {
1797                                 break;
1798                         }
1799                 }
1800         }
1801
1802         nlist = node.children();
1803
1804         if (deferred_state) {
1805                 delete deferred_state;
1806         }
1807
1808         deferred_state = new XMLNode(X_("deferred state"));
1809
1810         /* set parent class properties before anything else */
1811
1812         for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1813
1814                 child = *niter;
1815
1816                 if (child->name() == IO::state_node_name && call_base) {
1817
1818                         IO::set_state (*child);
1819                         break;
1820                 }
1821         }
1822
1823         XMLNodeList redirect_nodes;
1824                         
1825         for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1826
1827                 child = *niter;
1828                         
1829                 if (child->name() == X_("Send") || child->name() == X_("Insert")) {
1830                         redirect_nodes.push_back(child);
1831                 }
1832
1833         }
1834
1835         _set_redirect_states(redirect_nodes);
1836
1837
1838         for (niter = nlist.begin(); niter != nlist.end(); ++niter){
1839                 child = *niter;
1840                 // All redirects (sends and inserts) have been applied already
1841
1842                 if (child->name() == X_("Automation")) {
1843                         
1844                         if ((prop = child->property (X_("path"))) != 0)  {
1845                                 load_automation (prop->value());
1846                         }
1847
1848                 } else if (child->name() == X_("ControlOuts")) {
1849                         
1850                         string coutname = _name;
1851                         coutname += _("[control]");
1852
1853                         _control_outs = new IO (_session, coutname);
1854                         _control_outs->set_state (**(child->children().begin()));
1855
1856                 } else if (child->name() == X_("Comment")) {
1857
1858                         /* XXX this is a terrible API design in libxml++ */
1859
1860                         XMLNode *cmt = *(child->children().begin());
1861                         _comment = cmt->content();
1862
1863                 } else if (child->name() == X_("extra")) {
1864
1865                         _extra_xml = new XMLNode (*child);
1866
1867                 } else if (child->name() == X_("controllable") && (prop = child->property("name")) != 0) {
1868                         
1869                         if (prop->value() == "solo") {
1870                                 _solo_control.set_state (*child);
1871                                 _session.add_controllable (&_solo_control);
1872                         }
1873                         else if (prop->value() == "mute") {
1874                                 _mute_control.set_state (*child);
1875                                 _session.add_controllable (&_mute_control);
1876                         }
1877                 }
1878                 else if (child->name() == X_("remote_control")) {
1879                         if ((prop = child->property (X_("id"))) != 0) {
1880                                 int32_t x;
1881                                 sscanf (prop->value().c_str(), "%d", &x);
1882                                 set_remote_control_id (x);
1883                         }
1884                 }
1885         }
1886
1887         if ((prop = node.property (X_("mix-group"))) != 0) {
1888                 RouteGroup* mix_group = _session.mix_group_by_name(prop->value());
1889                 if (mix_group == 0) {
1890                         error << string_compose(_("Route %1: unknown mix group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg;
1891                 }  else {
1892                         set_mix_group(mix_group, this);
1893                 }
1894         }
1895
1896         return 0;
1897 }
1898
1899 void
1900 Route::_set_redirect_states(const XMLNodeList &nlist)
1901 {
1902         XMLNodeConstIterator niter;
1903         char buf[64];
1904
1905         RedirectList::iterator i, o;
1906
1907         // Iterate through existing redirects, remove those which are not in the state list
1908         for (i = _redirects.begin(); i != _redirects.end(); ) {
1909                 RedirectList::iterator tmp = i;
1910                 ++tmp;
1911
1912                 bool redirectInStateList = false;
1913         
1914                 (*i)->id().print (buf, sizeof (buf));
1915
1916
1917                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1918
1919                         if (strncmp(buf,(*niter)->child(X_("Redirect"))->child(X_("IO"))->property(X_("id"))->value().c_str(), sizeof(buf)) == 0) {
1920                                 redirectInStateList = true;
1921                                 break;
1922                         }
1923                 }
1924                 
1925                 if (!redirectInStateList) {
1926                         remove_redirect ( *i, this);
1927                 }
1928
1929
1930                 i = tmp;
1931         }
1932
1933
1934         // Iterate through state list and make sure all redirects are on the track and in the correct order,
1935         // set the state of existing redirects according to the new state on the same go
1936         i = _redirects.begin();
1937         for (niter = nlist.begin(); niter != nlist.end(); ++niter, ++i) {
1938
1939                 // Check whether the next redirect in the list 
1940                 o = i;
1941
1942                 while (o != _redirects.end()) {
1943                         (*o)->id().print (buf, sizeof (buf));
1944                         if ( strncmp(buf, (*niter)->child(X_("Redirect"))->child(X_("IO"))->property(X_("id"))->value().c_str(), sizeof(buf)) == 0)
1945                                 break;
1946                         ++o;
1947                 }
1948
1949                 if (o == _redirects.end()) {
1950                         // If the redirect (*niter) is not on the route, we need to create it
1951                         // and move it to the correct location
1952
1953                         RedirectList::iterator prev_last = _redirects.end();
1954                         --prev_last; // We need this to check whether adding succeeded
1955                         
1956                         add_redirect_from_xml (**niter);
1957
1958                         RedirectList::iterator last = _redirects.end();
1959                         --last;
1960
1961                         if (prev_last == last) {
1962                                 cerr << "Could not fully restore state as some redirects were not possible to create" << endl;
1963                                 continue;
1964
1965                         }
1966
1967                         boost::shared_ptr<Redirect> tmp = (*last);
1968                         // remove the redirect from the wrong location
1969                         _redirects.erase(last);
1970                         // insert the new redirect at the current location
1971                         _redirects.insert(i, tmp);
1972
1973                         --i; // move pointer to the newly inserted redirect
1974                         continue;
1975                 }
1976
1977                 // We found the redirect (*niter) on the route, first we must make sure the redirect
1978                 // is at the location provided in the XML state
1979                 if (i != o) {
1980                         boost::shared_ptr<Redirect> tmp = (*o);
1981                         // remove the old copy
1982                         _redirects.erase(o);
1983                         // insert the redirect at the correct location
1984                         _redirects.insert(i, tmp);
1985
1986                         --i; // move pointer so it points to the right redirect
1987                 }
1988
1989                 (*i)->set_state( (**niter) );
1990         }
1991         
1992         redirects_changed(this);
1993 }
1994
1995 void
1996 Route::curve_reallocate ()
1997 {
1998 //      _gain_automation_curve.finish_resize ();
1999 //      _pan_automation_curve.finish_resize ();
2000 }
2001
2002 void
2003 Route::silence (nframes_t nframes, nframes_t offset)
2004 {
2005         if (!_silent) {
2006
2007                 IO::silence (nframes, offset);
2008
2009                 if (_control_outs) {
2010                         _control_outs->silence (nframes, offset);
2011                 }
2012
2013                 { 
2014                         Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
2015                         
2016                         if (lm.locked()) {
2017                                 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2018                                         boost::shared_ptr<PluginInsert> pi;
2019                                         if (!_active && (pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
2020                                                 // skip plugins, they don't need anything when we're not active
2021                                                 continue;
2022                                         }
2023
2024                                         (*i)->silence (nframes, offset);
2025                                 }
2026
2027                                 if (nframes == _session.get_block_size() && offset == 0) {
2028                                         // _silent = true;
2029                                 }
2030                         }
2031                 }
2032                 
2033         }
2034 }       
2035
2036 int
2037 Route::set_control_outs (const vector<string>& ports)
2038 {
2039         Glib::Mutex::Lock lm (control_outs_lock);
2040         vector<string>::const_iterator i;
2041         size_t limit;
2042         
2043         if (_control_outs) {
2044                 delete _control_outs;
2045                 _control_outs = 0;
2046         }
2047
2048         if (control() || master()) {
2049                 /* no control outs for these two special busses */
2050                 return 0;
2051         }
2052         
2053         if (ports.empty()) {
2054                 return 0;
2055         }
2056  
2057         string coutname = _name;
2058         coutname += _("[control]");
2059         
2060         _control_outs = new IO (_session, coutname);
2061
2062         /* our control outs need as many outputs as we
2063            have audio outputs. we track the changes in ::output_change_handler().
2064         */
2065         
2066         // XXX its stupid that we have to get this value twice
2067
2068         limit = n_outputs().n_audio();
2069         
2070         if (_control_outs->ensure_io (ChanCount::ZERO, ChanCount (DataType::AUDIO, n_outputs().get (DataType::AUDIO)), true, this)) {
2071                 return -1;
2072         }
2073         
2074         /* now connect to the named ports */
2075         
2076         for (size_t n = 0; n < limit; ++n) {
2077                 if (_control_outs->connect_output (_control_outs->output (n), ports[n], this)) {
2078                         error << string_compose (_("could not connect %1 to %2"), _control_outs->output(n)->name(), ports[n]) << endmsg;
2079                         return -1;
2080                 }
2081         }
2082  
2083         return 0;
2084 }       
2085
2086 void
2087 Route::set_edit_group (RouteGroup *eg, void *src)
2088
2089 {
2090         if (eg == _edit_group) {
2091                 return;
2092         }
2093
2094         if (_edit_group) {
2095                 _edit_group->remove (this);
2096         }
2097
2098         if ((_edit_group = eg) != 0) {
2099                 _edit_group->add (this);
2100         }
2101
2102         _session.set_dirty ();
2103         edit_group_changed (src); /* EMIT SIGNAL */
2104 }
2105
2106 void
2107 Route::drop_edit_group (void *src)
2108 {
2109         _edit_group = 0;
2110         _session.set_dirty ();
2111         edit_group_changed (src); /* EMIT SIGNAL */
2112 }
2113
2114 void
2115 Route::set_mix_group (RouteGroup *mg, void *src)
2116
2117 {
2118         if (mg == _mix_group) {
2119                 return;
2120         }
2121
2122         if (_mix_group) {
2123                 _mix_group->remove (this);
2124         }
2125
2126         if ((_mix_group = mg) != 0) {
2127                 _mix_group->add (this);
2128         }
2129
2130         _session.set_dirty ();
2131         mix_group_changed (src); /* EMIT SIGNAL */
2132 }
2133
2134 void
2135 Route::drop_mix_group (void *src)
2136 {
2137         _mix_group = 0;
2138         _session.set_dirty ();
2139         mix_group_changed (src); /* EMIT SIGNAL */
2140 }
2141
2142 void
2143 Route::set_comment (string cmt, void *src)
2144 {
2145         _comment = cmt;
2146         comment_changed (src);
2147         _session.set_dirty ();
2148 }
2149
2150 bool
2151 Route::feeds (boost::shared_ptr<Route> other)
2152 {
2153         uint32_t i, j;
2154
2155         IO& self = *this;
2156         uint32_t no = self.n_outputs().n_total();
2157         uint32_t ni = other->n_inputs ().n_total();
2158
2159         for (i = 0; i < no; ++i) {
2160                 for (j = 0; j < ni; ++j) {
2161                         if (self.output(i)->connected_to (other->input(j)->name())) {
2162                                 return true;
2163                         }
2164                 }
2165         }
2166
2167         /* check Redirects which may also interconnect Routes */
2168
2169         for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); r++) {
2170
2171                 no = (*r)->n_outputs().n_total();
2172
2173                 for (i = 0; i < no; ++i) {
2174                         for (j = 0; j < ni; ++j) {
2175                                 if ((*r)->output(i)->connected_to (other->input (j)->name())) {
2176                                         return true;
2177                                 }
2178                         }
2179                 }
2180         }
2181
2182         /* check for control room outputs which may also interconnect Routes */
2183
2184         if (_control_outs) {
2185
2186                 no = _control_outs->n_outputs().n_total();
2187                 
2188                 for (i = 0; i < no; ++i) {
2189                         for (j = 0; j < ni; ++j) {
2190                                 if (_control_outs->output(i)->connected_to (other->input (j)->name())) {
2191                                         return true;
2192                                 }
2193                         }
2194                 }
2195         }
2196
2197         return false;
2198 }
2199
2200 void
2201 Route::set_mute_config (mute_type t, bool onoff, void *src)
2202 {
2203         switch (t) {
2204         case PRE_FADER:
2205                 _mute_affects_pre_fader = onoff;
2206                  pre_fader_changed(src); /* EMIT SIGNAL */
2207                 break;
2208
2209         case POST_FADER:
2210                 _mute_affects_post_fader = onoff;
2211                  post_fader_changed(src); /* EMIT SIGNAL */
2212                 break;
2213
2214         case CONTROL_OUTS:
2215                 _mute_affects_control_outs = onoff;
2216                  control_outs_changed(src); /* EMIT SIGNAL */
2217                 break;
2218
2219         case MAIN_OUTS:
2220                 _mute_affects_main_outs = onoff;
2221                  main_outs_changed(src); /* EMIT SIGNAL */
2222                 break;
2223         }
2224 }
2225
2226 bool
2227 Route::get_mute_config (mute_type t)
2228 {
2229         bool onoff = false;
2230         
2231         switch (t){
2232         case PRE_FADER:
2233                 onoff = _mute_affects_pre_fader; 
2234                 break;
2235         case POST_FADER:
2236                 onoff = _mute_affects_post_fader;
2237                 break;
2238         case CONTROL_OUTS:
2239                 onoff = _mute_affects_control_outs;
2240                 break;
2241         case MAIN_OUTS:
2242                 onoff = _mute_affects_main_outs;
2243                 break;
2244         }
2245         
2246         return onoff;
2247 }
2248
2249 void
2250 Route::set_active (bool yn)
2251 {
2252         _active = yn; 
2253          active_changed(); /* EMIT SIGNAL */
2254 }
2255
2256 void
2257 Route::handle_transport_stopped (bool abort_ignored, bool did_locate, bool can_flush_redirects)
2258 {
2259         nframes_t now = _session.transport_frame();
2260
2261         {
2262                 Glib::RWLock::ReaderLock lm (redirect_lock);
2263
2264                 if (!did_locate) {
2265                         automation_snapshot (now);
2266                 }
2267
2268                 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2269                         
2270                         if (Config->get_plugins_stop_with_transport() && can_flush_redirects) {
2271                                 (*i)->deactivate ();
2272                                 (*i)->activate ();
2273                         }
2274                         
2275                         (*i)->transport_stopped (now);
2276                 }
2277         }
2278
2279         IO::transport_stopped (now);
2280  
2281         _roll_delay = _initial_delay;
2282 }
2283
2284 void
2285 Route::input_change_handler (IOChange change, void *ignored)
2286 {
2287         if (change & ConfigurationChanged) {
2288                 reset_plugin_counts (0);
2289         }
2290 }
2291
2292 void
2293 Route::output_change_handler (IOChange change, void *ignored)
2294 {
2295         if (change & ConfigurationChanged) {
2296                 if (_control_outs) {
2297                         _control_outs->ensure_io (ChanCount::ZERO, ChanCount(DataType::AUDIO, n_outputs().n_audio()), true, this);
2298                 }
2299                 
2300                 reset_plugin_counts (0);
2301         }
2302 }
2303
2304 uint32_t
2305 Route::pans_required () const
2306 {
2307         if (n_outputs().n_audio() < 2) {
2308                 return 0;
2309         }
2310         
2311         return max (n_inputs ().n_audio(), static_cast<size_t>(redirect_max_outs.n_audio()));
2312 }
2313
2314 int 
2315 Route::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, 
2316                    bool session_state_changing, bool can_record, bool rec_monitors_input)
2317 {
2318         if (n_outputs().n_total() == 0) {
2319                 return 0;
2320         }
2321
2322         if (session_state_changing || !_active)  {
2323                 silence (nframes, offset);
2324                 return 0;
2325         }
2326
2327         apply_gain_automation = false;
2328         
2329         if (n_inputs().n_total()) {
2330                 passthru (start_frame, end_frame, nframes, offset, 0, false);
2331         } else {
2332                 silence (nframes, offset);
2333         }
2334
2335         return 0;
2336 }
2337
2338 nframes_t
2339 Route::check_initial_delay (nframes_t nframes, nframes_t& offset, nframes_t& transport_frame)
2340 {
2341         if (_roll_delay > nframes) {
2342
2343                 _roll_delay -= nframes;
2344                 silence (nframes, offset);
2345                 /* transport frame is not legal for caller to use */
2346                 return 0;
2347
2348         } else if (_roll_delay > 0) {
2349
2350                 nframes -= _roll_delay;
2351
2352                 silence (_roll_delay, offset);
2353
2354                 offset += _roll_delay;
2355                 transport_frame += _roll_delay;
2356
2357                 _roll_delay = 0;
2358         }
2359
2360         return nframes;
2361 }
2362
2363 int
2364 Route::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, int declick,
2365              bool can_record, bool rec_monitors_input)
2366 {
2367         {
2368                 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
2369                 if (lm.locked()) {
2370                         // automation snapshot can also be called from the non-rt context
2371                         // and it uses the redirect list, so we take the lock out here
2372                         automation_snapshot (_session.transport_frame());
2373                 }
2374         }
2375
2376         if ((n_outputs().n_total() == 0 && _redirects.empty()) || n_inputs().n_total() == 0 || !_active) {
2377                 silence (nframes, offset);
2378                 return 0;
2379         }
2380         
2381         nframes_t unused = 0;
2382
2383         if ((nframes = check_initial_delay (nframes, offset, unused)) == 0) {
2384                 return 0;
2385         }
2386
2387         _silent = false;
2388
2389         apply_gain_automation = false;
2390
2391         { 
2392                 Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK);
2393                 
2394                 if (am.locked() && _session.transport_rolling()) {
2395                         
2396                         if (gain_automation_playback()) {
2397                                 apply_gain_automation = _gain_automation_curve.rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes);
2398                         }
2399                 }
2400         }
2401
2402         passthru (start_frame, end_frame, nframes, offset, declick, false);
2403
2404         return 0;
2405 }
2406
2407 int
2408 Route::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, 
2409                     bool can_record, bool rec_monitors_input)
2410 {
2411         silence (nframes, offset);
2412         return 0;
2413 }
2414
2415 void
2416 Route::toggle_monitor_input ()
2417 {
2418         for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
2419                 i->ensure_monitor_input( ! i->monitoring_input());
2420         }
2421 }
2422
2423 bool
2424 Route::has_external_redirects () const
2425 {
2426         boost::shared_ptr<const PortInsert> pi;
2427         
2428         for (RedirectList::const_iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2429                 if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*i)) != 0) {
2430
2431                         for (PortSet::const_iterator port = pi->outputs().begin();
2432                                         port != pi->outputs().end(); ++port) {
2433                                 
2434                                 string port_name = port->name();
2435                                 string client_name = port_name.substr (0, port_name.find(':'));
2436
2437                                 /* only say "yes" if the redirect is actually in use */
2438                                 
2439                                 if (client_name != "ardour" && pi->active()) {
2440                                         return true;
2441                                 }
2442                         }
2443                 }
2444         }
2445
2446         return false;
2447 }
2448
2449 void
2450 Route::flush_redirects ()
2451 {
2452         /* XXX shouldn't really try to take this lock, since
2453            this is called from the RT audio thread.
2454         */
2455
2456         Glib::RWLock::ReaderLock lm (redirect_lock);
2457
2458         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2459                 (*i)->deactivate ();
2460                 (*i)->activate ();
2461         }
2462 }
2463
2464 void
2465 Route::set_meter_point (MeterPoint p, void *src)
2466 {
2467         if (_meter_point != p) {
2468                 _meter_point = p;
2469                  meter_change (src); /* EMIT SIGNAL */
2470                 _session.set_dirty ();
2471         }
2472 }
2473
2474 nframes_t
2475 Route::update_total_latency ()
2476 {
2477         _own_latency = 0;
2478
2479         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2480                 if ((*i)->active ()) {
2481                         _own_latency += (*i)->latency ();
2482                 }
2483         }
2484
2485         set_port_latency (_own_latency);
2486
2487         /* this (virtual) function is used for pure Routes,
2488            not derived classes like AudioTrack.  this means
2489            that the data processed here comes from an input
2490            port, not prerecorded material, and therefore we
2491            have to take into account any input latency.
2492         */
2493
2494         _own_latency += input_latency ();
2495
2496         return _own_latency;
2497 }
2498
2499 void
2500 Route::set_latency_delay (nframes_t longest_session_latency)
2501 {
2502         _initial_delay = longest_session_latency - _own_latency;
2503
2504         if (_session.transport_stopped()) {
2505                 _roll_delay = _initial_delay;
2506         }
2507 }
2508
2509 void
2510 Route::automation_snapshot (nframes_t now)
2511 {
2512         IO::automation_snapshot (now);
2513
2514         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2515                 (*i)->automation_snapshot (now);
2516         }
2517 }
2518
2519 Route::ToggleControllable::ToggleControllable (std::string name, Route& s, ToggleType tp)
2520         : Controllable (name), route (s), type(tp)
2521 {
2522         
2523 }
2524
2525 void
2526 Route::ToggleControllable::set_value (float val)
2527 {
2528         bool bval = ((val >= 0.5f) ? true: false);
2529         
2530         switch (type) {
2531         case MuteControl:
2532                 route.set_mute (bval, this);
2533                 break;
2534         case SoloControl:
2535                 route.set_solo (bval, this);
2536                 break;
2537         default:
2538                 break;
2539         }
2540 }
2541
2542 float
2543 Route::ToggleControllable::get_value (void) const
2544 {
2545         float val = 0.0f;
2546         
2547         switch (type) {
2548         case MuteControl:
2549                 val = route.muted() ? 1.0f : 0.0f;
2550                 break;
2551         case SoloControl:
2552                 val = route.soloed() ? 1.0f : 0.0f;
2553                 break;
2554         default:
2555                 break;
2556         }
2557
2558         return val;
2559 }
2560
2561 void 
2562 Route::set_block_size (nframes_t nframes)
2563 {
2564         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2565                 (*i)->set_block_size (nframes);
2566         }
2567 }
2568
2569 void
2570 Route::redirect_active_proxy (Redirect* ignored, void* ignored_src)
2571 {
2572         _session.update_latency_compensation (false, false);
2573 }
2574
2575 void
2576 Route::protect_automation ()
2577 {
2578         switch (gain_automation_state()) {
2579         case Write:
2580                 set_gain_automation_state (Off);
2581         case Touch:
2582                 set_gain_automation_state (Play);
2583                 break;
2584         default:
2585                 break;
2586         }
2587
2588         switch (panner().automation_state ()) {
2589         case Write:
2590                 panner().set_automation_state (Off);
2591                 break;
2592         case Touch:
2593                 panner().set_automation_state (Play);
2594                 break;
2595         default:
2596                 break;
2597         }
2598         
2599         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
2600                 boost::shared_ptr<PluginInsert> pi;
2601                 if ((pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
2602                         pi->protect_automation ();
2603                 }
2604         }
2605 }
2606
2607 void
2608 Route::set_pending_declick (int declick)
2609 {
2610         if (_declickable) {
2611                 /* this call is not allowed to turn off a pending declick unless "force" is true */
2612                 if (declick) {
2613                         _pending_declick = declick;
2614                 }
2615                 // cerr << _name << ": after setting to " << declick << " pending declick = " << _pending_declick << endl;
2616         } else {
2617                 _pending_declick = 0;
2618         }
2619
2620 }